commit f9d9a4a254a71a3bae419cc3c2d4959ae412724a Author: 17737207832 <18103773227@163.com> Date: Tue Mar 11 09:11:42 2025 +0800 代码初始化 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2959201 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.js linguist-language=java +*.css linguist-language=java +*.html linguist-language=java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..093fdac --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + skyeye + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..914aff9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 智能制造云办公 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..120cd5d --- /dev/null +++ b/README.en.md @@ -0,0 +1,36 @@ +# erp_pro + +#### Description +基于SpringBoot框架和SaaS模式,立志为中小企业提供开源好用的ERP软件,目前专注进销存+财务功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务管理、报表查询、系统管理等。支持预付款、收入支出、仓库调拨、组装拆卸、订单等特色功能。拥有库存状况、出入库统计等报表。同时对角色和权限进行了细致全面控制,精确到每个按钮和菜单。 + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e22265d --- /dev/null +++ b/README.md @@ -0,0 +1,190 @@ +# :tw-1f308: erp-pro + +> Skyeye云源代码,采用Springboot + winUI + UNI-APP的低代码平台开发模式。包含30多个应用模块、50多种电子流程,CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表设计、工作流、日程、云盘等全面管理,实现智能制造行业一体化管理。 + +**郑重声明:** + +**1. Skyeye云【源代码】针对 {星球用户} 开源。拿到源码后可进行学习、毕设、企业等使用。** + +**2. [开发文档](https://articles.zsxq.com/id_xi3xhacte72g.html) [视频教程](https://space.bilibili.com/87396008/channel/series)** + +**3. [常见问题](https://gitee.com/dromara/skyeye/blob/company_server/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98.md),优先看这个。《《《《《《《《《《《《《《这个文件必看,有`移动端`的详细说明。** + +**4. 我们的功能多达500个功能点,包含PC和移动端。本着`姜太公钓鱼愿者上钩`的心态来开放星球用户。`Skyeye云的功能是全网最全,价格最低的一款软件,没有之一`。如果你买了之后觉得不划算,那么进入星球后1个月内你可以找一套具备相同功能的软件源码提供给作者,并给作者提供一年的免费更新和维护,作者会原价退还给您。** + +**为什么推荐使用本项目?** + +① 无论你是学生、个人与企业,进入星球后皆可 100% 免费使用,不用保留类作者、Copyright 信息。 + +② 代码全部开放,让你可以了解整个项目的架构设计。 + +③ 具备低代码、功能全面、快速便捷开发、无需重复的CRUD等优点,短时间内可完成一款系统的开发。 + +④ [国产开源项目对比--以及Skyeye云功能点](https://docs.qq.com/sheet/DYUtPdWhTbVBITlpL?tab=000001)。 + +![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/mindMap/compare.png) + +本项目的GitCode地址: https://gitcode.com/doc_wei/erp-pro + +## 🐶 沟通交流 + +| | 知识星球 | 微信公众号(Skyeye智能制造云办公) | QQ交流群 | +|:---------------------:|:---------------------:|:--------------------------------:|:--------------------------------:| +| 微信扫码 | ![](https://gitee.com/dromara/skyeye/raw/company_server/images/mindMap/知识星球.png) | ![](https://gitee.com/dromara/skyeye/raw/company_server/images/mindMap/微信公众号.jpg) | ![](https://gitee.com/dromara/skyeye/raw/company_server/images/mindMap/Dromara-Skyeye云交流群群聊二维码.png) | + +## 项目框架介绍 + +### 环境依赖 + +| 依赖 | 版本 | 端口 | +|:---------------------:|:---------------------:|:---------------------:| +| Java | 1.8 | 无 | +| rocket MQ | 4.9.2 | 9876 | +| Redis | 5.0 / 6.0 | 6379 | +| nacos | 2.3.0 | 9000 | +| MySQL | 5.7或更高版本 | 3308 | + +### 微服务项目 + +> 介绍整体微服务的目录结构以及端口的占用情况。 + +| 工程 | 端口 | 介绍 | jar包名称 | +|:---------------------:|:---------------------:|:---------------------:|:---------------------:| +| - | - | 后台微服务公共配置项 | +|skyeye-web |8080 | **前端工程** |web.jar | +|skyeye-promote |8081 | **基础工程** (包含用户、组织、权限、API、消息队列、Skyeye系列的服务注册等基础服务), **优先启动该工程** 。 |skyeye-web.jar | +|skyeye-shop |8082 |商城 |shop-web.jar | +|skyeye-flowable |8083 |工作流 |flowable-web.jar | +|skyeye-report |8085 |报表设计器 |report-web.jar | +|xxl-job-2.3.0 |8200 |定时任务 |xxl-job-admin-2.3.0.jar | +|skyeye-school |8084 |学校模块 |school-web.jar | +|skyeye-wages |8101 |薪资模块 |wages-web.jar | +|skyeye-deploy |8010 |部署模块 |deploy-web.war | +|skyeye-adm |8103 |行政模块 |adm-web.jar | +|skyeye-boss |8104 |招聘模块 |boss-web.jar | +|skyeye-checkwork |8105 |考勤模块 |checkwork-web.jar | +|skyeye-crm |8102 |客户管理模块 |crm-web.jar | +|skyeye-ifs |8107 |财务模块 |ifs-web.jar | +|skyeye-project |8109 |PM项目管理模块 |project-web.jar | +|skyeye-erp |8106 |ERP+生产模块 |erp-web.jar | +|skyeye-seal-service |8108 |售后服务模块 |seal-service-web.jar | + +## :tw-1f31e: 架构介绍 + +![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/mindMap/image11.png) + +### :jack_o_lantern: 技术选型 + +#### 后端技术: + +| 框架 | 说明 | 版本 | 学习指南 | +|---|---|---|---| +| [Spring Cloud Alibaba](https://github.com/alibaba/spring-cloud-alibaba) | 微服务框架 | 2.1.0.RELEASE | [文档](https://github.com/YunaiV/SpringBoot-Labs) | +| [Nacos](https://nacos.io/) | 配置中心 & 注册中心 | 1.4.3 | [文档](https://nacos.io/docs/v1/what-is-nacos/) | +| [RocketMQ](https://rocketmq.apache.org/zh/) | 消息队列 | 4.0.0 | [文档](https://rocketmq.apache.org/zh/docs/4.x/) | +| [Sentinel](https://github.com/alibaba/sentinel) | 服务保障| 2.1.0.RELEASE | [文档](https://zhuanlan.zhihu.com/p/681044230) | +| [XXL Job](https://github.com/xuxueli/xxl-job) | 定时任务 | 2.3.0 | [文档](https://www.xuxueli.com/xxl-job/#google_vignette) | +| [Spring Cloud Zuul](https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html) | 服务网关 | 3.4.1 | [文档](https://www.jianshu.com/p/cf748031a08d) | +| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | | +| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.23 | [文档](https://zhuanlan.zhihu.com/p/555116830) | +| [MyBatis Plus](https://baomidou.com/) | MyBatis 增强工具包 | 3.5.7 | [文档](https://baomidou.com/introduce/) | +| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | | +| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.0 | [文档](https://doc.iocoder.cn/bpm/) | +| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.0.3 | [文档](https://blog.51cto.com/u_15916106/7063036) | +| [hutool](https://www.hutool.cn/) | 一个小而全的Java工具类库 | 5.5.4 | [文档](https://doc.hutool.cn/pages/index/) | +| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.22 | [文档](https://zhuanlan.zhihu.com/p/32779910) | +| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 4.12 | - | + +#### 前端技术: + +| 框架 | 技术 | 版本 | 学习指南 | +|---|---|---|---| +|[layui](https://layui.uimaker.com/)|模块化前端UI| 2.6.7 | [文档](https://layui.uimaker.com/doc/index.html) | +|winui|win10风格UI|自研|-| +|[uni-app](https://uniapp.dcloud.net.cn/)|一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序、快应用等多个平台。| VUE3 |[文档](https://uniapp.dcloud.net.cn/component/)| + +## :tw-1f30f: PC端效果图 + +### 基础内容 +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|组件管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/20240802001image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/2024080202image.png)|| +|布局/操作/属性管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/2024080203image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/2024080204image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/20240802005image.png)| +|菜单/角色/编码管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/20240802010image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/20240802011image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/base/20240802012image.png)| + +### CRM +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|客户管理(包括合同、跟单、文档等)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/1image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/2image.png)| +|客户管理(包括合同、跟单、文档等)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/3image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/4image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/5image.png)| +|报表分析|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/6image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/7image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/crm/8image.png)| + +### ERP +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|商品管理 **(支持一物一码)** |![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/08image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/07image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/09image.png)| +|采购模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/01image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/02image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/03image.png)| +|采购模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/04image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/05image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/06image.png)| +|销售模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/10image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/11image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/12image.png)| +|报表模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/13image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/14image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erp/15image.png)| + +### ERP仓库 +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|其他单据管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/1image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/2image.png)| +|仓库管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/3image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/4image.png)|| +|盘点管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/5image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/6image.png)|| +|出入库管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/7image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/8image.png)|| +|商品条形码|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/9image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/erpDepot/10image.png)|| + +### MES生产 +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|生产管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/1image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/2image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/3image.png)| +|设置中心|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/4image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/5image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/6image.png)| +|物料管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/7image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/8image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/9image.png)| +|生产执行|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/10image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/11image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/12image.png)| +|物料确认|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/13image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/14image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/mes/15image.png)| + +### 行政办公 +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|会议室模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/1image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/2image.png)|| +|用品模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/3image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/4image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/5image.png)| +|资产模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/6image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/7image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/8image.png)| +|公文模块|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/9image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/10image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/11image.png)| +|印章,证照,车辆|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/12image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/13image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/oa/14image.png)| + +### 售后管理模块 +|功能| 效果图 | 效果图 | 效果图 | +|----|-------|-----|------| +|工单管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/1image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/2image.png)|| +|配件管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/3image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/4image.png)|| +|工人管理|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/5image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/6image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/sealService/7image.png)| + +## :tw-1f30f: 移动端效果图 + +> 移动端和PC端功能类似,这里不截那么多图拉。 + +### 基础模块 +| 效果图 | 效果图 | 效果图 | 效果图 | +|--------|-------|-------|-------| +|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/20240730image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073002image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073003image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073004image.png)| + +### ERP + +| 效果图 | 效果图 | 效果图 | 效果图 | +|--------|-------|-------|-------| +|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073005image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073006image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073007image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073008image.png)| + +### CRM + +| 效果图 | 效果图 | 效果图 | 效果图 | +|--------|-------|-------|-------| +|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073012image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073009image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073010image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073011image.png)| + +### OA + +| 效果图 | 效果图 | 效果图 | 效果图 | +|--------|-------|-------|-------| +|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073013image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073014image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073015image.png)|![输入图片说明](https://gitee.com/dromara/skyeye/raw/company_server/images/show/phone/2024073016image.png)| diff --git a/skyeye-adm/.gitignore b/skyeye-adm/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-adm/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-adm/adm-common/.gitignore b/skyeye-adm/adm-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-adm/adm-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-adm/adm-common/lib/aspose-words-15.8.0-jdk16.jar b/skyeye-adm/adm-common/lib/aspose-words-15.8.0-jdk16.jar new file mode 100644 index 0000000..c0e699f Binary files /dev/null and b/skyeye-adm/adm-common/lib/aspose-words-15.8.0-jdk16.jar differ diff --git a/skyeye-adm/adm-common/pom.xml b/skyeye-adm/adm-common/pom.xml new file mode 100644 index 0000000..84827c2 --- /dev/null +++ b/skyeye-adm/adm-common/pom.xml @@ -0,0 +1,34 @@ + + + + skyeye-adm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + adm-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + com.aspose + aspose-words + 15.8.0 + system + ${basedir}/lib/aspose-words-15.8.0-jdk16.jar + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/DiskCloudConstants.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/DiskCloudConstants.java new file mode 100644 index 0000000..5c61d58 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/DiskCloudConstants.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constans; + +/** + * @ClassName: DiskCloudConstants + * @Description: 文件系统相关的常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/14 11:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class DiskCloudConstants { + + /** + * 文件管理---目录logo图片 + */ + public static final String SYS_FILE_CONSOLE_IS_FOLDER_LOGO_PATH = "../../assets/images/icon/folder-show.png"; + + // 文件分享路径 + public static final String getFileShareUrl(String id) { + return "tpl/shareFile/shareFilepwd.html?id=" + id; + } + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/ForumConstants.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/ForumConstants.java new file mode 100644 index 0000000..e525f97 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/ForumConstants.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constans; + +/** + * @ClassName: ForumConstants + * @Description: 论坛系统常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/15 21:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class ForumConstants { + + // 获取上线的论坛标签 + public static final String FORUM_TAG_UP_STATE_LIST = "forum_tag_up_state_list"; + + // 获取论坛敏感词的redis的key + public static final String FORUM_SENSITIVE_WORDS_ALL = "forum_sensitive_words_all"; + + public static String forumSensitiveWordsAll() { + return FORUM_SENSITIVE_WORDS_ALL; + } + + // 获取论坛帖子评论量的redis的key(实时的) + public static final String FORUM_COMMENT_NUMS_BY_ = "forum_comment_nums_by_"; + + public static String forumCommentNumsByForumId(String forumId) { + return FORUM_COMMENT_NUMS_BY_ + forumId; + } + + // 获取论坛帖子评论量的redis的key(执行上一次定时任务时的) + public static final String FORUMYESTERDAY_COMMENT_NUMS_BYFORUMID = "forum_yesterday_comment_nums_by_"; + + public static String forumYesterdayCommentNumsByForumId(String forumId) { + return FORUMYESTERDAY_COMMENT_NUMS_BYFORUMID + forumId; + } + + // 获取论坛帖子浏览量的redis的key(实时的) + public static final String FORUM_BROWSE_NUMS_BYFORUMID = "forum_browse_nums_by_"; + + public static String forumBrowseNumsByForumId(String forumId) { + return FORUM_BROWSE_NUMS_BYFORUMID + forumId; + } + + // 获取论坛帖子浏览量的redis的key(执行上一次定时任务时的) + public static final String FORUMYESTERDAY_BROWSE_NUMS_BYFORUMID = "forum_yesterday_browse_nums_by_"; + + public static String forumYesterdayBrowseNumsByForumId(String forumId) { + return FORUMYESTERDAY_BROWSE_NUMS_BYFORUMID + forumId; + } + + // 获取用户论坛帖子浏览信息的redis的key + public static final String FORUM_BROWSE_MATION_BYUSERID = "forum_browse_mation_by_"; + + public static String forumBrowseMationByUserid(String userId) { + return FORUM_BROWSE_MATION_BYUSERID + userId; + } + + // 获取论坛帖子每天被浏览过帖子的redis的key + public static final String FORUM_EVERYDAY_BROWSE_IDS_BYTIME = "forum_everyday_browse_ids_by_"; + + public static String forumEverydayBrowseIdsByTime(String time) { + return FORUM_EVERYDAY_BROWSE_IDS_BYTIME + time; + } + + // 获取论坛每个帖子每天的浏览和评论数的redis的key + public static final String EVERYFORUM_EVERYDAY_NUMS_BY_ = "everyforum_everyday_nums_by_"; + + public static String everyforumEverydayNumsByIdAndTime(String id, String time) { + return EVERYFORUM_EVERYDAY_NUMS_BY_ + id + "_" + time; + } + + // 获取solr同步数据的时间的redis的key + public static final String FORUM_SOLR_SYNCHRONOUSTIME = "forum_solr_synchronoustime"; + + public static String forumSolrSynchronoustime() { + return FORUM_SOLR_SYNCHRONOUSTIME; + } + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/NoteConstants.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/NoteConstants.java new file mode 100644 index 0000000..660a749 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/constans/NoteConstants.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constans; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: NoteConstants + * @Description: 笔记系统相关的常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/14 11:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class NoteConstants { + + /** + * 获取我的笔记默认的文件夹 + * + * @return + */ + public static final List> getFileMyNoteDefaultFolder() { + List> beans = new ArrayList<>(); + Map newnotes = new HashMap<>(); + newnotes.put("id", "1"); + newnotes.put("name", "最新笔记"); + newnotes.put("pId", "0"); + newnotes.put("isParent", 0);// 是否是文件夹 0否1是 + newnotes.put("icon", "../../assets/images/note-folder.png");// 图标 + beans.add(newnotes); + Map myfiles = new HashMap<>(); + myfiles.put("id", "2"); + myfiles.put("name", "我的文件夹"); + myfiles.put("pId", "0"); + myfiles.put("isParent", 1);// 是否是文件夹 0否1是 + myfiles.put("icon", "../../assets/images/cloud/my-folder-icon.png");// 图标 + beans.add(myfiles); + return beans; + } + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/CheckWorkService.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/CheckWorkService.java new file mode 100644 index 0000000..7c2f67f --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/CheckWorkService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.checkwork; + +import com.skyeye.common.client.ClientConfiguration; +import com.skyeye.rest.checkwork.entity.DayWorkMationRest; +import com.skyeye.rest.checkwork.entity.UserOtherDayMationRest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +/** + * @ClassName: CheckWorkService + * @Description: 考勤模块接口信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 20:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-checkwork}", configuration = ClientConfiguration.class) +public interface CheckWorkService { + + /** + * 获取节假日信息 + * + * @param dayWorkMationRest 入参信息 + */ + @PostMapping("/queryDayWorkMation") + String queryDayWorkMation(DayWorkMationRest dayWorkMationRest); + + /** + * 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + * + * @param userOtherDayMationRest 入参信息 + */ + @PostMapping("/getUserOtherDayMation") + String getUserOtherDayMation(UserOtherDayMationRest userOtherDayMationRest); + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/DayWorkMationRest.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/DayWorkMationRest.java new file mode 100644 index 0000000..aff179e --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/DayWorkMationRest.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.checkwork.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DayWorkMationParams + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 20:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("判断节假日信息的实体类") +public class DayWorkMationRest implements Serializable { + + @ApiModelProperty(value = "月份里面的天", required = "required") + private List> beans; + + @ApiModelProperty(value = "月份", required = "required") + private List months; + + @ApiModelProperty(value = "考勤班次id", required = "required") + private String timeId; + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/UserOtherDayMationRest.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/UserOtherDayMationRest.java new file mode 100644 index 0000000..d32e189 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/checkwork/entity/UserOtherDayMationRest.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.checkwork.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: UserOtherDayMationParams + * @Description: 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如 : 请假 , 出差 , 加班等)的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 21:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等)的实体类") +public class UserOtherDayMationRest implements Serializable { + + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @ApiModelProperty(value = "考勤班次id", required = "required") + private String timeId; + + @ApiModelProperty(value = "月份", required = "required") + private List months; + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/pro/win/SysEveWinDragDropService.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/pro/win/SysEveWinDragDropService.java new file mode 100644 index 0000000..1042bb4 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/rest/pro/win/SysEveWinDragDropService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.pro.win; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: SysEveWinDragDropService + * @Description: 自定义桌面菜单服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/6 0:18 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface SysEveWinDragDropService { + + /** + * 新增轻应用到桌面菜单 + * + * @param params 入参 + * @return + */ + @PostMapping("/sysevewindragdrop002") + String insertWinCustomMenu(Map params); + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/util/MqSendUtil.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/util/MqSendUtil.java new file mode 100644 index 0000000..209fcba --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/util/MqSendUtil.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.util; + +import com.skyeye.common.util.SpringUtils; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.eve.service.IJobMateMationService; + +/** + * @ClassName: MqSendUtil + * @Description: mq消息相关的工具类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/3 23:24 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class MqSendUtil { + + /** + * 修改任务信息 + * + * @param jobId 任务id + * @param status 状态 + * @param responseBody 放入任务结果集的值 + */ + public static void comMQJobMation(String jobId, String status, String responseBody) { + JobMateUpdateMation jobMateUpdateMation = new JobMateUpdateMation(); + jobMateUpdateMation.setJobId(jobId); + jobMateUpdateMation.setStatus(status); + jobMateUpdateMation.setResponseBody(responseBody); + IJobMateMationService iJobMateMationService = SpringUtils.getBean(IJobMateMationService.class); + iJobMateMationService.comMQJobMation(jobMateUpdateMation); + } + +} diff --git a/skyeye-adm/adm-common/src/main/java/com/skyeye/util/OfficeUtils.java b/skyeye-adm/adm-common/src/main/java/com/skyeye/util/OfficeUtils.java new file mode 100644 index 0000000..a9fad15 --- /dev/null +++ b/skyeye-adm/adm-common/src/main/java/com/skyeye/util/OfficeUtils.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.util; + +import com.aspose.words.Document; +import com.aspose.words.ImageSaveOptions; +import com.aspose.words.SaveFormat; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageInputStream; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @ClassName: OfficeUtils + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/4/30 14:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class OfficeUtils { + + /** + * 验证aspose.word组件是否授权:无授权的文件有水印标记 + * 需要使用(aspose-words-15.8.0-jdk16.jar),版本要对应。无水印 + * + * @return + */ + public static boolean isWordLicense() { + boolean result = false; + try { + String s = "Aspose.Total for JavaAspose.Words for JavaEnterprise20991231209912318bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU="; + ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes()); + com.aspose.words.License license = new com.aspose.words.License(); + license.setLicense(inputStream); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + //outputStream转inputStream + public static ByteArrayInputStream parse(OutputStream out) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos = (ByteArrayOutputStream) out; + ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray()); + return swapStream; + } + + /** + * word和txt文件转换图片 + * + * @param inputStream + * @param + * @return + * @throws Exception + */ + public static List wordToImg(InputStream inputStream) throws Exception { + if (!isWordLicense()) { + return null; + } + try { + Date start = new Date(); + Document doc = new Document(inputStream); + ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG); + options.setPrettyFormat(true); + options.setUseAntiAliasing(true); + options.setUseHighQualityRendering(true); + int pageCount = doc.getPageCount(); + //生成前pageCount张,这可以限制输出长图时的页数(方法入参可以传值pageNum) + /*if (pageCount > pageNum) { + pageCount = pageNum; + }*/ + List imageList = new ArrayList<>(); + for (int i = 0; i < pageCount; i++) { + OutputStream output = new ByteArrayOutputStream(); + options.setPageIndex(i); + doc.save(output, options); + ImageInputStream imageInputStream = javax.imageio.ImageIO.createImageInputStream(parse(output)); + imageList.add(javax.imageio.ImageIO.read(imageInputStream)); + } + List imageList2 = new ArrayList(); + //这个重新生成新的图片是因为直接输出的图片底色为红色 + for (int j = 0; j < imageList.size(); j++) { + // 生成新图片 + BufferedImage destImage = imageList.get(j); + int w1 = destImage.getWidth(); + int h1 = destImage.getHeight(); + destImage = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB); + Graphics2D g2 = (Graphics2D) destImage.getGraphics(); + g2.setBackground(Color.LIGHT_GRAY); + g2.clearRect(0, 0, w1, h1); + g2.setPaint(Color.RED); + // 从图片中读取RGB + int[] ImageArrayOne = new int[w1 * h1]; + ImageArrayOne = imageList.get(j).getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中 + destImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB + imageList2.add(destImage); + } + Date end = new Date(); + long l = end.getTime() - start.getTime(); + long hour = l / (1000 * 60 * 60); + long min = (l - hour * (1000 * 60 * 60)) / (1000 * 60); + long s = (l - hour * (1000 * 60 * 60) - min * 1000 * 60) / (1000); + long ss = (l - hour * (1000 * 60 * 60) - min * 1000 * 60 - s * 1000) / (1000 / 60); + System.out.println("word转图片时间:" + min + "分" + s + "秒" + ss + "毫秒");//hour+"小时"+ + return imageList2; + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + /** + * 合并任数量的图片成一张图片 + * + * @param isHorizontal true代表水平合并,fasle代表垂直合并 + * @param imgs 待合并的图片数组 + * @return + * @throws IOException + */ + public static BufferedImage mergeImage(boolean isHorizontal, List imgs) throws IOException { + // 生成新图片 + BufferedImage destImage = null; + // 计算新图片的长和高 + int allw = 0, allh = 0, allwMax = 0, allhMax = 0; + // 获取总长、总宽、最长、最宽 + for (int i = 0; i < imgs.size(); i++) { + BufferedImage img = imgs.get(i); + allw += img.getWidth(); + if (imgs.size() != i + 1) { + allh += img.getHeight() + 5; + } else { + allh += img.getHeight(); + } + if (img.getWidth() > allwMax) { + allwMax = img.getWidth(); + } + if (img.getHeight() > allhMax) { + allhMax = img.getHeight(); + } + } + // 创建新图片 + if (isHorizontal) { + destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB); + } else { + destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB); + } + Graphics2D g2 = (Graphics2D) destImage.getGraphics(); + g2.setBackground(Color.LIGHT_GRAY); + g2.clearRect(0, 0, allw, allh); + g2.setPaint(Color.RED); + + // 合并所有子图片到新图片 + int wx = 0, wy = 0; + for (int i = 0; i < imgs.size(); i++) { + BufferedImage img = imgs.get(i); + int w1 = img.getWidth(); + int h1 = img.getHeight(); + // 从图片中读取RGB + int[] ImageArrayOne = new int[w1 * h1]; + ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中 + if (isHorizontal) { // 水平方向合并 + destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB + } else { // 垂直方向合并 + destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB + } + wx += w1; + wy += h1 + 5; + } + return destImage; + } + + + // 测试工具类 + public static void main(String[] args) { + //word转图片格式 + try { + File file = new File("G:\\test\\test22.docx"); + InputStream inStream = new FileInputStream(file); + List wordToImg = wordToImg(inStream); + //for(int i=0; i + + + skyeye-adm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + adm-ehr + + + + + com.skyeye + adm-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/controller/ArchivesController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/controller/ArchivesController.java new file mode 100644 index 0000000..e30f99e --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/controller/ArchivesController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.archives.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.archives.entity.Archives; +import com.skyeye.archives.service.ArchivesService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ArchivesController + * @Description: 员工档案管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/10 16:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工档案", tags = "员工档案", modelName = "员工档案") +public class ArchivesController { + + @Autowired + private ArchivesService archivesService; + + /** + * 查询档案信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysStaffArchivesList", value = "查询档案信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArchivesController/querySysStaffArchivesList") + public void querySysStaffArchivesList(InputObject inputObject, OutputObject outputObject) { + archivesService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工档案信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysStaffArchives", value = "新增/编辑员工档案信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Archives.class) + @RequestMapping("/post/ArchivesController/writeSysStaffArchives") + public void writeSysStaffArchives(InputObject inputObject, OutputObject outputObject) { + archivesService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除员工档案信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSysStaffArchivesById", value = "删除员工档案信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArchivesController/deleteSysStaffArchivesById") + public void deleteSysStaffArchivesById(InputObject inputObject, OutputObject outputObject) { + archivesService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/dao/ArchivesDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/dao/ArchivesDao.java new file mode 100644 index 0000000..b55d356 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/dao/ArchivesDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.archives.dao; + +import com.skyeye.archives.entity.Archives; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArchivesDao + * @Description: 员工档案管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArchivesDao extends SkyeyeBaseMapper { + + List> querySysStaffArchivesList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/entity/Archives.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/entity/Archives.java new file mode 100644 index 0000000..a178965 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/entity/Archives.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.archives.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Archives + * @Description: 员工档案实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/20 20:46 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "objectKey", "archivesNumber"}) +@RedisCacheField(name = "ehr:archives", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_archives") +@ApiModel("员工档案实体类") +public class Archives extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "archives_number") + @ApiModelProperty(value = "档案编号", required = "required") + private String archivesNumber; + + @TableField(value = "company_id") + @ApiModelProperty(value = "管理单位id", required = "required") + private String companyId; + + @TableField(exist = false) + @Property(value = "管理单位信息") + private Map companyMation; + + @TableField(value = "custody_place") + @ApiModelProperty(value = "档案保管地") + private String custodyPlace; + + @TableField(value = "archives_center") + @ApiModelProperty(value = "档案室") + private String archivesCenter; + + @TableField(value = "archives_time") + @ApiModelProperty(value = "入档时间", required = "required") + private String archivesTime; + + @TableField(value = "education_id") + @ApiModelProperty(value = "档案学历id。数据来源:数据字典") + private String educationId; + + @TableField(value = "whether_archives") + @ApiModelProperty(value = "是否在档,参考#WhetherEnum", required = "required,num") + private Integer whetherArchives; + + @TableField(value = "state") + @ApiModelProperty(value = "是否有效,参考#WhetherEnum", required = "required,num") + private Integer state; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/ArchivesService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/ArchivesService.java new file mode 100644 index 0000000..4d352fc --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/ArchivesService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.archives.service; + +import com.skyeye.archives.entity.Archives; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: ArchivesService + * @Description: 员工档案管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArchivesService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/impl/ArchivesServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/impl/ArchivesServiceImpl.java new file mode 100644 index 0000000..059c649 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/archives/service/impl/ArchivesServiceImpl.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.archives.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.archives.dao.ArchivesDao; +import com.skyeye.archives.entity.Archives; +import com.skyeye.archives.service.ArchivesService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArchivesServiceImpl + * @Description: 员工档案管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工档案", groupName = "员工档案", teamAuth = true) +public class ArchivesServiceImpl extends SkyeyeBusinessServiceImpl implements ArchivesService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySysStaffArchivesList(commonPageInfo); + return beans; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/controller/CertificateController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/controller/CertificateController.java new file mode 100644 index 0000000..64d2bae --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/controller/CertificateController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certificate.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.certificate.entity.Certificate; +import com.skyeye.certificate.service.CertificateService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CertificateController + * @Description: 员工证书管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工证书", tags = "员工证书", modelName = "员工证书") +public class CertificateController { + + @Autowired + private CertificateService certificateService; + + /** + * 查询员工证书列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCertificateList", value = "查询员工证书列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CertificateController/queryCertificateList") + public void queryCertificateList(InputObject inputObject, OutputObject outputObject) { + certificateService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工证书信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCertificate", value = "新增/编辑员工证书信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Certificate.class) + @RequestMapping("/post/CertificateController/writeCertificate") + public void writeCertificate(InputObject inputObject, OutputObject outputObject) { + certificateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工证书信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCertificateById", value = "根据id删除员工证书信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CertificateController/deleteCertificateById") + public void deleteCertificateById(InputObject inputObject, OutputObject outputObject) { + certificateService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/dao/CertificateDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/dao/CertificateDao.java new file mode 100644 index 0000000..ee88030 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/dao/CertificateDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certificate.dao; + +import com.skyeye.certificate.entity.Certificate; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CertificateDao + * @Description: 员工证书管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CertificateDao extends SkyeyeBaseMapper { + + List> queryCertificateList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/entity/Certificate.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/entity/Certificate.java new file mode 100644 index 0000000..714ff81 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/entity/Certificate.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certificate.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Certificate + * @Description: 员工证书实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 11:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ehr:certificate", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_certificate") +@ApiModel("员工证书实体类") +public class Certificate extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "certificate_number") + @ApiModelProperty(value = "证书编号", required = "required") + private String certificateNumber; + + @TableField(value = "`name`") + @ApiModelProperty(value = "证书名称", required = "required") + private String name; + + @TableField(value = "type_id") + @ApiModelProperty(value = "证书类型,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "证书类型信息") + private Map typeMation; + + @TableField(value = "issue_organ") + @ApiModelProperty(value = "签发机构", required = "required") + private String issueOrgan; + + @TableField(value = "issue_time") + @ApiModelProperty(value = "签发时间", required = "required") + private String issueTime; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/CertificateService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/CertificateService.java new file mode 100644 index 0000000..d2844f5 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/CertificateService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certificate.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.certificate.entity.Certificate; + +/** + * @ClassName: CertificateService + * @Description: 员工证书管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CertificateService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/impl/CertificateServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/impl/CertificateServiceImpl.java new file mode 100644 index 0000000..25698c2 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/certificate/service/impl/CertificateServiceImpl.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certificate.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.certificate.dao.CertificateDao; +import com.skyeye.certificate.entity.Certificate; +import com.skyeye.certificate.service.CertificateService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CertificateServiceImpl + * @Description: 员工证书管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工证书", groupName = "员工证书", teamAuth = true) +public class CertificateServiceImpl extends SkyeyeBusinessServiceImpl implements CertificateService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryCertificateList(commonPageInfo); + return beans; + } + + @Override + public Certificate selectById(String id) { + Certificate certificate = super.selectById(id); + iSysDictDataService.setDataMation(certificate, Certificate::getTypeId); + return certificate; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/controller/ContractController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/controller/ContractController.java new file mode 100644 index 0000000..97cdba1 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/controller/ContractController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.Contract; +import com.skyeye.contract.service.ContractService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ContractController + * @Description: 员工合同信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 7:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工合同信息", tags = "员工合同信息", modelName = "员工合同信息") +public class ContractController { + + @Autowired + private ContractService contractService; + + /** + * 查询合同列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryContractList", value = "查询合同列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ContractController/queryContractList") + public void queryContractList(InputObject inputObject, OutputObject outputObject) { + contractService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeContract", value = "新增/编辑员工合同信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Contract.class) + @RequestMapping("/post/ContractController/writeContract") + public void writeContract(InputObject inputObject, OutputObject outputObject) { + contractService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteContractById", value = "根据id删除员工合同信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ContractController/deleteContractById") + public void deleteContractById(InputObject inputObject, OutputObject outputObject) { + contractService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/dao/ContractDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/dao/ContractDao.java new file mode 100644 index 0000000..2fe7cf9 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/dao/ContractDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.contract.entity.Contract; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ContractDao + * @Description: 员工合同管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 20:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ContractDao extends SkyeyeBaseMapper { + + List> queryContractList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/entity/Contract.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/entity/Contract.java new file mode 100644 index 0000000..e0c4643 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/entity/Contract.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Contract + * @Description: 员工合同信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 11:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"contractNumber"}) +@RedisCacheField(name = "ehr:contract", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_contract") +@ApiModel("员工合同信息实体类") +public class Contract extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "contract_number") + @ApiModelProperty(value = "合同编号", required = "required") + private String contractNumber; + + @TableField(value = "type_id") + @ApiModelProperty(value = "合同类别,参考数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "合同类别信息") + private Map typeMation; + + @TableField(value = "mold_id") + @ApiModelProperty(value = "合同类型,参考数据字典", required = "required") + private String moldId; + + @TableField(exist = false) + @Property(value = "合同类型信息") + private Map moldMation; + + @TableField(value = "start_time") + @ApiModelProperty(value = "开始时间", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "结束时间", required = "required") + private String endTime; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/ContractService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/ContractService.java new file mode 100644 index 0000000..a51222a --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/ContractService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.contract.entity.Contract; + +/** + * @ClassName: ContractService + * @Description: 员工合同信息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ContractService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/impl/ContractServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/impl/ContractServiceImpl.java new file mode 100644 index 0000000..c7fc85b --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/contract/service/impl/ContractServiceImpl.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.contract.dao.ContractDao; +import com.skyeye.contract.entity.Contract; +import com.skyeye.contract.service.ContractService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ContractServiceImpl + * @Description: 员工合同管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工合同信息", groupName = "员工合同信息", teamAuth = true) +public class ContractServiceImpl extends SkyeyeBusinessServiceImpl implements ContractService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryContractList(commonPageInfo); + return beans; + } + + @Override + public Contract selectById(String id) { + Contract contract = super.selectById(id); + iSysDictDataService.setDataMation(contract, Contract::getTypeId); + iSysDictDataService.setDataMation(contract, Contract::getMoldId); + return contract; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/controller/EducationController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/controller/EducationController.java new file mode 100644 index 0000000..08a2800 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/controller/EducationController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.education.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.education.entity.Education; +import com.skyeye.education.service.EducationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EducationController + * @Description: 员工教育背景管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 7:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工教育背景", tags = "员工教育背景", modelName = "员工教育背景") +public class EducationController { + + @Autowired + private EducationService educationService; + + /** + * 查询教育背景列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEducationList", value = "查询教育背景列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EducationController/queryEducationList") + public void queryEducationList(InputObject inputObject, OutputObject outputObject) { + educationService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工教育背景信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeEducation", value = "新增/编辑员工教育背景信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Education.class) + @RequestMapping("/post/EducationController/writeEducation") + public void writeEducation(InputObject inputObject, OutputObject outputObject) { + educationService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工教育背景信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteEducationById", value = "根据id删除员工教育背景信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/EducationController/deleteEducationById") + public void deleteEducationById(InputObject inputObject, OutputObject outputObject) { + educationService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/dao/EducationDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/dao/EducationDao.java new file mode 100644 index 0000000..98b86ae --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/dao/EducationDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.education.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.education.entity.Education; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EducationDao + * @Description: 员工教育背景管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EducationDao extends SkyeyeBaseMapper { + + List> queryEducationList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/entity/Education.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/entity/Education.java new file mode 100644 index 0000000..d67a435 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/entity/Education.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.education.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Education + * @Description: 员工教育背景实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 11:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ehr:education", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_education") +@ApiModel("员工教育背景实体类") +public class Education extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "education_id") + @ApiModelProperty(value = "学历id,参考数据字典", required = "required") + private String educationId; + + @TableField(exist = false) + @Property(value = "学历信息") + private Map educationMation; + + @TableField(value = "start_time") + @ApiModelProperty(value = "入校时间", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "毕业时间", required = "required") + private String endTime; + + @TableField(value = "graduction_school") + @ApiModelProperty(value = "毕业学校", required = "required") + private String graductionSchool; + + @TableField(value = "major") + @ApiModelProperty(value = "专业") + private String major; + + @TableField(value = "learning_modality_id") + @ApiModelProperty(value = "学习形式,参考数据字典", required = "required") + private String learningModalityId; + + @TableField(exist = false) + @Property(value = "学习形式信息") + private Map learningModalityMation; + + @TableField(value = "school_nature") + @ApiModelProperty(value = "学校性质,参考数据字典", required = "required") + private String schoolNature; + + @TableField(exist = false) + @Property(value = "学校性质信息") + private Map schoolNatureMation; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/EducationService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/EducationService.java new file mode 100644 index 0000000..eb9b818 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/EducationService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.education.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.education.entity.Education; + +/** + * @ClassName: EducationService + * @Description: 员工教育背景管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EducationService extends SkyeyeBusinessService { + + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/impl/EducationServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/impl/EducationServiceImpl.java new file mode 100644 index 0000000..2ede47c --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/education/service/impl/EducationServiceImpl.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.education.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.education.dao.EducationDao; +import com.skyeye.education.entity.Education; +import com.skyeye.education.service.EducationService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EducationServiceImpl + * @Description: 员工教育背景管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工教育背景", groupName = "员工教育背景", teamAuth = true) +public class EducationServiceImpl extends SkyeyeBusinessServiceImpl implements EducationService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryEducationList(commonPageInfo); + return beans; + } + + @Override + public Education selectById(String id) { + Education education = super.selectById(id); + iSysDictDataService.setDataMation(education, Education::getEducationId); + iSysDictDataService.setDataMation(education, Education::getLearningModalityId); + iSysDictDataService.setDataMation(education, Education::getSchoolNature); + return education; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/controller/FamilyController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/controller/FamilyController.java new file mode 100644 index 0000000..3b785ba --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/controller/FamilyController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.family.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.family.entity.Family; +import com.skyeye.family.service.FamilyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FamilyController + * @Description: 员工家庭成员信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 7:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工家庭成员", tags = "员工家庭成员", modelName = "员工家庭成员") +public class FamilyController { + + @Autowired + private FamilyService familyService; + + /** + * 查询家庭情况列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFamilyList", value = "查询家庭情况列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FamilyController/queryFamilyList") + public void queryFamilyList(InputObject inputObject, OutputObject outputObject) { + familyService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工家庭情况 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeFamily", value = "新增/编辑员工家庭情况", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Family.class) + @RequestMapping("/post/FamilyController/writeFamily") + public void writeFamily(InputObject inputObject, OutputObject outputObject) { + familyService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工家庭情况信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFamilyById", value = "根据id删除员工家庭情况信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FamilyController/deleteFamilyById") + public void deleteFamilyById(InputObject inputObject, OutputObject outputObject) { + familyService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/dao/FamilyDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/dao/FamilyDao.java new file mode 100644 index 0000000..014587a --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/dao/FamilyDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.family.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.family.entity.Family; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FamilyDao + * @Description: 员工家庭情况管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FamilyDao extends SkyeyeBaseMapper { + + List> queryFamilyList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/entity/Family.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/entity/Family.java new file mode 100644 index 0000000..8227f5b --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/entity/Family.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.family.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Family + * @Description: 员工家庭情况实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 11:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ehr:family", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_family") +@ApiModel("员工家庭情况实体类") +public class Family extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "relationship_id") + @ApiModelProperty(value = "与本人关系id,参考数据字典", required = "required") + private String relationshipId; + + @TableField(exist = false) + @Property(value = "与本人关系信息") + private Map relationshipMation; + + @TableField(value = "`name`") + @ApiModelProperty(value = "姓名", required = "required") + private String name; + + @TableField(value = "card_type") + @ApiModelProperty(value = "证件类型id,参考数据字典", required = "required") + private String cardType; + + @TableField(exist = false) + @Property(value = "证件类型信息") + private Map cardTypeMation; + + @TableField(value = "card_number") + @ApiModelProperty(value = "证件号码", required = "required") + private String cardNumber; + + @TableField(value = "sex") + @ApiModelProperty(value = "性别,参考#SexEnum", required = "required") + private Integer sex; + + @TableField(value = "work_unit") + @ApiModelProperty(value = "工作单位", required = "required") + private String workUnit; + + @TableField(value = "job") + @ApiModelProperty(value = "职位", required = "required") + private String job; + + @TableField(value = "politic_id") + @ApiModelProperty(value = "政治面貌id,参考数据字典", required = "required") + private String politicId; + + @TableField(exist = false) + @Property(value = "政治面貌信息") + private Map politicMation; + + @TableField(value = "emergency_contact") + @ApiModelProperty(value = "是否紧急联系人,参考#WhetherEnum", required = "required") + private String emergencyContact; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/FamilyService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/FamilyService.java new file mode 100644 index 0000000..136de6d --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/FamilyService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.family.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.family.entity.Family; + +/** + * @ClassName: FamilyService + * @Description: 员工家庭情况管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 17:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FamilyService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/impl/FamilyServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/impl/FamilyServiceImpl.java new file mode 100644 index 0000000..d0e41a1 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/family/service/impl/FamilyServiceImpl.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.family.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.family.dao.FamilyDao; +import com.skyeye.family.entity.Family; +import com.skyeye.family.service.FamilyService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FamilyServiceImpl + * @Description: 员工家庭情况管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工家庭成员", groupName = "员工家庭成员", teamAuth = true) +public class FamilyServiceImpl extends SkyeyeBusinessServiceImpl implements FamilyService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryFamilyList(commonPageInfo); + return beans; + } + + @Override + public Family selectById(String id) { + Family family = super.selectById(id); + iSysDictDataService.setDataMation(family, Family::getCardType); + iSysDictDataService.setDataMation(family, Family::getPoliticId); + iSysDictDataService.setDataMation(family, Family::getRelationshipId); + return family; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/controller/JobResumeController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/controller/JobResumeController.java new file mode 100644 index 0000000..04a8928 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/controller/JobResumeController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.job.entity.JobResume; +import com.skyeye.job.service.JobResumeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: JobResumeController + * @Description: 员工工作履历管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 7:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工工作履历信息", tags = "员工工作履历信息", modelName = "员工工作履历信息") +public class JobResumeController { + + @Autowired + private JobResumeService jobResumeService; + + /** + * 查询工作履历列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryJobResumeList", value = "查询工作履历列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/JobResumeController/queryJobResumeList") + public void queryJobResumeList(InputObject inputObject, OutputObject outputObject) { + jobResumeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工工作履历信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeJobResume", value = "新增/编辑员工工作履历信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = JobResume.class) + @RequestMapping("/post/JobResumeController/writeJobResume") + public void writeJobResume(InputObject inputObject, OutputObject outputObject) { + jobResumeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工工作履历信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteEducationById", value = "根据id删除员工工作履历信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/JobResumeController/deleteJobResumeById") + public void deleteJobResumeById(InputObject inputObject, OutputObject outputObject) { + jobResumeService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/dao/JobResumeDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/dao/JobResumeDao.java new file mode 100644 index 0000000..0531083 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/dao/JobResumeDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.job.entity.JobResume; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobResumeDao + * @Description: 员工工作履历管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/18 14:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JobResumeDao extends SkyeyeBaseMapper { + + List> queryJobResumeList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/entity/JobResume.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/entity/JobResume.java new file mode 100644 index 0000000..4f29c9f --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/entity/JobResume.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: JobResume + * @Description: 员工工作履历实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 11:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ehr:jobResume", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_job_resume") +@ApiModel("员工工作履历实体类") +public class JobResume extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "start_time") + @ApiModelProperty(value = "任职开始时间", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "任职结束时间", required = "required") + private String endTime; + + @TableField(value = "work_unit") + @ApiModelProperty(value = "任职单位", required = "required") + private String workUnit; + + @TableField(value = "department") + @ApiModelProperty(value = "部门", required = "required") + private String department; + + @TableField(value = "job") + @ApiModelProperty(value = "职务", required = "required") + private String job; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/JobResumeService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/JobResumeService.java new file mode 100644 index 0000000..53ef636 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/JobResumeService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.job.entity.JobResume; + +/** + * @ClassName: JobResumeService + * @Description: 员工工作履历管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/18 14:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JobResumeService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/impl/JobResumeServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/impl/JobResumeServiceImpl.java new file mode 100644 index 0000000..7ace830 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/job/service/impl/JobResumeServiceImpl.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.job.dao.JobResumeDao; +import com.skyeye.job.entity.JobResume; +import com.skyeye.job.service.JobResumeService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobResumeServiceImpl + * @Description: 员工工作履历管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工工作履历信息", groupName = "员工工作履历信息", teamAuth = true) +public class JobResumeServiceImpl extends SkyeyeBusinessServiceImpl implements JobResumeService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryJobResumeList(commonPageInfo); + return beans; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/controller/LanguageController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/controller/LanguageController.java new file mode 100644 index 0000000..55f40c2 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/controller/LanguageController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.language.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.language.entity.Language; +import com.skyeye.language.service.LanguageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LanguageController + * @Description: 员工语言能力信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 7:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工语言能力", tags = "员工语言能力", modelName = "员工语言能力") +public class LanguageController { + + @Autowired + private LanguageService languageService; + + /** + * 查询语言能力列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLanguageList", value = "查询语言能力列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LanguageController/queryLanguageList") + public void queryLanguageList(InputObject inputObject, OutputObject outputObject) { + languageService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工语言能力 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLanguage", value = "新增/编辑员工语言能力", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Language.class) + @RequestMapping("/post/LanguageController/writeLanguage") + public void writeLanguage(InputObject inputObject, OutputObject outputObject) { + languageService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工语言能力 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLanguageById", value = "根据id删除员工语言能力", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LanguageController/deleteLanguageById") + public void deleteLanguageById(InputObject inputObject, OutputObject outputObject) { + languageService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/dao/LanguageDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/dao/LanguageDao.java new file mode 100644 index 0000000..b346f9c --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/dao/LanguageDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.language.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.language.entity.Language; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LanguageDao + * @Description: 员工语言能力信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/18 14:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LanguageDao extends SkyeyeBaseMapper { + + List> queryLanguageList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/entity/Language.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/entity/Language.java new file mode 100644 index 0000000..0a24c04 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/entity/Language.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.language.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Language + * @Description: 员工语言能力信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/20 20:46 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "objectKey", "levelId"}) +@RedisCacheField(name = "ehr:language", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_language") +@ApiModel("员工语言能力信息实体类") +public class Language extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "level_id") + @ApiModelProperty(value = "语种等级id,参考数据字典", required = "required") + private String levelId; + + @TableField(exist = false) + @Property(value = "语种等级信息") + private Map levelMation; + + @TableField(value = "get_time") + @ApiModelProperty(value = "获取时间", required = "required") + private String getTime; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosure; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/LanguageService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/LanguageService.java new file mode 100644 index 0000000..76c4192 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/LanguageService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.language.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.language.entity.Language; + +/** + * @ClassName: LanguageService + * @Description: 员工语言能力管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LanguageService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/impl/LanguageServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/impl/LanguageServiceImpl.java new file mode 100644 index 0000000..b8d52cd --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/language/service/impl/LanguageServiceImpl.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.language.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.language.dao.LanguageDao; +import com.skyeye.language.entity.Language; +import com.skyeye.language.service.LanguageService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LanguageServiceImpl + * @Description: 员工语言能力管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工语言能力", groupName = "员工语言能力", teamAuth = true) +public class LanguageServiceImpl extends SkyeyeBusinessServiceImpl implements LanguageService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryLanguageList(commonPageInfo); + return beans; + } + + @Override + public Language selectById(String id) { + Language language = super.selectById(id); + iSysDictDataService.setDataMation(language, Language::getLevelId); + return language; + } +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/controller/RewardPunishController.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/controller/RewardPunishController.java new file mode 100644 index 0000000..6c45495 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/controller/RewardPunishController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reward.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.reward.entity.RewardPunish; +import com.skyeye.reward.service.RewardPunishService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RewardPunishController + * @Description: 员工奖惩信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/17 8:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工奖惩信息", tags = "员工奖惩信息", modelName = "员工奖惩信息") +public class RewardPunishController { + + @Autowired + private RewardPunishService rewardPunishService; + + /** + * 查询奖惩列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRewardPunishList", value = "查询奖惩列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RewardPunishController/queryRewardPunishList") + public void queryRewardPunishList(InputObject inputObject, OutputObject outputObject) { + rewardPunishService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工奖惩信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRewardPunish", value = "新增/编辑员工奖惩信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = RewardPunish.class) + @RequestMapping("/post/RewardPunishController/writeRewardPunish") + public void writeRewardPunish(InputObject inputObject, OutputObject outputObject) { + rewardPunishService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除员工奖惩信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteRewardPunishById", value = "根据id删除员工奖惩信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RewardPunishController/deleteRewardPunishById") + public void deleteRewardPunishById(InputObject inputObject, OutputObject outputObject) { + rewardPunishService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/dao/RewardPunishDao.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/dao/RewardPunishDao.java new file mode 100644 index 0000000..a98589b --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/dao/RewardPunishDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reward.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.reward.entity.RewardPunish; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: RewardPunishDao + * @Description: 员工奖惩管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RewardPunishDao extends SkyeyeBaseMapper { + + List> queryRewardPunishList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/entity/RewardPunish.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/entity/RewardPunish.java new file mode 100644 index 0000000..a9dc101 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/entity/RewardPunish.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reward.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: RewardPunish + * @Description: 员工奖惩信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/20 20:46 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ehr:rewardPunish", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_staff_reward_punish") +@ApiModel("员工奖惩信息实体类") +public class RewardPunish extends BaseGeneralInfo { + + @TableField(value = "reward_punish_time") + @ApiModelProperty(value = "奖惩时间", required = "required") + private String rewardPunishTime; + + @TableField(value = "price") + @ApiModelProperty(value = "奖惩金额", required = "double", defaultValue = "0") + private String price; + + @TableField(value = "content") + @ApiModelProperty(value = "奖惩事件描述", required = "required") + private String content; + + @TableField(value = "type_id") + @ApiModelProperty(value = "奖惩分类id,参考数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "奖惩分类信息") + private Map typeMation; + + @TableField(value = "award_unit") + @ApiModelProperty(value = "授予单位", required = "required") + private String awardUnit; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id(员工id)", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key(员工key)", required = "required") + private String objectKey; + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/RewardPunishService.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/RewardPunishService.java new file mode 100644 index 0000000..0c8e878 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/RewardPunishService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reward.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.reward.entity.RewardPunish; + +/** + * @ClassName: RewardPunishService + * @Description: 员工奖惩管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RewardPunishService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/impl/RewardPunishServiceImpl.java b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/impl/RewardPunishServiceImpl.java new file mode 100644 index 0000000..108cbda --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/java/com/skyeye/reward/service/impl/RewardPunishServiceImpl.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reward.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.reward.dao.RewardPunishDao; +import com.skyeye.reward.entity.RewardPunish; +import com.skyeye.reward.service.RewardPunishService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: RewardPunishServiceImpl + * @Description: 员工奖惩管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工奖惩信息", groupName = "员工奖惩信息", teamAuth = true) +public class RewardPunishServiceImpl extends SkyeyeBusinessServiceImpl implements RewardPunishService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryRewardPunishList(commonPageInfo); + return beans; + } + + @Override + public RewardPunish selectById(String id) { + RewardPunish rewardPunish = super.selectById(id); + iSysDictDataService.setDataMation(rewardPunish, RewardPunish::getTypeId); + return rewardPunish; + } + +} diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/archives/ArchivesMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/archives/ArchivesMapper.xml new file mode 100644 index 0000000..79688b8 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/archives/ArchivesMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/certificate/CertificateMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/certificate/CertificateMapper.xml new file mode 100644 index 0000000..0ee66de --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/certificate/CertificateMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/contract/ContractMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/contract/ContractMapper.xml new file mode 100644 index 0000000..ba9f8ae --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/contract/ContractMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/education/EducationMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/education/EducationMapper.xml new file mode 100644 index 0000000..8a5ccde --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/education/EducationMapper.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/family/FamilyMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/family/FamilyMapper.xml new file mode 100644 index 0000000..6d94e46 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/family/FamilyMapper.xml @@ -0,0 +1,37 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/job/JobResumeMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/job/JobResumeMapper.xml new file mode 100644 index 0000000..64011f9 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/job/JobResumeMapper.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/language/LanguageMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/language/LanguageMapper.xml new file mode 100644 index 0000000..650e9fd --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/language/LanguageMapper.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-ehr/src/main/resources/mapper/reward/RewardPunishMapper.xml b/skyeye-adm/adm-ehr/src/main/resources/mapper/reward/RewardPunishMapper.xml new file mode 100644 index 0000000..814f4b5 --- /dev/null +++ b/skyeye-adm/adm-ehr/src/main/resources/mapper/reward/RewardPunishMapper.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/.gitignore b/skyeye-adm/adm-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-adm/adm-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-adm/adm-pro/lib/epublib-core-latest.jar b/skyeye-adm/adm-pro/lib/epublib-core-latest.jar new file mode 100644 index 0000000..6799a30 Binary files /dev/null and b/skyeye-adm/adm-pro/lib/epublib-core-latest.jar differ diff --git a/skyeye-adm/adm-pro/pom.xml b/skyeye-adm/adm-pro/pom.xml new file mode 100644 index 0000000..90005ba --- /dev/null +++ b/skyeye-adm/adm-pro/pom.xml @@ -0,0 +1,67 @@ + + + + skyeye-adm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + adm-pro + + + + + com.skyeye + adm-survey + 1.0-SNAPSHOT + + + + com.skyeye + adm-ehr + 1.0-SNAPSHOT + + + + com.deepoove + poi-tl + 1.9.1 + + + + io.github.draco1023 + poi-tl-ext + 0.3.3 + + + com.deepoove + poi-tl + + + commons-io + commons-io + + + + + + + epublib-core + latest + 1.3.1 + system + ${basedir}/lib/epublib-core-latest.jar + + + + org.springframework.boot + spring-boot-starter-data-solr + 2.4.9 + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesController.java new file mode 100644 index 0000000..70dbe31 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.entity.Articles; +import com.skyeye.eve.articles.service.ArticlesService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ArticlesController + * @Description: 用品管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用品管理", tags = "用品管理", modelName = "用品模块") +public class ArticlesController { + + @Autowired + private ArticlesService articlesService; + + /** + * 新增/编辑用品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetArticlesMation", value = "新增/编辑用品信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Articles.class) + @RequestMapping("/post/ArticlesController/writeAssetArticlesMation") + public void writeArticlesMation(InputObject inputObject, OutputObject outputObject) { + articlesService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取用品列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles012", value = "获取用品列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArticlesController/queryArticlesList") + public void queryArticlesList(InputObject inputObject, OutputObject outputObject) { + articlesService.queryPageList(inputObject, outputObject); + } + + /** + * 删除用品 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles014", value = "删除用品", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArticlesController/deleteArticles") + public void deleteArticles(InputObject inputObject, OutputObject outputObject) { + articlesService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有用品列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles018", value = "获取所有用品列表信息", method = "GET", allUse = "2") + @RequestMapping("/post/ArticlesController/queryAllArticlesList") + public void queryAllArticlesList(InputObject inputObject, OutputObject outputObject) { + articlesService.queryAllArticlesList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesPurchaseController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesPurchaseController.java new file mode 100644 index 0000000..e35725d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesPurchaseController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.entity.ArticlesPurchase; +import com.skyeye.eve.articles.service.ArticlesPurchaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ArticlesPurchaseController + * @Description: 用品采购申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用品采购", tags = "用品采购", modelName = "用品模块") +public class ArticlesPurchaseController { + + @Autowired + private ArticlesPurchaseService articlesPurchaseService; + + /** + * 用品采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeArticlesPurchase", value = "用品采购申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ArticlesPurchase.class) + @RequestMapping("/post/ArticlesPurchaseController/writeArticlesPurchasee") + public void writeArticlesPurchasee(InputObject inputObject, OutputObject outputObject) { + articlesPurchaseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取用品采购申请信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles025", value = "获取用品采购申请信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArticlesPurchaseController/queryArticlesPurchaseList") + public void queryArticlesPurchaseList(InputObject inputObject, OutputObject outputObject) { + articlesPurchaseService.queryPageList(inputObject, outputObject); + } + + /** + * 用品采购申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles027", value = "用品采购申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ArticlesPurchaseController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + articlesPurchaseService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废用品采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles031", value = "作废用品采购申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArticlesPurchaseController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + articlesPurchaseService.invalid(inputObject, outputObject); + } + + /** + * 撤销用品采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles035", value = "撤销用品采购申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ArticlesPurchaseController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + articlesPurchaseService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesUseController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesUseController.java new file mode 100644 index 0000000..60fc069 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/controller/ArticlesUseController.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.entity.ArticlesUse; +import com.skyeye.eve.articles.service.ArticlesUseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ArticlesUseController + * @Description: 用品领用申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 9:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用品领用", tags = "用品领用", modelName = "用品模块") +public class ArticlesUseController { + + @Autowired + private ArticlesUseService articlesUseService; + + /** + * 获取我领用的用品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles017", value = "获取我领用的用品信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArticlesUseController/queryMyUseAssetArticlesMation") + public void queryMyUseAssetArticlesMation(InputObject inputObject, OutputObject outputObject) { + articlesUseService.queryPageList(inputObject, outputObject); + } + + /** + * 用品领用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetArticlesApplyUse", value = "用品领用申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ArticlesUse.class) + @RequestMapping("/post/ArticlesUseController/writeArticlesApplyUse") + public void writeArticlesApplyUse(InputObject inputObject, OutputObject outputObject) { + articlesUseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 用品领用申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles023", value = "用品领用申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ArticlesUseController/articlesUseSubmitToApproval") + public void articlesUseSubmitToApproval(InputObject inputObject, OutputObject outputObject) { + articlesUseService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废用品领用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles030", value = "作废用品领用申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArticlesUseController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + articlesUseService.invalid(inputObject, outputObject); + } + + /** + * 撤销用品领用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assetarticles034", value = "撤销用品领用申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ArticlesUseController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + articlesUseService.revoke(inputObject, outputObject); + } + + /** + * 我的用品领用历史 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "myhasmation004", value = "我的用品领用历史", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArticlesUseController/queryMyArticlesList") + public void queryMyArticlesList(InputObject inputObject, OutputObject outputObject) { + articlesUseService.queryMyArticlesList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesDao.java new file mode 100644 index 0000000..ca100d3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.articles.entity.Articles; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArticlesDao + * @Description: 用品管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 9:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesDao extends SkyeyeBaseMapper { + + List> queryArticlesList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseDao.java new file mode 100644 index 0000000..0ed0b8c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.articles.entity.ArticlesPurchase; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArticlesPurchaseDao + * @Description: 用品采购申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesPurchaseDao extends SkyeyeBaseMapper { + + List> queryMyPurchaseArticlesList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseLinkDao.java new file mode 100644 index 0000000..7a1e4fc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesPurchaseLinkDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.dao; + +import com.skyeye.eve.articles.entity.ArticlesPurchaseLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ArticlesPurchaseLinkDao + * @Description: 用品采购申请关联的用品信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesPurchaseLinkDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseDao.java new file mode 100644 index 0000000..93cb0ca --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.articles.entity.ArticlesUse; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArticlesUseDao + * @Description: 用品领用申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 9:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesUseDao extends SkyeyeBaseMapper { + + List> queryMyUseArticlesMation(CommonPageInfo commonPageInfo); + + List> queryMyArticlesList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseLinkDao.java new file mode 100644 index 0000000..ee0f200 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/dao/ArticlesUseLinkDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.dao; + +import com.skyeye.eve.articles.entity.ArticlesUseLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ArticlesUseLinkDao + * @Description: 用品领用申请关联的用品信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesUseLinkDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/Articles.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/Articles.java new file mode 100644 index 0000000..3f44943 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/Articles.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Articles + * @Description: 用品实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 9:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "assistant:articles", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_articles") +@ApiModel("用品实体类") +public class Articles extends BaseGeneralInfo { + + @TableField(value = "articles_num") + @Property("用品编号") + private String articlesNum; + + @TableField(value = "type_id") + @ApiModelProperty(value = "用品类别", required = "required") + private String typeId; + + @TableField(exist = false) + @Property("用品类别名称") + private String typeName; + + @TableField(value = "specifications") + @ApiModelProperty(value = "规格") + private String specifications; + + @TableField(value = "unit_of_measurement") + @ApiModelProperty(value = "计量单位", required = "required") + private String unitOfMeasurement; + + @TableField(value = "initial_num", fill = FieldFill.INSERT) + @ApiModelProperty(value = "初始化数量【不可修改】", required = "num") + private Integer initialNum; + + @TableField(value = "residual_num") + @Property("当前剩余数量,新增时和初始化数量(initialNum)保持一致") + private Integer residualNum; + + @TableField(value = "storage_area") + @ApiModelProperty(value = "存放区域") + private String storageArea; + + @TableField(value = "asset_admin") + @ApiModelProperty(value = "管理人") + private String assetAdmin; + + @TableField(exist = false) + @Property("管理人信息") + private Map assetAdminMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchase.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchase.java new file mode 100644 index 0000000..54dac86 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchase.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ArticlesPurchase + * @Description: 用品采购申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 18:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:articles:purchase", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_articles_purchase") +@ApiModel("用品采购申请实体类") +public class ArticlesPurchase extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总金额") + private String allPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "用品信息", required = "required,json") + private List purchaseLink; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchaseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchaseLink.java new file mode 100644 index 0000000..ed20dc2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesPurchaseLink.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: ArticlesPurchaseLink + * @Description: 用品采购申请关联的用品信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 18:16 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_articles_purchase_goods") +@ApiModel("用品采购申请关联的用品信息实体类") +public class ArticlesPurchaseLink extends SkyeyeLinkData { + + @TableField("article_id") + @ApiModelProperty(value = "用品id", required = "required") + private String articleId; + + @TableField(exist = false) + @Property("用品信息") + private Articles articleMation; + + @TableField("apply_purchase_num") + @ApiModelProperty(value = "申请采购数量", required = "required,num") + private Integer applyPurchaseNum; + + @TableField("unit_price") + @ApiModelProperty(value = "用品单价", required = "required,double") + private String unitPrice; + + @TableField("amount_of_money") + @ApiModelProperty(value = "金额") + private String amountOfMoney; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUse.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUse.java new file mode 100644 index 0000000..3d1d913 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUse.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ArticlesUse + * @Description: 用品领用申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 18:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:articles:applyUse", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_articles_use") +@ApiModel("用品领用申请实体类") +public class ArticlesUse extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "用品信息", required = "required,json") + private List applyUseLnk; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUseLink.java new file mode 100644 index 0000000..a6d279f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/entity/ArticlesUseLink.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: ArticlesUseLink + * @Description: 用品领用申请关联的用品信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 18:16 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_articles_use_goods") +@ApiModel("用品领用申请关联的用品信息实体类") +public class ArticlesUseLink extends SkyeyeLinkData { + + @TableField("article_id") + @ApiModelProperty(value = "用品id", required = "required") + private String articleId; + + @TableField(exist = false) + @Property("用品信息") + private Articles articleMation; + + @TableField("apply_use_num") + @ApiModelProperty(value = "申请领用数量", required = "required,num") + private Integer applyUseNum; + + @TableField("actual_use_num") + @Property("实际发放数量") + private Integer actualUseNum; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseLinkService.java new file mode 100644 index 0000000..717e7aa --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.articles.entity.ArticlesPurchaseLink; + +/** + * @ClassName: ArticlesPurchaseLinkService + * @Description: 用品采购申请关联的用品信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesPurchaseLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseService.java new file mode 100644 index 0000000..d35684b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesPurchaseService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.articles.entity.ArticlesPurchase; + +/** + * @ClassName: ArticlesPurchaseService + * @Description: 用品采购申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesPurchaseService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesService.java new file mode 100644 index 0000000..105843c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.entity.Articles; + +/** + * @ClassName: ArticlesService + * @Description: 用品管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesService extends SkyeyeBusinessService { + + void queryAllArticlesList(InputObject inputObject, OutputObject outputObject); + + /** + * 根据id修改剩余库存信息 + * + * @param id + * @param residualNum + */ + void editResidualNum(String id, Integer residualNum); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseLinkService.java new file mode 100644 index 0000000..59ec099 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseLinkService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.articles.entity.ArticlesUseLink; + +/** + * @ClassName: ArticlesUseLinkService + * @Description: 用品领用申请关联的用品信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesUseLinkService extends SkyeyeLinkDataService { + + void editActualUseNumById(String id, String state, Integer actualUseNum); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseService.java new file mode 100644 index 0000000..23dab2d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/ArticlesUseService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.entity.ArticlesUse; + +/** + * @ClassName: ArticlesUseService + * @Description: 用品领用申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 9:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArticlesUseService extends SkyeyeFlowableService { + + void queryMyArticlesList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseLinkServiceImpl.java new file mode 100644 index 0000000..eec4933 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.articles.dao.ArticlesPurchaseLinkDao; +import com.skyeye.eve.articles.entity.Articles; +import com.skyeye.eve.articles.entity.ArticlesPurchaseLink; +import com.skyeye.eve.articles.service.ArticlesPurchaseLinkService; +import com.skyeye.eve.articles.service.ArticlesService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ArticlesPurchaseLinkServiceImpl + * @Description: 用品采购申请关联的用品信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用品采购单-用品Link", groupName = "用品模块", manageShow = false) +public class ArticlesPurchaseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements ArticlesPurchaseLinkService { + + @Autowired + private ArticlesService articlesService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("用品信息不能为空."); + } + List articleIds = beans.stream().map(ArticlesPurchaseLink::getArticleId).distinct().collect(Collectors.toList()); + Map articlesMap = articlesService.selectMapByIds(articleIds); + beans.forEach(assetArticlesApplyUseChild -> { + Articles article = articlesMap.get(assetArticlesApplyUseChild.getArticleId()); + if (article == null) { + throw new CustomException("数据中包含不存在的用品信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseServiceImpl.java new file mode 100644 index 0000000..507e39d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesPurchaseServiceImpl.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.eve.articles.dao.ArticlesPurchaseDao; +import com.skyeye.eve.articles.entity.ArticlesPurchase; +import com.skyeye.eve.articles.entity.ArticlesPurchaseLink; +import com.skyeye.eve.articles.service.ArticlesPurchaseLinkService; +import com.skyeye.eve.articles.service.ArticlesPurchaseService; +import com.skyeye.eve.articles.service.ArticlesService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ArticlesPurchaseServiceImpl + * @Description: 用品采购申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 11:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用品采购单", groupName = "用品模块", flowable = true) +public class ArticlesPurchaseServiceImpl extends SkyeyeFlowableServiceImpl implements ArticlesPurchaseService { + + @Autowired + private ArticlesPurchaseLinkService articlesPurchaseLinkService; + + @Autowired + private ArticlesService articlesService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryMyPurchaseArticlesList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(ArticlesPurchase entity) { + chectOrderItem(entity.getPurchaseLink()); + getTotalPrice(entity); + } + + @Override + public void writeChild(ArticlesPurchase entity, String userId) { + articlesPurchaseLinkService.saveLinkList(entity.getId(), entity.getPurchaseLink()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List articlesPurchaseLinks) { + if (CollectionUtil.isEmpty(articlesPurchaseLinks)) { + throw new CustomException("请最少选择一条用品信息"); + } + List articleIds = articlesPurchaseLinks.stream() + .map(ArticlesPurchaseLink::getArticleId).distinct() + .collect(Collectors.toList()); + if (articlesPurchaseLinks.size() != articleIds.size()) { + throw new CustomException("单据中不允许出现同一用品信息"); + } + } + + private void getTotalPrice(ArticlesPurchase entity) { + String totalPrice = "0"; + // 计算关联的用品总价 + for (ArticlesPurchaseLink purchaseLink : entity.getPurchaseLink()) { + String amountOfMoney = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(purchaseLink.getApplyPurchaseNum()), purchaseLink.getUnitPrice()); + purchaseLink.setAmountOfMoney(amountOfMoney); + totalPrice = CalculationUtil.add(totalPrice, amountOfMoney); + } + entity.setAllPrice(totalPrice); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + articlesPurchaseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public ArticlesPurchase getDataFromDb(String id) { + ArticlesPurchase articlesPurchase = super.getDataFromDb(id); + List articlesPurchaseLinks = articlesPurchaseLinkService.selectByPId(articlesPurchase.getId()); + articlesPurchase.setPurchaseLink(articlesPurchaseLinks); + return articlesPurchase; + } + + @Override + public ArticlesPurchase selectById(String id) { + ArticlesPurchase articlesPurchase = super.selectById(id); + // 获取用品信息 + articlesService.setDataMation(articlesPurchase.getPurchaseLink(), ArticlesPurchaseLink::getArticleId); + articlesPurchase.getPurchaseLink().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + articlesPurchase.setStateName(FlowableStateEnum.getStateName(articlesPurchase.getState())); + iAuthUserService.setName(articlesPurchase, "createId", "createName"); + return articlesPurchase; + } + + @Override + public void revokePostpose(ArticlesPurchase entity) { + super.revokePostpose(entity); + articlesPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(ArticlesPurchase entity) { + ArticlesPurchase purchase = selectById(entity.getId()); + for (ArticlesPurchaseLink bean : purchase.getPurchaseLink()) { + // 当前用品剩余的数量 + int residualNum = bean.getArticleMation().getResidualNum(); + // 重置库存剩余数量 + residualNum = residualNum + bean.getApplyPurchaseNum(); + // 修改库存 + articlesService.editResidualNum(bean.getArticleId(), residualNum); + } + // 修改用品采购状态 + articlesPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + protected void approvalEndIsFailed(ArticlesPurchase entity) { + articlesPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesServiceImpl.java new file mode 100644 index 0000000..efcecc2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesServiceImpl.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service.impl; + +import cn.hutool.core.map.MapUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.StringUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.articles.dao.ArticlesDao; +import com.skyeye.eve.articles.entity.Articles; +import com.skyeye.eve.articles.service.ArticlesService; +import com.skyeye.eve.coderule.service.ICodeRuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArticlesServiceImpl + * @Description: 用品管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "用品管理", groupName = "用品模块") +public class ArticlesServiceImpl extends SkyeyeBusinessServiceImpl implements ArticlesService { + + @Autowired + private ICodeRuleService iCodeRuleService; + + @Override + public void createPrepose(Articles entity) { + setArticlesNum(entity); + entity.setResidualNum(entity.getInitialNum()); + } + + private void setArticlesNum(Articles articles) { + String prefix = StringUtil.chineseToFirstLetter(articles.getName()); + Map bussness = MapUtil.newHashMap(); + bussness.put("prefix", prefix); + String codeNumber = iCodeRuleService.getNextCodeByClassName(this.getClass().getName(), bussness); + articles.setArticlesNum(codeNumber); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryArticlesList(pageInfo); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public Articles selectById(String id) { + Articles articles = super.selectById(id); + iSysDictDataService.setName(articles, "typeId", "typeName"); + articles.setAssetAdminMation(iAuthUserService.queryDataMationById(articles.getAssetAdmin())); + return articles; + } + + @Override + public List selectByIds(String... ids) { + List articles = super.selectByIds(ids); + iSysDictDataService.setName(articles, "typeId", "typeName"); + // 设置管理人信息 + iAuthUserService.setDataMation(articles, Articles::getAssetAdmin); + return articles; + } + + /** + * 根据用品类别获取用品列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllArticlesList(InputObject inputObject, OutputObject outputObject) { + List articlesList = list(); + outputObject.setBeans(articlesList); + outputObject.settotal(articlesList.size()); + } + + /** + * 根据id修改剩余库存信息 + * + * @param id + * @param residualNum + */ + @Override + public void editResidualNum(String id, Integer residualNum) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Articles::getResidualNum), residualNum); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseLinkServiceImpl.java new file mode 100644 index 0000000..aac9acc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseLinkServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.articles.dao.ArticlesUseLinkDao; +import com.skyeye.eve.articles.entity.Articles; +import com.skyeye.eve.articles.entity.ArticlesUseLink; +import com.skyeye.eve.articles.service.ArticlesService; +import com.skyeye.eve.articles.service.ArticlesUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ArticlesUseLinkServiceImpl + * @Description: 用品领用申请关联的用品信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用品领用单-用品Link", groupName = "用品模块", manageShow = false) +public class ArticlesUseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements ArticlesUseLinkService { + + @Autowired + private ArticlesService articlesService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("用品信息不能为空."); + } + List articleIds = beans.stream().map(ArticlesUseLink::getArticleId).distinct().collect(Collectors.toList()); + Map articlesMap = articlesService.selectMapByIds(articleIds); + beans.forEach(assetArticlesApplyUseChild -> { + Articles article = articlesMap.get(assetArticlesApplyUseChild.getArticleId()); + if (article == null) { + throw new CustomException("数据中包含不存在的用品信息."); + } + if (article.getResidualNum() < assetArticlesApplyUseChild.getApplyUseNum()) { + throw new CustomException("用品【" + article.getName() + "】库存余量不足。"); + } + }); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editActualUseNumById(String id, String state, Integer actualUseNum) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ArticlesUseLink::getState), state); + updateWrapper.set(MybatisPlusUtil.toColumns(ArticlesUseLink::getActualUseNum), actualUseNum); + update(updateWrapper); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseServiceImpl.java new file mode 100644 index 0000000..b0b9f32 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/articles/service/impl/ArticlesUseServiceImpl.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.articles.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.articles.dao.ArticlesUseDao; +import com.skyeye.eve.articles.entity.ArticlesUse; +import com.skyeye.eve.articles.entity.ArticlesUseLink; +import com.skyeye.eve.articles.service.ArticlesService; +import com.skyeye.eve.articles.service.ArticlesUseLinkService; +import com.skyeye.eve.articles.service.ArticlesUseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArticlesUseServiceImpl + * @Description: 用品领用申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 9:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用品领用单", groupName = "用品模块", flowable = true) +public class ArticlesUseServiceImpl extends SkyeyeFlowableServiceImpl implements ArticlesUseService { + + @Autowired + private ArticlesUseLinkService articlesUseLinkService; + + @Autowired + private ArticlesService articlesService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryMyUseArticlesMation(commonPageInfo); + return beans; + } + + @Override + public void writeChild(ArticlesUse entity, String userId) { + articlesUseLinkService.saveLinkList(entity.getId(), entity.getApplyUseLnk()); + super.writeChild(entity, userId); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + articlesUseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public ArticlesUse getDataFromDb(String id) { + ArticlesUse articlesUse = super.getDataFromDb(id); + List articlesUseLink = articlesUseLinkService.selectByPId(articlesUse.getId()); + articlesUse.setApplyUseLnk(articlesUseLink); + return articlesUse; + } + + @Override + public ArticlesUse selectById(String id) { + ArticlesUse articlesUse = super.selectById(id); + // 获取用品信息 + articlesService.setDataMation(articlesUse.getApplyUseLnk(), ArticlesUseLink::getArticleId); + articlesUse.getApplyUseLnk().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + articlesUse.setStateName(FlowableStateEnum.getStateName(articlesUse.getState())); + iAuthUserService.setName(articlesUse, "createId", "createName"); + return articlesUse; + } + + @Override + public void revokePostpose(ArticlesUse entity) { + super.revokePostpose(entity); + articlesUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(ArticlesUse entity) { + ArticlesUse articlesApplyUse = selectById(entity.getId()); + for (ArticlesUseLink bean : articlesApplyUse.getApplyUseLnk()) { + // 当前用品剩余的数量 + int residualNum = bean.getArticleMation().getResidualNum(); + // 允许用户领用的数量 + int actualUseNum; + // 用品对应的领用状态 + String applyState; + if (residualNum >= bean.getApplyUseNum()) { + // 当前库存充足 + applyState = FlowableChildStateEnum.ADEQUATE.getKey(); + actualUseNum = bean.getApplyUseNum(); + } else { + // 当前库存不足 + applyState = FlowableChildStateEnum.INSUFFICIENT.getKey(); + actualUseNum = residualNum; + } + // 重置库存剩余数量 + residualNum = residualNum - actualUseNum; + // 修改库存 + articlesService.editResidualNum(bean.getArticleId(), residualNum); + // 修改用品领用状态 + articlesUseLinkService.editActualUseNumById(bean.getId(), applyState, actualUseNum); + } + } + + @Override + protected void approvalEndIsFailed(ArticlesUse entity) { + articlesUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + @Override + public void queryMyArticlesList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryMyArticlesList(pageInfo); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/AssetReportState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/AssetReportState.java new file mode 100644 index 0000000..706285d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/AssetReportState.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: AssetReportState + * @Description: 资产明细状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AssetReportState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + REPAIR(2, "维修", true, false), + SCRAP(3, "报废", true, false), + RETURN(4, "退货", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (AssetReportState bean : AssetReportState.values()) { + if (state == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseOrderStateEnum.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseOrderStateEnum.java new file mode 100644 index 0000000..2eb23bb --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseOrderStateEnum.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: PurchaseOrderStateEnum + * @Description: 资产采购订单状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseOrderStateEnum implements SkyeyeEnumClass { + + PARTIALLY_COMPLETED("partiallyCompleted", "部分完成", "orange", true, false), + COMPLETED("completed", "已完成", "green", true, false); + + private String key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchasePutFromType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchasePutFromType.java new file mode 100644 index 0000000..673e8d6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchasePutFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchasePutFromType + * @Description: 采购入库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchasePutFromType implements SkyeyeEnumClass { + + PURCHASE_ORDER(1, "采购订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseReturnFromType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseReturnFromType.java new file mode 100644 index 0000000..9bf2799 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/classenum/PurchaseReturnFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseReturnFromType + * @Description: 采购退货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseReturnFromType implements SkyeyeEnumClass { + + PURCHASE_ORDER(1, "采购订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetController.java new file mode 100644 index 0000000..b64a888 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.service.AssetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetController + * @Description: 资产管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产管理", tags = "资产管理", modelName = "资产模块") +public class AssetController { + + @Autowired + private AssetService assetService; + + /** + * 获取所有的资产 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset001", value = "获取所有的资产", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetController/selectAllAssetMation") + public void queryAssetMationList(InputObject inputObject, OutputObject outputObject) { + assetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetMation", value = "新增/编辑资产", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Asset.class) + @RequestMapping("/post/AssetController/writeAssetMation") + public void writeAssetMation(InputObject inputObject, OutputObject outputObject) { + assetService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除资产 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset003", value = "删除资产", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetController/deleteAssetById") + public void deleteAssetById(InputObject inputObject, OutputObject outputObject) { + assetService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询资产 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetById", value = "根据id查询资产", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetController/queryAssetById") + public void queryAssetById(InputObject inputObject, OutputObject outputObject) { + assetService.selectById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseController.java new file mode 100644 index 0000000..d62475f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseController.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetPurchase; +import com.skyeye.eve.assets.entity.AssetPurchasePut; +import com.skyeye.eve.assets.entity.AssetPurchaseReturn; +import com.skyeye.eve.assets.service.AssetPurchaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetPurchaseController + * @Description: 资产采购单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产采购", tags = "资产采购", modelName = "资产模块") +public class AssetPurchaseController { + + @Autowired + private AssetPurchaseService assetPurchaseService; + + /** + * 获取资产采购单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset018", value = "获取资产采购单信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetPurchaseController/queryAssetPurchaseList") + public void queryAssetPurchaseList(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产采购单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetPurchase", value = "新增/编辑资产采购单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetPurchase.class) + @RequestMapping("/post/AssetPurchaseController/writeAssetPurchase") + public void writeAssetPurchase(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 资产采购申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset020", value = "资产采购申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废资产采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset022", value = "作废资产采购申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.invalid(inputObject, outputObject); + } + + /** + * 撤销资产采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset037", value = "撤销资产采购申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.revoke(inputObject, outputObject); + } + + /** + * 转采购入库单/采购退货单时,根据id查询采购订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetPurchaseOrderTransById", value = "转采购入库单/采购退货单时,根据id查询采购订单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/queryAssetPurchaseOrderTransById") + public void queryAssetPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.queryAssetPurchaseOrderTransById(inputObject, outputObject); + } + + /** + * 采购单信息转采购入库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertAssetPurchaseOrderToTurnPut", value = "采购单信息转采购入库", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetPurchasePut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/insertAssetPurchaseOrderToTurnPut") + public void insertAssetPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.insertAssetPurchaseOrderToTurnPut(inputObject, outputObject); + } + + /** + * 采购单信息转采购退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertAssetPurchaseOrderToReturns", value = "采购单信息转采购退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetPurchaseReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchaseController/insertAssetPurchaseOrderToReturns") + public void insertAssetPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject) { + assetPurchaseService.insertAssetPurchaseOrderToReturns(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchasePutController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchasePutController.java new file mode 100644 index 0000000..9e9b54a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchasePutController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetPurchase; +import com.skyeye.eve.assets.service.AssetPurchasePutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetPurchasePutController + * @Description: 资产采购入库控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 19:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产采购入库", tags = "资产采购入库", modelName = "资产模块") +public class AssetPurchasePutController { + + @Autowired + private AssetPurchasePutService assetPurchasePutService; + + /** + * 获取资产入库单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetPurchasePutList", value = "获取资产入库单信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetPurchasePutController/queryAssetPurchasePutList") + public void queryAssetPurchaseList(InputObject inputObject, OutputObject outputObject) { + assetPurchasePutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetPurchasePut", value = "新增/编辑资产入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetPurchase.class) + @RequestMapping("/post/AssetPurchasePutController/writeAssetPurchasePut") + public void writeAssetPurchase(InputObject inputObject, OutputObject outputObject) { + assetPurchasePutService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 资产入库单提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitAssetPurchasePut", value = "资产入库单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AssetPurchasePutController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + assetPurchasePutService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除资产入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAssetPurchasePutById", value = "删除资产入库单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchasePutController/deleteAssetPurchasePutById") + public void deleteAssetPurchasePutById(InputObject inputObject, OutputObject outputObject) { + assetPurchasePutService.deleteById(inputObject, outputObject); + } + + /** + * 撤销资产入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeAssetPurchasePut", value = "撤销资产入库单", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AssetPurchasePutController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + assetPurchasePutService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseReturnController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseReturnController.java new file mode 100644 index 0000000..1e2e5c2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetPurchaseReturnController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetPurchaseReturn; +import com.skyeye.eve.assets.service.AssetPurchaseReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetPurchaseReturnController + * @Description: 资产采购退货控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 20:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产采购退货", tags = "资产采购退货", modelName = "资产模块") +public class AssetPurchaseReturnController { + + @Autowired + private AssetPurchaseReturnService assetPurchaseReturnService; + + /** + * 获取资产退货单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetPurchaseReturnList", value = "获取资产退货单信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetPurchaseReturnController/queryAssetPurchaseReturnList") + public void queryAssetPurchaseList(InputObject inputObject, OutputObject outputObject) { + assetPurchaseReturnService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetPurchaseReturn", value = "新增/编辑资产退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetPurchaseReturn.class) + @RequestMapping("/post/AssetPurchaseReturnController/writeAssetPurchaseReturn") + public void writeAssetPurchase(InputObject inputObject, OutputObject outputObject) { + assetPurchaseReturnService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 资产退货单提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitAssetPurchaseReturn", value = "资产退货单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AssetPurchaseReturnController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + assetPurchaseReturnService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除资产退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAssetPurchaseReturnById", value = "删除资产退货单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetPurchaseReturnController/deleteAssetPurchaseReturnById") + public void deleteAssetPurchaseReturnById(InputObject inputObject, OutputObject outputObject) { + assetPurchaseReturnService.deleteById(inputObject, outputObject); + } + + /** + * 撤销资产退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeAssetPurchaseReturn", value = "撤销资产退货单", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AssetPurchaseReturnController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + assetPurchaseReturnService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReportController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReportController.java new file mode 100644 index 0000000..2886fec --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReportController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetReportQueryDo; +import com.skyeye.eve.assets.service.AssetReportService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetReportController + * @Description: 资产明细控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 14:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产明细管理", tags = "资产明细管理", modelName = "资产模块") +public class AssetReportController { + + @Autowired + private AssetReportService assetReportService; + + /** + * 获取资产明细一物一码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetReportList", value = "获取资产明细一物一码信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AssetReportQueryDo.class) + @RequestMapping("/post/AssetReportController/queryAssetReportList") + public void queryAssetReportList(InputObject inputObject, OutputObject outputObject) { + assetReportService.queryPageList(inputObject, outputObject); + } + + /** + * 生成条形码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertAssetReport", value = "生成条形码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "list", name = "list", value = "商品信息,必须包含assetId,operNumber", required = "required,json")}) + @RequestMapping("/post/AssetReportController/insertAssetReport") + public void insertAssetReport(InputObject inputObject, OutputObject outputObject) { + assetReportService.insertAssetReport(inputObject, outputObject); + } + + /** + * 删除商品条形码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAssetReportById", value = "删除商品条形码", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetReportController/deleteAssetReportById") + public void deleteAssetReportById(InputObject inputObject, OutputObject outputObject) { + assetReportService.deleteById(inputObject, outputObject); + } + + /** + * 根据条件获取条形码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAssetReportCodeList", value = "根据条件获取条形码信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AssetReportQueryDo.class) + @RequestMapping("/post/AssetReportController/queryAssetReportCodeList") + public void queryAssetReportCodeList(InputObject inputObject, OutputObject outputObject) { + assetReportService.queryAssetReportCodeList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReturnController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReturnController.java new file mode 100644 index 0000000..de109a2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetReturnController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetReturn; +import com.skyeye.eve.assets.service.AssetReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetReturnController + * @Description: 资产归还单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/20 22:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产归还", tags = "资产归还", modelName = "资产模块") +public class AssetReturnController { + + @Autowired + private AssetReturnService assetReturnService; + + /** + * 获取我的资产归还申请信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset025", value = "获取我的资产归还申请信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetReturnController/queryAssetReturnList") + public void queryAssetReturnList(InputObject inputObject, OutputObject outputObject) { + assetReturnService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产归还单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetReturn", value = "新增/编辑资产归还单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetReturn.class) + @RequestMapping("/post/AssetReturnController/writeAssetReturn") + public void writeAssetReturn(InputObject inputObject, OutputObject outputObject) { + assetReturnService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 资产归还申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset028", value = "资产归还申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AssetReturnController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + assetReturnService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废资产归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset030", value = "作废资产归还申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetReturnController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + assetReturnService.invalid(inputObject, outputObject); + } + + /** + * 撤销资产归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset038", value = "撤销资产归还申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AssetReturnController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + assetReturnService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetUseController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetUseController.java new file mode 100644 index 0000000..162765b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/controller/AssetUseController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetUse; +import com.skyeye.eve.assets.service.AssetUseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssetUseController + * @Description: 资产领用申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 17:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资产领用", tags = "资产领用", modelName = "资产模块") +public class AssetUseController { + + @Autowired + private AssetUseService assetUseService; + + /** + * 获取我发起的资产领用信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset010", value = "获取我发起的资产领用信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssetUseController/queryAssetUseList") + public void queryAssetUseList(InputObject inputObject, OutputObject outputObject) { + assetUseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑资产领用单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssetUse", value = "新增/编辑资产领用单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssetUse.class) + @RequestMapping("/post/AssetUseController/writeAssetUse") + public void writeAssetUse(InputObject inputObject, OutputObject outputObject) { + assetUseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 作废资产领用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset016", value = "作废资产领用申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AssetUseController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + assetUseService.invalid(inputObject, outputObject); + } + + /** + * 资产领用申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset017", value = "资产领用申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AssetUseController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + assetUseService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销资产领用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "asset036", value = "撤销资产领用申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AssetUseController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + assetUseService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetDao.java new file mode 100644 index 0000000..cfcff09 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetDao + * @Description: 资产管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseDao.java new file mode 100644 index 0000000..4acd4a8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetPurchase; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetPurchaseDao + * @Description: 资产采购单数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkCodeDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkCodeDao.java new file mode 100644 index 0000000..f762f90 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetPurchaseLinkCode; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetPurchaseLinkCodeDao + * @Description: 资产采购子表关联的条形码编号数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 22:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseLinkCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkDao.java new file mode 100644 index 0000000..0bc3c25 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetPurchaseLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetPurchaseLinkDao + * @Description: 资产采购申请关联的资产信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchasePutDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchasePutDao.java new file mode 100644 index 0000000..a798e3c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchasePutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetPurchasePut; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetPurchasePutDao + * @Description: 资产采购入库数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 19:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchasePutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseReturnDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseReturnDao.java new file mode 100644 index 0000000..5beba8c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetPurchaseReturnDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetPurchaseReturn; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetPurchaseReturnDao + * @Description: 资产采购退货数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 20:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseReturnDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReportDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReportDao.java new file mode 100644 index 0000000..734fb59 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReportDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetReport; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetReportDao + * @Description: 资产明细数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 14:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReportDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnDao.java new file mode 100644 index 0000000..dd30c10 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetReturn; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetReturnDao + * @Description: 资产归还单数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/20 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReturnDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnLinkDao.java new file mode 100644 index 0000000..de8d1ef --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetReturnLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetReturnLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetReturnLinkDao + * @Description: 资产归还申请关联的资产信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReturnLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseDao.java new file mode 100644 index 0000000..6e6d3ca --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetUse; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetUseDao + * @Description: 资产领用申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 17:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetUseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseLinkDao.java new file mode 100644 index 0000000..f0a2504 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/dao/AssetUseLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.dao; + +import com.skyeye.eve.assets.entity.AssetUseLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AssetUseLinkDao + * @Description: 资产领用申请关联的资产信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetUseLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/Asset.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/Asset.java new file mode 100644 index 0000000..82b982d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/Asset.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Asset + * @Description: 资产实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "asset_management") +@ApiModel("资产实体类") +public class Asset extends BaseGeneralInfo { + + @TableField(value = "asset_img") + @ApiModelProperty(value = "资产图片", required = "required") + private String assetImg; + + @TableField(value = "type_id") + @ApiModelProperty(value = "资产所属类型", required = "required") + private String typeId; + + @TableField(value = "number_prefix") + @ApiModelProperty(value = "资产编号前缀,不可重复", required = "required") + private String numberPrefix; + + @TableField(value = "specifications") + @ApiModelProperty(value = "资产规格") + private String specifications; + + @TableField(value = "read_price") + @ApiModelProperty(value = "资产参考价", required = "required,double") + private String readPrice; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchase.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchase.java new file mode 100644 index 0000000..2a2bc79 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchase.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AssetPurchase + * @Description: 资产采购申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset:purchase", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_purchase") +@ApiModel("资产采购申请实体类") +public class AssetPurchase extends SkyeyeFlowable { + + @TableField(value = "id_key", updateStrategy = FieldStrategy.NEVER) + @Property("服务类的serviceClassName") + private String idKey; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总金额") + private String allPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "资产信息", required = "required,json") + private List purchaseLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLink.java new file mode 100644 index 0000000..f5c1b75 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLink.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AssetPurchaseLink + * @Description: 资产采购申请关联的资产信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_purchase_goods") +@ApiModel("资产采购申请关联的资产信息实体类") +public class AssetPurchaseLink extends SkyeyeLinkData { + + @TableField("asset_id") + @ApiModelProperty(value = "资产id", required = "required") + private String assetId; + + @TableField(exist = false) + @Property("资产信息") + private Asset assetMation; + + @TableField("purchase_num") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer purchaseNum; + + @TableField("from_id") + @ApiModelProperty(value = "来源id") + private String fromId; + + @TableField(exist = false) + @Property(value = "资产来源信息") + private Map fromMation; + + @TableField("unit_price") + @ApiModelProperty(value = "资产单价", required = "required,double") + private String unitPrice; + + @TableField("amount_of_money") + @ApiModelProperty(value = "金额") + private String amountOfMoney; + + @TableField(exist = false) + @ApiModelProperty(value = "产品条形码编号") + private String normsCode; + + @TableField(exist = false) + @Property(value = "产品条形码编号集合") + private List normsCodeList; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLinkCode.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLinkCode.java new file mode 100644 index 0000000..f9b9c12 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseLinkCode.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AssetPurchaseLinkCode + * @Description: 资产采购子表关联的条形码编号 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_purchase_goods_code") +@ApiModel("资产采购子表关联的条形码编号实体类") +public class AssetPurchaseLinkCode extends CommonInfo { + + @TableId("id") + private String id; + + @TableField("parent_id") + @Property(value = "订单id") + private String parentId; + + @TableField("asset_id") + @Property(value = "资产id") + private String assetId; + + @TableField("norms_code") + @Property(value = "条形码编号") + private String normsCode; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchasePut.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchasePut.java new file mode 100644 index 0000000..5aa4dcf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchasePut.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AssetPurchasePut + * @Description: 资产采购入库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset:purchasePut", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_purchase") +@ApiModel("资产采购申请实体类") +public class AssetPurchasePut extends SkyeyeFlowable { + + @TableField(value = "id_key", updateStrategy = FieldStrategy.NEVER) + @Property("服务类的serviceClassName") + private String idKey; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总金额") + private String allPrice; + + @TableField("need_depot") + @ApiModelProperty(value = "是否需要出入库,参考#WhetherEnum") + private Integer needDepot; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#PurchasePutFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField(exist = false) + @ApiModelProperty(value = "资产信息", required = "required,json") + private List purchaseLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseReturn.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseReturn.java new file mode 100644 index 0000000..0603c30 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetPurchaseReturn.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AssetPurchaseReturn + * @Description: 资产采购退货实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset:purchaseReturn", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_purchase") +@ApiModel("资产采购退货实体类") +public class AssetPurchaseReturn extends SkyeyeFlowable { + + @TableField(value = "id_key", updateStrategy = FieldStrategy.NEVER) + @Property("服务类的serviceClassName") + private String idKey; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总金额") + private String allPrice; + + @TableField("need_depot") + @ApiModelProperty(value = "是否需要出入库,参考#WhetherEnum") + private Integer needDepot; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#PurchaseReturnFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField(exist = false) + @ApiModelProperty(value = "资产信息", required = "required,json") + private List purchaseLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReport.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReport.java new file mode 100644 index 0000000..e12efe8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReport.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: AssetReport + * @Description: 资产明细实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:assetReport", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "asset_management_detail") +@ApiModel("资产明细实体类") +public class AssetReport extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "asset_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "资产id", required = "required") + private String assetId; + + @TableField(value = "asset_num", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "资产编号", required = "required", fuzzyLike = true) + private String assetNum; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "资产单价", required = "required,double") + private String unitPrice; + + @TableField(value = "from_id") + @ApiModelProperty(value = "资产来源id", required = "required") + private String fromId; + + @TableField(exist = false) + @Property(value = "资产来源信息") + private Map fromMation; + + @TableField(value = "purchase_id") + @ApiModelProperty(value = "采购单id") + private String purchaseId; + + @TableField(value = "purchase_time") + @ApiModelProperty(value = "采购日期") + private String purchaseTime; + + @TableField(value = "warehousing_id") + @ApiModelProperty(value = "入库单id") + private String warehousingId; + + @TableField(value = "warehousing_time") + @ApiModelProperty(value = "入库日期") + private String warehousingTime; + + @TableField(value = "return_id") + @ApiModelProperty(value = "退货单id") + private String returnId; + + @TableField(value = "return_time") + @ApiModelProperty(value = "退货日期") + private String returnTime; + + @TableField(value = "storage_area") + @ApiModelProperty(value = "存放区域") + private String storageArea; + + @TableField(value = "use_id") + @ApiModelProperty(value = "领用单id") + private String useId; + + @TableField(value = "use_user_id") + @ApiModelProperty(value = "领用人") + private String useUserId; + + @TableField(exist = false) + @Property(value = "领用人信息") + private Map useUserMation; + + @TableField(value = "revert_id") + @ApiModelProperty(value = "归还单id") + private String revertId; + + @TableField(value = "revert_user_id") + @ApiModelProperty(value = "归还人") + private String revertUserId; + + @TableField(exist = false) + @Property(value = "归还人信息") + private Map revertUserMation; + + @TableField(value = "asset_admin") + @ApiModelProperty(value = "管理人") + private String assetAdmin; + + @TableField(exist = false) + @Property(value = "管理人信息") + private Map assetAdminMation; + + @TableField(value = "`describe`") + @ApiModelProperty(value = "附加描述") + private String describe; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(value = "state") + @Property(value = "状态,参考#AssetReportState") + private Integer state; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReportQueryDo.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReportQueryDo.java new file mode 100644 index 0000000..ed237a3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReportQueryDo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: AssetReportQueryDo + * @Description: 资产明细查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 21:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("资产明细查询条件实体类") +public class AssetReportQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "资产id") + private String assetId; + + @ApiModelProperty(value = "获取的数量") + private Integer number; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturn.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturn.java new file mode 100644 index 0000000..8c47cb8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturn.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AssetReturn + * @Description: 资产归还申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset:return", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_return") +@ApiModel("资产归还申请实体类") +public class AssetReturn extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "资产信息", required = "required,json") + private List returnLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturnLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturnLink.java new file mode 100644 index 0000000..706ce7e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetReturnLink.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: AssetReturnLink + * @Description: 资产归还申请关联的资产信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_return_goods") +@ApiModel("资产归还申请关联的资产信息实体类") +public class AssetReturnLink extends SkyeyeLinkData { + + @TableField("asset_id") + @Property(value = "资产id") + private String assetId; + + @TableField(exist = false) + @Property("资产信息") + private Asset assetMation; + + @TableField("asset_report_id") + @ApiModelProperty(value = "资产明细id", required = "required") + private String assetReportId; + + @TableField(exist = false) + @Property("资产明细信息") + private AssetReport assetReportMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUse.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUse.java new file mode 100644 index 0000000..8366eb2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUse.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AssetUse + * @Description: 资产领用申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:asset:use", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "asset_use") +@ApiModel("资产领用申请实体类") +public class AssetUse extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "资产信息", required = "required,json") + private List useLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUseLink.java new file mode 100644 index 0000000..63b495e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/entity/AssetUseLink.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: AssetUseLink + * @Description: 资产领用申请关联的资产信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "asset_use_goods") +@ApiModel("资产领用申请关联的资产信息实体类") +public class AssetUseLink extends SkyeyeLinkData { + + @TableField("asset_id") + @Property(value = "资产id") + private String assetId; + + @TableField(exist = false) + @Property("资产信息") + private Asset assetMation; + + @TableField("asset_report_id") + @ApiModelProperty(value = "资产明细id", required = "required") + private String assetReportId; + + @TableField(exist = false) + @Property("资产明细信息") + private AssetReport assetReportMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkCodeService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkCodeService.java new file mode 100644 index 0000000..f88340b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkCodeService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.assets.entity.AssetPurchaseLinkCode; + +import java.util.List; + +/** + * @ClassName: AssetPurchaseLinkCodeService + * @Description: 资产采购子表关联的条形码编号服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/20 10:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseLinkCodeService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkService.java new file mode 100644 index 0000000..691d53f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseLinkService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.assets.entity.AssetPurchaseLink; + +import java.util.List; + +/** + * @ClassName: AssetPurchaseLinkService + * @Description: 资产采购申请关联的资产信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseLinkService extends SkyeyeLinkDataService { + + List queryAssetPurchaseLinkByPIds(List pIds); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchasePutService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchasePutService.java new file mode 100644 index 0000000..49546f7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchasePutService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.assets.entity.AssetPurchasePut; + +import java.util.Map; + +/** + * @ClassName: AssetPurchasePutService + * @Description: 资产采购入库服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 19:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchasePutService extends SkyeyeFlowableService { + + Map calcAssetNumByFromId(String fromId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseReturnService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseReturnService.java new file mode 100644 index 0000000..24838a8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseReturnService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.assets.entity.AssetPurchaseReturn; + +import java.util.Map; + +/** + * @ClassName: AssetPurchaseReturnService + * @Description: 资产采购退货服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 20:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseReturnService extends SkyeyeFlowableService { + + Map calcAssetNumByFromId(String fromId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseService.java new file mode 100644 index 0000000..80410e6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetPurchaseService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetPurchase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AssetPurchaseService + * @Description: 资产采购单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetPurchaseService extends SkyeyeFlowableService { + + void queryAssetPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject); + + void insertAssetPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject); + + void insertAssetPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject); + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReportService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReportService.java new file mode 100644 index 0000000..2bef613 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReportService.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.assets.entity.AssetReport; + +import java.util.List; + +/** + * @ClassName: AssetReportService + * @Description: 资产明细服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 14:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReportService extends SkyeyeBusinessService { + + /** + * 设置资产领用信息 + * + * @param id 资产明细id + * @param useId 领用单id + * @param useUserId 领用人id + */ + void setAssetReportEmployee(String id, String useId, String useUserId); + + /** + * 设置资产归还信息 + * + * @param id 资产明细id + * @param revertId 归还单id + * @param revertUserId 归还人id + */ + void setAssetReportRevert(String id, String revertId, String revertUserId); + + /** + * 根据资产id获取资产明细总数 + * + * @param assetId 资产id + * @return 资产明细总数 + */ + Long getAssetReportNumByAssetId(String assetId); + + /** + * 根据编码获取未入库的编码信息 + * + * @param codeNumList 编码 + * @param depotState 是否入库 true:已入库 false:未入库 + * @return + */ + List queryAssetReportListByCodeNum(List codeNumList, Boolean depotState); + + + void insertAssetReport(InputObject inputObject, OutputObject outputObject); + + void queryAssetReportCodeList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnLinkService.java new file mode 100644 index 0000000..e97562c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.assets.entity.AssetReturnLink; + +/** + * @ClassName: AssetReturnLinkService + * @Description: 资产归还申请关联的资产信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReturnLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnService.java new file mode 100644 index 0000000..c519666 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetReturnService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.assets.entity.AssetReturn; + +/** + * @ClassName: AssetReturnService + * @Description: 资产归还单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/20 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetReturnService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetService.java new file mode 100644 index 0000000..b950920 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.assets.entity.Asset; + +/** + * @ClassName: AssetService + * @Description: 资产管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 16:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseLinkService.java new file mode 100644 index 0000000..3bf12a3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.assets.entity.AssetUseLink; + +/** + * @ClassName: AssetUseLinkService + * @Description: 资产领用申请关联的资产信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetUseLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseService.java new file mode 100644 index 0000000..e48c468 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/AssetUseService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.assets.entity.AssetUse; + +/** + * @ClassName: AssetUseService + * @Description: 资产领用服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 17:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssetUseService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkCodeServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkCodeServiceImpl.java new file mode 100644 index 0000000..22da13b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkCodeServiceImpl.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.dao.AssetPurchaseLinkCodeDao; +import com.skyeye.eve.assets.entity.AssetPurchaseLinkCode; +import com.skyeye.eve.assets.service.AssetPurchaseLinkCodeService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: AssetPurchaseLinkCodeServiceImpl + * @Description: 资产采购子表关联的条形码编号服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/20 10:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class AssetPurchaseLinkCodeServiceImpl extends SkyeyeBusinessServiceImpl implements AssetPurchaseLinkCodeService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (AssetPurchaseLinkCode assetPurchaseLinkCode : beans) { + assetPurchaseLinkCode.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseLinkCode::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseLinkCode::getParentId), parentId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkServiceImpl.java new file mode 100644 index 0000000..4d2fb0e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseLinkServiceImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.dao.AssetPurchaseLinkDao; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.entity.AssetPurchaseLink; +import com.skyeye.eve.assets.entity.AssetPurchaseLinkCode; +import com.skyeye.eve.assets.service.AssetPurchaseLinkCodeService; +import com.skyeye.eve.assets.service.AssetPurchaseLinkService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetPurchaseLinkServiceImpl + * @Description: 资产采购关联的资产信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产采购-资产Link", groupName = "资产模块", manageShow = false) +public class AssetPurchaseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements AssetPurchaseLinkService { + + @Autowired + private AssetService assetService; + + @Autowired + private AssetPurchaseLinkCodeService assetPurchaseLinkCodeService; + + @Override + public void saveLinkList(String pId, List beans) { + super.saveLinkList(pId, beans); + // 保存关联的条形码 + List assetPurchaseLinkCodeList = new ArrayList<>(); + beans.forEach(bean -> { + if (CollectionUtil.isNotEmpty(bean.getNormsCodeList())) { + bean.getNormsCodeList().forEach(normsCode -> { + AssetPurchaseLinkCode assetPurchaseLinkCode = new AssetPurchaseLinkCode(); + assetPurchaseLinkCode.setNormsCode(normsCode); + assetPurchaseLinkCode.setAssetId(bean.getAssetId()); + assetPurchaseLinkCodeList.add(assetPurchaseLinkCode); + }); + } + }); + if (CollectionUtil.isNotEmpty(assetPurchaseLinkCodeList)) { + assetPurchaseLinkCodeService.saveList(pId, assetPurchaseLinkCodeList); + } + } + + @Override + public void deleteByPId(String pId) { + super.deleteByPId(pId); + assetPurchaseLinkCodeService.deleteByParentId(pId); + } + + @Override + public List selectByPId(String pId) { + List assetPurchaseLinkList = super.selectByPId(pId); + // 查询资产条形码 + List assetPurchaseLinkCodeList = assetPurchaseLinkCodeService.selectByParentId(pId); + if (CollectionUtil.isNotEmpty(assetPurchaseLinkCodeList)) { + Map> collect = assetPurchaseLinkCodeList.stream() + .collect(Collectors.groupingBy(AssetPurchaseLinkCode::getAssetId)); + // 进行条形码赋值 + assetPurchaseLinkList.forEach(assetPurchaseLink -> { + List assetPurchaseLinkCodes = collect.get(assetPurchaseLink.getAssetId()); + if (CollectionUtil.isNotEmpty(assetPurchaseLinkCodes)) { + List list = assetPurchaseLinkCodes.stream().map(AssetPurchaseLinkCode::getNormsCode).collect(Collectors.toList()); + assetPurchaseLink.setNormsCodeList(list); + assetPurchaseLink.setNormsCode(Joiner.on("\n").join(list)); + } + }); + } + + return assetPurchaseLinkList; + } + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("资产信息不能为空."); + } + List articleIds = beans.stream().map(AssetPurchaseLink::getAssetId).distinct().collect(Collectors.toList()); + Map articlesMap = assetService.selectMapByIds(articleIds); + beans.forEach(assetPurchaseLink -> { + Asset asset = articlesMap.get(assetPurchaseLink.getAssetId()); + if (asset == null) { + throw new CustomException("数据中包含不存在的资产信息."); + } + }); + } + + @Override + public List queryAssetPurchaseLinkByPIds(List pIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(AssetPurchaseLink::getParentId), pIds); + return list(queryWrapper); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchasePutServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchasePutServiceImpl.java new file mode 100644 index 0000000..31e789f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchasePutServiceImpl.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.classenum.AssetReportState; +import com.skyeye.eve.assets.classenum.PurchaseOrderStateEnum; +import com.skyeye.eve.assets.dao.AssetPurchasePutDao; +import com.skyeye.eve.assets.entity.*; +import com.skyeye.eve.assets.service.*; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetPurchasePutServiceImpl + * @Description: 资产采购入库服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 19:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产入库", groupName = "资产模块", flowable = true) +public class AssetPurchasePutServiceImpl extends SkyeyeFlowableServiceImpl implements AssetPurchasePutService { + + @Autowired + private AssetPurchaseLinkService assetPurchaseLinkService; + + @Autowired + private AssetService assetService; + + @Autowired + private AssetPurchaseService assetPurchaseService; + + @Autowired + private AssetPurchaseReturnService assetPurchaseReturnService; + + @Autowired + private AssetReportService assetReportService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchasePut::getIdKey), getServiceClassName()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + assetPurchaseService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(AssetPurchasePut entity) { + checkOrderItem(entity.getPurchaseLinks()); + checkMaterialNorms(entity, false); + getTotalPrice(entity); + } + + @Override + public void createPrepose(AssetPurchasePut entity) { + entity.setIdKey(getServiceClassName()); + super.createPrepose(entity); + } + + @Override + public void writeChild(AssetPurchasePut entity, String userId) { + assetPurchaseLinkService.saveLinkList(entity.getId(), entity.getPurchaseLinks()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(List assetPurchaseLinks) { + List assetIds = assetPurchaseLinks.stream() + .map(AssetPurchaseLink::getAssetId).distinct() + .collect(Collectors.toList()); + if (assetPurchaseLinks.size() != assetIds.size()) { + throw new CustomException("单据中不允许出现同一资产信息"); + } + } + + private void getTotalPrice(AssetPurchasePut entity) { + String totalPrice = "0"; + List assetIdList = entity.getPurchaseLinks().stream().map(AssetPurchaseLink::getAssetId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(assetIdList)) { + return; + } + Map assetMap = assetService.selectMapByIds(assetIdList); + // 计算关联的资产总价 + for (AssetPurchaseLink purchaseLink : entity.getPurchaseLinks()) { + Asset asset = assetMap.get(purchaseLink.getAssetId()); + // 计算总价 + String amountOfMoney = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(purchaseLink.getPurchaseNum()), purchaseLink.getUnitPrice()); + purchaseLink.setAmountOfMoney(amountOfMoney); + totalPrice = CalculationUtil.add(totalPrice, amountOfMoney); + // 计算条形码 + List normsCodeList = Arrays.asList(purchaseLink.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (purchaseLink.getPurchaseNum() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "产品【%s】的条形码数量与明细数量不一致,请确认", asset.getName())); + } + purchaseLink.setNormsCodeList(normsCodeList); + } + entity.setAllPrice(totalPrice); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + assetPurchaseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public AssetPurchasePut getDataFromDb(String id) { + AssetPurchasePut assetPurchase = super.getDataFromDb(id); + List assetPurchaseLinks = assetPurchaseLinkService.selectByPId(assetPurchase.getId()); + assetPurchase.setPurchaseLinks(assetPurchaseLinks); + return assetPurchase; + } + + @Override + public AssetPurchasePut selectById(String id) { + AssetPurchasePut assetPurchasePut = super.selectById(id); + // 获取资产信息 + assetService.setDataMation(assetPurchasePut.getPurchaseLinks(), AssetPurchaseLink::getAssetId); + assetPurchasePut.getPurchaseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + // 资产来源信息 + iSysDictDataService.setDataMation(assetPurchasePut.getPurchaseLinks(), AssetPurchaseLink::getFromId); + assetPurchasePut.setStateName(FlowableStateEnum.getStateName(assetPurchasePut.getState())); + iAuthUserService.setName(assetPurchasePut, "createId", "createName"); + assetPurchaseService.setDataMation(assetPurchasePut, AssetPurchasePut::getFromId); + return assetPurchasePut; + } + + @Override + public void revokePostpose(AssetPurchasePut entity) { + super.revokePostpose(entity); + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(AssetPurchasePut entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 修改条形码编码信息 + editAssetBarCodeDepotMaiton(entity); + // 修改子单据状态 + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + public void approvalEndIsFailed(AssetPurchasePut entity) { + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + private void editAssetBarCodeDepotMaiton(AssetPurchasePut entity) { + // 获取所有的条形码信息 + List normsCodeList = entity.getPurchaseLinks().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(bean -> bean.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(normsCodeList)) { + throw new CustomException("单据信息中条形码为空."); + } + // 获取所有未入库的编码 + List assetReportList = assetReportService.queryAssetReportListByCodeNum(normsCodeList, false); + List inSqlNormsCodeList = assetReportList.stream().map(AssetReport::getAssetNum).collect(Collectors.toList()); + // 求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = normsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或已被使用,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 批量修改条形码信息 + Map purchaseLinkMap = entity.getPurchaseLinks().stream() + .collect(Collectors.toMap(AssetPurchaseLink::getAssetId, bean -> bean)); + String warehousingTime = DateUtil.getTimeAndToString(); + assetReportList.forEach(assetReport -> { + AssetPurchaseLink assetPurchaseLink = purchaseLinkMap.get(assetReport.getAssetId()); + assetReport.setUnitPrice(assetPurchaseLink.getUnitPrice()); + assetReport.setFromId(assetPurchaseLink.getFromId()); + if (StrUtil.isNotEmpty(entity.getFromId())) { + assetReport.setPurchaseId(entity.getFromId()); + assetReport.setPurchaseTime(entity.getFromMation().get("createTime").toString()); + } + if (!StrUtil.equals(assetReport.getAssetId(), assetPurchaseLink.getAssetId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与资产不匹配,请确认", assetReport.getAssetNum())); + } + assetReport.setWarehousingId(entity.getId()); + assetReport.setWarehousingTime(warehousingTime); + assetReport.setState(AssetReportState.NORMAL.getKey()); + }); + assetReportService.updateEntity(assetReportList, entity.getCreateId()); + } + + @Override + public Map calcAssetNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchasePut::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchasePut::getIdKey), getServiceClassName()); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchasePut::getState), FlowableStateEnum.PASS.getKey()); + List purchasePutList = list(queryWrapper); + List ids = purchasePutList.stream().map(AssetPurchasePut::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List assetPurchaseLinkList = assetPurchaseLinkService.queryAssetPurchaseLinkByPIds(ids); + Map collect = assetPurchaseLinkList.stream() + .collect(Collectors.groupingBy(AssetPurchaseLink::getAssetId, Collectors.summingInt(AssetPurchaseLink::getPurchaseNum))); + return collect; + } + + private void checkMaterialNorms(AssetPurchasePut entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前采购入库单的商品数量 + Map orderNormsNum = entity.getPurchaseLinks().stream() + .collect(Collectors.toMap(AssetPurchaseLink::getAssetId, AssetPurchaseLink::getPurchaseNum)); + // 获取已经下达采购入库单的商品信息 + Map executeNum = calcAssetNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + AssetPurchase assetPurchase = assetPurchaseService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(assetPurchase.getPurchaseLinks())) { + throw new CustomException("该采购订单下未包含商品."); + } + List fromAssetIds = assetPurchase.getPurchaseLinks().stream() + .map(AssetPurchaseLink::getAssetId).collect(Collectors.toList()); + // 求差集(采购订单中不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromAssetIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List assetList = assetService.selectByIds(diffList.toArray(new String[]{})); + List assetNames = assetList.stream().map(Asset::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该来源采购订单下未包含如下产品:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(assetNames))); + } + // 获取已经下达采购退货单的商品信息 + Map returnExecuteNum = assetPurchaseReturnService.calcAssetNumByFromId(entity.getFromId()); + assetPurchase.getPurchaseLinks().forEach(purchaseLink -> { + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 - 已经退货的商品数量 + Integer surplusNum = purchaseLink.getPurchaseNum() + - (orderNormsNum.containsKey(purchaseLink.getAssetId()) ? orderNormsNum.get(purchaseLink.getAssetId()) : 0) + - (executeNum.containsKey(purchaseLink.getAssetId()) ? executeNum.get(purchaseLink.getAssetId()) : 0) + - (returnExecuteNum.containsKey(purchaseLink.getAssetId()) ? returnExecuteNum.get(purchaseLink.getAssetId()) : 0); + if (surplusNum < 0) { + throw new CustomException("超出采购订单的商品数量."); + } + if (setData) { + purchaseLink.setPurchaseNum(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = assetPurchase.getPurchaseLinks().stream() + .filter(purchaseLink -> purchaseLink.getPurchaseNum() > 0).collect(Collectors.toList()); + // 如果该采购订单的商品已经全部生成了采购入库单/采购退货单,那说明已经完成了采购订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + assetPurchaseService.editStateById(assetPurchase.getId(), PurchaseOrderStateEnum.COMPLETED.getKey()); + } else { + assetPurchaseService.editStateById(assetPurchase.getId(), PurchaseOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseReturnServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseReturnServiceImpl.java new file mode 100644 index 0000000..e6e80eb --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseReturnServiceImpl.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.classenum.AssetReportState; +import com.skyeye.eve.assets.classenum.PurchaseOrderStateEnum; +import com.skyeye.eve.assets.dao.AssetPurchaseReturnDao; +import com.skyeye.eve.assets.entity.*; +import com.skyeye.eve.assets.service.*; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetPurchaseReturnServiceImpl + * @Description: 资产采购退货服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/19 20:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购退货", groupName = "资产模块", flowable = true) +public class AssetPurchaseReturnServiceImpl extends SkyeyeFlowableServiceImpl implements AssetPurchaseReturnService { + + @Autowired + private AssetPurchaseLinkService assetPurchaseLinkService; + + @Autowired + private AssetService assetService; + + @Autowired + private AssetPurchaseService assetPurchaseService; + + @Autowired + private AssetPurchasePutService assetPurchasePutService; + + @Autowired + private AssetReportService assetReportService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseReturn::getIdKey), getServiceClassName()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + assetPurchaseService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(AssetPurchaseReturn entity) { + checkOrderItem(entity.getPurchaseLinks()); + checkMaterialNorms(entity, false); + getTotalPrice(entity); + } + + @Override + public void createPrepose(AssetPurchaseReturn entity) { + entity.setIdKey(getServiceClassName()); + super.createPrepose(entity); + } + + @Override + public void writeChild(AssetPurchaseReturn entity, String userId) { + assetPurchaseLinkService.saveLinkList(entity.getId(), entity.getPurchaseLinks()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(List assetPurchaseLinks) { + List assetIds = assetPurchaseLinks.stream() + .map(AssetPurchaseLink::getAssetId).distinct() + .collect(Collectors.toList()); + if (assetPurchaseLinks.size() != assetIds.size()) { + throw new CustomException("单据中不允许出现同一资产信息"); + } + } + + private void getTotalPrice(AssetPurchaseReturn entity) { + String totalPrice = "0"; + List assetIdList = entity.getPurchaseLinks().stream().map(AssetPurchaseLink::getAssetId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(assetIdList)) { + return; + } + Map assetMap = assetService.selectMapByIds(assetIdList); + // 计算关联的资产总价 + for (AssetPurchaseLink purchaseLink : entity.getPurchaseLinks()) { + Asset asset = assetMap.get(purchaseLink.getAssetId()); + // 计算总价 + String amountOfMoney = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(purchaseLink.getPurchaseNum()), purchaseLink.getUnitPrice()); + purchaseLink.setAmountOfMoney(amountOfMoney); + totalPrice = CalculationUtil.add(totalPrice, amountOfMoney); + if (entity.getNeedDepot() == WhetherEnum.ENABLE_USING.getKey()) { + // 计算条形码 + List normsCodeList = Arrays.asList(purchaseLink.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (purchaseLink.getPurchaseNum() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "产品【%s】的条形码数量与明细数量不一致,请确认", asset.getName())); + } + purchaseLink.setNormsCodeList(normsCodeList); + } + } + entity.setAllPrice(totalPrice); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + assetPurchaseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public AssetPurchaseReturn getDataFromDb(String id) { + AssetPurchaseReturn assetPurchaseReturn = super.getDataFromDb(id); + List assetPurchaseLinks = assetPurchaseLinkService.selectByPId(assetPurchaseReturn.getId()); + assetPurchaseReturn.setPurchaseLinks(assetPurchaseLinks); + return assetPurchaseReturn; + } + + @Override + public AssetPurchaseReturn selectById(String id) { + AssetPurchaseReturn assetPurchaseReturn = super.selectById(id); + // 获取资产信息 + assetService.setDataMation(assetPurchaseReturn.getPurchaseLinks(), AssetPurchaseLink::getAssetId); + assetPurchaseReturn.getPurchaseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + // 资产来源信息 + iSysDictDataService.setDataMation(assetPurchaseReturn.getPurchaseLinks(), AssetPurchaseLink::getFromId); + assetPurchaseReturn.setStateName(FlowableStateEnum.getStateName(assetPurchaseReturn.getState())); + iAuthUserService.setName(assetPurchaseReturn, "createId", "createName"); + assetPurchaseService.setDataMation(assetPurchaseReturn, AssetPurchaseReturn::getFromId); + return assetPurchaseReturn; + } + + @Override + public void revokePostpose(AssetPurchaseReturn entity) { + super.revokePostpose(entity); + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(AssetPurchaseReturn entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + if (entity.getNeedDepot() == WhetherEnum.ENABLE_USING.getKey()) { + // 修改条形码编码信息 + editAssetBarCodeDepotMaiton(entity); + } + // 修改子单据状态 + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + public void approvalEndIsFailed(AssetPurchaseReturn entity) { + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + private void editAssetBarCodeDepotMaiton(AssetPurchaseReturn entity) { + // 获取所有的条形码信息 + List normsCodeList = entity.getPurchaseLinks().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(bean -> bean.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(normsCodeList)) { + throw new CustomException("单据信息中条形码为空."); + } + // 获取所有已入库的编码 + List assetReportList = assetReportService.queryAssetReportListByCodeNum(normsCodeList, true); + List inSqlNormsCodeList = assetReportList.stream().map(AssetReport::getAssetNum).collect(Collectors.toList()); + // 求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = normsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】未入库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 批量修改条形码信息 + Map returnLinkMap = entity.getPurchaseLinks().stream() + .collect(Collectors.toMap(AssetPurchaseLink::getAssetId, bean -> bean)); + String returnTime = DateUtil.getTimeAndToString(); + assetReportList.forEach(assetReport -> { + AssetPurchaseLink assetReturnLink = returnLinkMap.get(assetReport.getAssetId()); + if (!StrUtil.equals(assetReport.getAssetId(), assetReturnLink.getAssetId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与资产不匹配,请确认", assetReport.getAssetNum())); + } + assetReport.setReturnId(entity.getId()); + assetReport.setReturnTime(returnTime); + assetReport.setState(AssetReportState.RETURN.getKey()); + }); + assetReportService.updateEntity(assetReportList, entity.getCreateId()); + + } + + @Override + public Map calcAssetNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseReturn::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseReturn::getIdKey), getServiceClassName()); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchaseReturn::getState), FlowableStateEnum.PASS.getKey()); + List purchaseReturnList = list(queryWrapper); + List ids = purchaseReturnList.stream().map(AssetPurchaseReturn::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List assetPurchaseLinkList = assetPurchaseLinkService.queryAssetPurchaseLinkByPIds(ids); + Map collect = assetPurchaseLinkList.stream() + .collect(Collectors.groupingBy(AssetPurchaseLink::getAssetId, Collectors.summingInt(AssetPurchaseLink::getPurchaseNum))); + return collect; + } + + private void checkMaterialNorms(AssetPurchaseReturn entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前采购入库单的商品数量 + Map orderNormsNum = entity.getPurchaseLinks().stream() + .collect(Collectors.toMap(AssetPurchaseLink::getAssetId, AssetPurchaseLink::getPurchaseNum)); + // 获取已经下达采购入库单的商品信息 + Map executeNum = calcAssetNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + AssetPurchase assetPurchase = assetPurchaseService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(assetPurchase.getPurchaseLinks())) { + throw new CustomException("该采购订单下未包含商品."); + } + List fromAssetIds = assetPurchase.getPurchaseLinks().stream() + .map(AssetPurchaseLink::getAssetId).collect(Collectors.toList()); + // 求差集(采购订单中不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromAssetIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List assetList = assetService.selectByIds(diffList.toArray(new String[]{})); + List assetNames = assetList.stream().map(Asset::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该来源采购订单下未包含如下产品:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(assetNames))); + } + // 获取已经下达采购入库单的商品信息 + Map putExecuteNum = assetPurchasePutService.calcAssetNumByFromId(entity.getFromId()); + assetPurchase.getPurchaseLinks().forEach(purchaseLink -> { + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 - 已经退货的商品数量 + Integer surplusNum = purchaseLink.getPurchaseNum() + - (orderNormsNum.containsKey(purchaseLink.getAssetId()) ? orderNormsNum.get(purchaseLink.getAssetId()) : 0) + - (executeNum.containsKey(purchaseLink.getAssetId()) ? executeNum.get(purchaseLink.getAssetId()) : 0) + - (putExecuteNum.containsKey(purchaseLink.getAssetId()) ? putExecuteNum.get(purchaseLink.getAssetId()) : 0); + if (surplusNum < 0) { + throw new CustomException("超出采购订单的商品数量."); + } + if (setData) { + purchaseLink.setPurchaseNum(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = assetPurchase.getPurchaseLinks().stream() + .filter(purchaseLink -> purchaseLink.getPurchaseNum() > 0).collect(Collectors.toList()); + // 如果该采购订单的商品已经全部生成了采购入库单/采购退货单,那说明已经完成了采购订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + assetPurchaseService.editStateById(assetPurchase.getId(), PurchaseOrderStateEnum.COMPLETED.getKey()); + } else { + assetPurchaseService.editStateById(assetPurchase.getId(), PurchaseOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseServiceImpl.java new file mode 100644 index 0000000..a5227e8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetPurchaseServiceImpl.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.classenum.PurchaseOrderStateEnum; +import com.skyeye.eve.assets.classenum.PurchasePutFromType; +import com.skyeye.eve.assets.classenum.PurchaseReturnFromType; +import com.skyeye.eve.assets.dao.AssetPurchaseDao; +import com.skyeye.eve.assets.entity.AssetPurchase; +import com.skyeye.eve.assets.entity.AssetPurchaseLink; +import com.skyeye.eve.assets.entity.AssetPurchasePut; +import com.skyeye.eve.assets.entity.AssetPurchaseReturn; +import com.skyeye.eve.assets.service.*; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetPurchaseServiceImpl + * @Description: 资产采购单服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产采购", groupName = "资产模块", flowable = true) +public class AssetPurchaseServiceImpl extends SkyeyeFlowableServiceImpl implements AssetPurchaseService { + + @Autowired + private AssetPurchaseLinkService assetPurchaseLinkService; + + @Autowired + private AssetService assetService; + + @Autowired + private AssetPurchasePutService assetPurchasePutService; + + @Autowired + private AssetPurchaseReturnService assetPurchaseReturnService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetPurchase::getIdKey), getServiceClassName()); + return queryWrapper; + } + + @Override + public void validatorEntity(AssetPurchase entity) { + checkOrderItem(entity.getPurchaseLinks()); + getTotalPrice(entity); + } + + @Override + public void createPrepose(AssetPurchase entity) { + entity.setIdKey(getServiceClassName()); + super.createPrepose(entity); + } + + @Override + public void writeChild(AssetPurchase entity, String userId) { + assetPurchaseLinkService.saveLinkList(entity.getId(), entity.getPurchaseLinks()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(List assetPurchaseLinks) { + List assetIds = assetPurchaseLinks.stream() + .map(bean -> String.format(Locale.ROOT, "%s-%s", bean.getFromId(), bean.getAssetId())).distinct() + .collect(Collectors.toList()); + if (assetPurchaseLinks.size() != assetIds.size()) { + throw new CustomException("单据中不允许相同来源的同一资产信息"); + } + } + + private void getTotalPrice(AssetPurchase entity) { + String totalPrice = "0"; + // 计算关联的资产总价 + for (AssetPurchaseLink purchaseLink : entity.getPurchaseLinks()) { + String amountOfMoney = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(purchaseLink.getPurchaseNum()), purchaseLink.getUnitPrice()); + purchaseLink.setAmountOfMoney(amountOfMoney); + totalPrice = CalculationUtil.add(totalPrice, amountOfMoney); + } + entity.setAllPrice(totalPrice); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + assetPurchaseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public AssetPurchase getDataFromDb(String id) { + AssetPurchase assetPurchase = super.getDataFromDb(id); + List assetPurchaseLinks = assetPurchaseLinkService.selectByPId(assetPurchase.getId()); + assetPurchase.setPurchaseLinks(assetPurchaseLinks); + return assetPurchase; + } + + @Override + public AssetPurchase selectById(String id) { + AssetPurchase assetPurchase = super.selectById(id); + // 获取资产信息 + assetService.setDataMation(assetPurchase.getPurchaseLinks(), AssetPurchaseLink::getAssetId); + assetPurchase.getPurchaseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + // 资产来源信息 + iSysDictDataService.setDataMation(assetPurchase.getPurchaseLinks(), AssetPurchaseLink::getFromId); + assetPurchase.setStateName(FlowableStateEnum.getStateName(assetPurchase.getState())); + iAuthUserService.setName(assetPurchase, "createId", "createName"); + return assetPurchase; + } + + @Override + public void revokePostpose(AssetPurchase entity) { + super.revokePostpose(entity); + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(AssetPurchase entity) { + // 修改子单据状态 + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + public void approvalEndIsFailed(AssetPurchase entity) { + assetPurchaseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + @Override + public void queryAssetPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + AssetPurchase assetPurchase = selectById(id); + // 获取已经下达采购退货单的资产信息 + Map returnExecuteNum = assetPurchaseReturnService.calcAssetNumByFromId(assetPurchase.getId()); + // 获取已经下达采购入库单的资产信息 + Map putExecuteNum = assetPurchasePutService.calcAssetNumByFromId(assetPurchase.getId()); + assetPurchase.getPurchaseLinks().forEach(purchaseLink -> { + // 采购订单数量 - 已入库数量 - 已退货数量 + Integer surplusNum = purchaseLink.getPurchaseNum() + - (putExecuteNum.containsKey(purchaseLink.getAssetId()) ? putExecuteNum.get(purchaseLink.getAssetId()) : 0) + - (returnExecuteNum.containsKey(purchaseLink.getAssetId()) ? returnExecuteNum.get(purchaseLink.getAssetId()) : 0); + // 设置未下达采购入库单/采购退货单的资产数量 + purchaseLink.setPurchaseNum(surplusNum); + }); + + // 过滤掉数量为0的进行生成采购入库单/退货单 + assetPurchase.setPurchaseLinks(assetPurchase.getPurchaseLinks().stream() + .filter(purchaseLink -> purchaseLink.getPurchaseNum() > 0).collect(Collectors.toList())); + outputObject.setBean(assetPurchase); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertAssetPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + AssetPurchasePut assetPurchasePut = inputObject.getParams(AssetPurchasePut.class); + // 获取采购单状态 + AssetPurchase order = selectById(assetPurchasePut.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到采购入库单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || PurchaseOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + assetPurchasePut.setFromId(assetPurchasePut.getId()); + assetPurchasePut.setFromTypeId(PurchasePutFromType.PURCHASE_ORDER.getKey()); + assetPurchasePut.setId(StrUtil.EMPTY); + assetPurchasePutService.createEntity(assetPurchasePut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购入库单."); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertAssetPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject) { + AssetPurchaseReturn assetPurchaseReturn = inputObject.getParams(AssetPurchaseReturn.class); + // 获取采购单状态 + AssetPurchase order = selectById(assetPurchaseReturn.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到采购退货单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || PurchaseOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + assetPurchaseReturn.setFromId(assetPurchaseReturn.getId()); + assetPurchaseReturn.setFromTypeId(PurchaseReturnFromType.PURCHASE_ORDER.getKey()); + assetPurchaseReturn.setId(StrUtil.EMPTY); + assetPurchaseReturnService.createEntity(assetPurchaseReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购退货单."); + } + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List entityList = list(queryWrapper); + Map entityMap = entityList.stream().collect(Collectors.toMap(AssetPurchase::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + AssetPurchase entity = entityMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReportServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReportServiceImpl.java new file mode 100644 index 0000000..395e14f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReportServiceImpl.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.csp.sentinel.util.StringUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.PropertiesUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.classenum.AssetReportState; +import com.skyeye.eve.assets.dao.AssetReportDao; +import com.skyeye.eve.assets.entity.AssetReport; +import com.skyeye.eve.assets.entity.AssetReportQueryDo; +import com.skyeye.eve.assets.service.AssetReportService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IBarCodeService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetReportServiceImpl + * @Description: 资产明细服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 14:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产明细管理", groupName = "资产模块") +public class AssetReportServiceImpl extends SkyeyeBusinessServiceImpl implements AssetReportService { + + @Autowired + private IBarCodeService iBarCodeService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private AssetService assetService; + + @Override + public void getQueryWrapper(InputObject inputObject, QueryWrapper wrapper) { + setCustomerWrapper(inputObject, wrapper); + } + + private static void setCustomerWrapper(InputObject inputObject, QueryWrapper wrapper) { + AssetReportQueryDo commonPageInfo = inputObject.getParams(AssetReportQueryDo.class); + if (StrUtil.isNotEmpty(commonPageInfo.getAssetId())) { + wrapper.eq(MybatisPlusUtil.toColumns(AssetReport::getAssetId), commonPageInfo.getAssetId()); + } + if (StrUtil.equals("unPut", commonPageInfo.getState())) { + // 未入库的(状态为空) + String stateKey = MybatisPlusUtil.toColumns(AssetReport::getState); + wrapper.and(wra -> { + wra.isNull(stateKey).or().eq(stateKey, StrUtil.EMPTY); + }); + } + if (StrUtil.equals("unUse", commonPageInfo.getState())) { + // 未申领的 + String useUserIdKey = MybatisPlusUtil.toColumns(AssetReport::getUseUserId); + wrapper.and(wra -> { + wra.isNull(useUserIdKey).or().eq(useUserIdKey, StrUtil.EMPTY); + }); + // && 状态不能为空 + String stateKey = MybatisPlusUtil.toColumns(AssetReport::getState); + wrapper.isNotNull(stateKey).ne(stateKey, StrUtil.EMPTY).ne(stateKey, AssetReportState.RETURN.getKey()); + } + if (StrUtil.equals("myUse", commonPageInfo.getState())) { + // 我借用中的 + String userId = inputObject.getLogParams().get("id").toString(); + wrapper.eq(MybatisPlusUtil.toColumns(AssetReport::getUseUserId), userId); + } + wrapper.orderByDesc(MybatisPlusUtil.toColumns(AssetReport::getCreateTime)); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(AssetReport::getAssetNum)); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setMationForMap(beans, "assetAdmin", "assetAdminMation"); + iAuthUserService.setMationForMap(beans, "useUserId", "useUserMation"); + iAuthUserService.setMationForMap(beans, "revertUserId", "revertUserMation"); + + assetService.setMationForMap(beans, "assetId", "assetMation"); + + iBarCodeService.setBarCodeMationForMap(beans, "id", getServiceClassName()); + return beans; + } + + @Override + public void deletePreExecution(String id) { + AssetReport assetReport = selectById(id); + if (assetReport.getState() != null) { + throw new CustomException("该编码正常使用中,无法删除"); + } + } + + @Override + public void deletePostpose(String id) { + iBarCodeService.deleteByObjectId(id); + } + + @Override + public void setAssetReportEmployee(String id, String useId, String useUserId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + AssetReport assetReportMation = new AssetReport(); + assetReportMation.setUseId(useId); + assetReportMation.setUseUserId(useUserId); + // 设置归还信息为空 + assetReportMation.setRevertId(StringUtil.EMPTY); + assetReportMation.setRevertUserId(StringUtil.EMPTY); + update(assetReportMation, updateWrapper); + refreshCache(id); + } + + @Override + public void setAssetReportRevert(String id, String revertId, String revertUserId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + AssetReport assetReportMation = new AssetReport(); + assetReportMation.setRevertId(revertId); + assetReportMation.setRevertUserId(revertUserId); + // 设置领用信息为空 + assetReportMation.setUseId(StringUtil.EMPTY); + assetReportMation.setUseUserId(StringUtil.EMPTY); + update(assetReportMation, updateWrapper); + refreshCache(id); + } + + @Override + public Long getAssetReportNumByAssetId(String assetId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetReport::getAssetId), assetId); + return count(queryWrapper); + } + + @Override + public List queryAssetReportListByCodeNum(List codeNumList, Boolean depotState) { + codeNumList = codeNumList.stream().distinct().collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(AssetReport::getAssetNum), codeNumList); + if (!depotState) { + String stateKey = MybatisPlusUtil.toColumns(AssetReport::getState); + queryWrapper.and(Wrapper -> { + Wrapper.isNull(stateKey).or().eq(stateKey, StrUtil.EMPTY); + }); + } else { + String stateKey = MybatisPlusUtil.toColumns(AssetReport::getState); + queryWrapper.isNotNull(stateKey).ne(stateKey, StrUtil.EMPTY); + } + List assetReportList = list(queryWrapper); + return assetReportList; + } + + @Override + public void insertAssetReport(InputObject inputObject, OutputObject outputObject) { + List> list = JSONUtil.toList(inputObject.getParams().get("list").toString(), null); + if (CollectionUtil.isEmpty(list)) { + return; + } + List assetIdList = list.stream().map(bean -> bean.get("assetId").toString()).distinct().collect(Collectors.toList()); + if (list.size() != assetIdList.size()) { + throw new CustomException("存在重复的资产信息,请确认"); + } + + // 创建任务 + Map jobBody = new HashMap<>(); + // 是否创建任务 + jobBody.put("whetherCreatTask", false); + jobBody.put("list", JSONUtil.toJsonStr(list)); + jobBody.put("className", getServiceClassName()); + jobBody.put("userId", inputObject.getLogParams().get("id").toString()); + String topic = PropertiesUtil.getPropertiesValue("${topic.asset-generate-barcode}"); + jobBody.put("topic", topic); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(jobBody)); + jobMateMation.setUserId(inputObject.getLogParams().get("id").toString()); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + @Override + public void queryAssetReportCodeList(InputObject inputObject, OutputObject outputObject) { + AssetReportQueryDo commonPageInfo = inputObject.getParams(AssetReportQueryDo.class); + QueryWrapper wrapper = new QueryWrapper<>(); + setCustomerWrapper(inputObject, wrapper); + + if (commonPageInfo.getNumber() != null) { + wrapper.last(String.format(Locale.ROOT, "limit %s", commonPageInfo.getNumber())); + } else { + wrapper.last(String.format(Locale.ROOT, "limit %s", 20)); + } + wrapper.select(MybatisPlusUtil.toColumns(AssetReport::getAssetNum)); + List assetReportList = list(wrapper); + List codeNumList = assetReportList.stream().map(AssetReport::getAssetNum).collect(Collectors.toList()); + outputObject.setBeans(codeNumList); + outputObject.settotal(codeNumList.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnLinkServiceImpl.java new file mode 100644 index 0000000..b04ac3e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.assets.dao.AssetReturnLinkDao; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.entity.AssetReturnLink; +import com.skyeye.eve.assets.service.AssetReturnLinkService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetReturnLinkServiceImpl + * @Description: 资产归还申请关联的资产信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产归还单-资产Link", groupName = "资产模块", manageShow = false) +public class AssetReturnLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements AssetReturnLinkService { + + @Autowired + private AssetService assetService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("资产信息不能为空."); + } + List articleIds = beans.stream().map(AssetReturnLink::getAssetId).distinct().collect(Collectors.toList()); + Map articlesMap = assetService.selectMapByIds(articleIds); + beans.forEach(assetReturnLink -> { + Asset asset = articlesMap.get(assetReturnLink.getAssetId()); + if (asset == null) { + throw new CustomException("数据中包含不存在的资产信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnServiceImpl.java new file mode 100644 index 0000000..3ccbcdb --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetReturnServiceImpl.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.dao.AssetReturnDao; +import com.skyeye.eve.assets.entity.AssetReport; +import com.skyeye.eve.assets.entity.AssetReturn; +import com.skyeye.eve.assets.entity.AssetReturnLink; +import com.skyeye.eve.assets.service.AssetReportService; +import com.skyeye.eve.assets.service.AssetReturnLinkService; +import com.skyeye.eve.assets.service.AssetReturnService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetReturnServiceImpl + * @Description: 资产归还单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/20 22:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产归还", groupName = "资产模块", flowable = true) +public class AssetReturnServiceImpl extends SkyeyeFlowableServiceImpl implements AssetReturnService { + + @Autowired + private AssetReturnLinkService assetReturnLinkService; + + @Autowired + private AssetService assetService; + + @Autowired + private AssetReportService assetReportService; + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetReturn::getCreateId), userId); + return queryWrapper; + } + + @Override + public void validatorEntity(AssetReturn entity) { + chectOrderItem(entity.getReturnLinks()); + setOtherMation(entity); + } + + @Override + public void writeChild(AssetReturn entity, String userId) { + assetReturnLinkService.saveLinkList(entity.getId(), entity.getReturnLinks()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List returnLinks) { + if (CollectionUtil.isEmpty(returnLinks)) { + throw new CustomException("请最少选择一条资产信息"); + } + List assetReportId = returnLinks.stream() + .map(AssetReturnLink::getAssetReportId).distinct().collect(Collectors.toList()); + if (returnLinks.size() != assetReportId.size()) { + throw new CustomException("单据中不允许出现同一个资产信息"); + } + } + + private void setOtherMation(AssetReturn entity) { + // 设置资产id + List assetReportId = entity.getReturnLinks().stream().map(AssetReturnLink::getAssetReportId).collect(Collectors.toList()); + Map assetReportMap = assetReportService.selectMapByIds(assetReportId); + entity.getReturnLinks().forEach(assetReturnLink -> { + assetReturnLink.setAssetId(assetReportMap.get(assetReturnLink.getAssetReportId()).getAssetId()); + }); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + assetReturnLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public AssetReturn getDataFromDb(String id) { + AssetReturn assetReturn = super.getDataFromDb(id); + List assetReturnLinks = assetReturnLinkService.selectByPId(assetReturn.getId()); + assetReturn.setReturnLinks(assetReturnLinks); + return assetReturn; + } + + @Override + public AssetReturn selectById(String id) { + AssetReturn assetReturn = super.selectById(id); + // 获取资产信息 + assetService.setDataMation(assetReturn.getReturnLinks(), AssetReturnLink::getAssetId); + assetReturn.getReturnLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + // 设置资产明细数据 + assetReportService.setDataMation(assetReturn.getReturnLinks(), AssetReturnLink::getAssetReportId); + assetReturn.setStateName(FlowableStateEnum.getStateName(assetReturn.getState())); + iAuthUserService.setName(assetReturn, "createId", "createName"); + return assetReturn; + } + + @Override + public void revokePostpose(AssetReturn entity) { + super.revokePostpose(entity); + assetReturnLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(AssetReturn entity) { + AssetReturn assetReturn = selectById(entity.getId()); + for (AssetReturnLink bean : assetReturn.getReturnLinks()) { + assetReportService.setAssetReportRevert(bean.getAssetReportId(), entity.getId(), entity.getCreateId()); + } + assetReturnLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + protected void approvalEndIsFailed(AssetReturn entity) { + assetReturnLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetServiceImpl.java new file mode 100644 index 0000000..549dcdd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetServiceImpl.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.dao.AssetDao; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.service.AssetReportService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: AssetServiceImpl + * @Description: 资产管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产管理", groupName = "资产模块") +public class AssetServiceImpl extends SkyeyeBusinessServiceImpl implements AssetService { + + @Autowired + private AssetReportService assetReportService; + + @Override + public void validatorEntity(Asset entity) { + super.validatorEntity(entity); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(Asset::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(Asset::getNumberPrefix), entity.getNumberPrefix())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Asset checkAssetMation = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkAssetMation)) { + throw new CustomException("this data is exist."); + } + } + + @Override + public void deletePreExecution(String id) { + Long assetReportNum = assetReportService.getAssetReportNumByAssetId(id); + if (assetReportNum > 0) { + throw new CustomException("无法删除拥有明细的资产."); + } + } + + @Override + public Asset selectById(String id) { + Asset asset = super.selectById(id); + return asset; + } + + @Override + public List selectByIds(String... ids) { + List assetList = super.selectByIds(ids); + return assetList; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseLinkServiceImpl.java new file mode 100644 index 0000000..637b194 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.assets.dao.AssetUseLinkDao; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.entity.AssetUseLink; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.eve.assets.service.AssetUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetUseLinkServiceImpl + * @Description: 资产领用申请关联的资产信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产领用单-资产Link", groupName = "资产模块", manageShow = false) +public class AssetUseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements AssetUseLinkService { + + @Autowired + private AssetService assetService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("资产信息不能为空."); + } + List articleIds = beans.stream().map(AssetUseLink::getAssetId).distinct().collect(Collectors.toList()); + Map articlesMap = assetService.selectMapByIds(articleIds); + beans.forEach(assetUseLink -> { + Asset asset = articlesMap.get(assetUseLink.getAssetId()); + if (asset == null) { + throw new CustomException("数据中包含不存在的资产信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseServiceImpl.java new file mode 100644 index 0000000..d984985 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/assets/service/impl/AssetUseServiceImpl.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.assets.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.assets.dao.AssetUseDao; +import com.skyeye.eve.assets.entity.AssetReport; +import com.skyeye.eve.assets.entity.AssetUse; +import com.skyeye.eve.assets.entity.AssetUseLink; +import com.skyeye.eve.assets.service.AssetReportService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.eve.assets.service.AssetUseLinkService; +import com.skyeye.eve.assets.service.AssetUseService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetUseServiceImpl + * @Description: 资产领用服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 17:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资产领用", groupName = "资产模块", flowable = true) +public class AssetUseServiceImpl extends SkyeyeFlowableServiceImpl implements AssetUseService { + + @Autowired + private AssetUseLinkService assetUseLinkService; + + @Autowired + private AssetService assetService; + + @Autowired + private AssetReportService assetReportService; + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AssetUse::getCreateId), userId); + return queryWrapper; + } + + @Override + public void validatorEntity(AssetUse entity) { + chectOrderItem(entity.getUseLinks()); + setOtherMation(entity); + } + + @Override + public void writeChild(AssetUse entity, String userId) { + assetUseLinkService.saveLinkList(entity.getId(), entity.getUseLinks()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List useLinks) { + if (CollectionUtil.isEmpty(useLinks)) { + throw new CustomException("请最少选择一条资产信息"); + } + List assetReportId = useLinks.stream() + .map(AssetUseLink::getAssetReportId).distinct().collect(Collectors.toList()); + if (useLinks.size() != assetReportId.size()) { + throw new CustomException("单据中不允许出现同一个资产信息"); + } + } + + private void setOtherMation(AssetUse entity) { + // 设置资产id + List assetReportId = entity.getUseLinks().stream().map(AssetUseLink::getAssetReportId).collect(Collectors.toList()); + Map assetReportMap = assetReportService.selectMapByIds(assetReportId); + entity.getUseLinks().forEach(assetUseLink -> { + assetUseLink.setAssetId(assetReportMap.get(assetUseLink.getAssetReportId()).getAssetId()); + }); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + assetUseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public AssetUse getDataFromDb(String id) { + AssetUse assetUse = super.getDataFromDb(id); + List assetUseLinks = assetUseLinkService.selectByPId(assetUse.getId()); + assetUse.setUseLinks(assetUseLinks); + return assetUse; + } + + @Override + public AssetUse selectById(String id) { + AssetUse assetUse = super.selectById(id); + // 获取资产信息 + assetService.setDataMation(assetUse.getUseLinks(), AssetUseLink::getAssetId); + assetUse.getUseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + // 设置资产明细数据 + assetReportService.setDataMation(assetUse.getUseLinks(), AssetUseLink::getAssetReportId); + assetUse.setStateName(FlowableStateEnum.getStateName(assetUse.getState())); + iAuthUserService.setName(assetUse, "createId", "createName"); + return assetUse; + } + + @Override + public void revokePostpose(AssetUse entity) { + super.revokePostpose(entity); + assetUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(AssetUse entity) { + AssetUse assetUse = selectById(entity.getId()); + for (AssetUseLink bean : assetUse.getUseLinks()) { + // 当前资产的领用人为空 + if (StrUtil.isEmpty(bean.getAssetReportMation().getUseUserId())) { + // 设置资产的领用人 + assetReportService.setAssetReportEmployee(bean.getAssetReportId(), entity.getId(), entity.getCreateId()); + assetUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } else { + // 当前库存不足,修改资产领用状态,审批不通过 + assetUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + } + } + + @Override + protected void approvalEndIsFailed(AssetUse entity) { + assetUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectController.java new file mode 100644 index 0000000..a51c2ff --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectController.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.businessflow.service.PlanProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PlanProjectController + * @Description: 业务流程规划管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/2 0:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "业务流程规划", tags = "业务流程规划", modelName = "业务流程规划") +public class PlanProjectController { + + @Autowired + private PlanProjectService planProjectService; + + /** + * 获取业务流程规划列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "planproject001", value = "获取业务流程规划列表", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "limit", name = "limit", value = "分页参数,每页多少条数据", required = "required,num"), + @ApiImplicitParam(id = "page", name = "page", value = "分页参数,第几页", required = "required,num"), + @ApiImplicitParam(id = "projectName", name = "projectName", value = "业务流程规划名称")}) + @RequestMapping("/post/PlanProjectController/queryPlanProjectList") + public void queryPlanProjectList(InputObject inputObject, OutputObject outputObject) { + planProjectService.queryPlanProjectList(inputObject, outputObject); + } + + /** + * 新增业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectController/insertPlanProjectMation") + public void insertPlanProjectMation(InputObject inputObject, OutputObject outputObject) { + planProjectService.insertPlanProjectMation(inputObject, outputObject); + } + + /** + * 删除业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectController/deletePlanProjectMationById") + public void deletePlanProjectMationById(InputObject inputObject, OutputObject outputObject) { + planProjectService.deletePlanProjectMationById(inputObject, outputObject); + } + + /** + * 编辑业务流程规划时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectController/queryPlanProjectMationToEditById") + public void queryPlanProjectMationToEditById(InputObject inputObject, OutputObject outputObject) { + planProjectService.queryPlanProjectMationToEditById(inputObject, outputObject); + } + + /** + * 编辑业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectController/editPlanProjectMationById") + public void editPlanProjectMationById(InputObject inputObject, OutputObject outputObject) { + planProjectService.editPlanProjectMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectFlowController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectFlowController.java new file mode 100644 index 0000000..e31f755 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/controller/PlanProjectFlowController.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.businessflow.service.PlanProjectFlowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlanProjectFlowController { + + @Autowired + private PlanProjectFlowService planProjectFlowService; + + /** + * 获取项目规划-项目流程图表列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/queryPlanProjectFlowList") + public void queryPlanProjectFlowList(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.queryPlanProjectFlowList(inputObject, outputObject); + } + + /** + * 添加项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/insertPlanProjectFlowMation") + public void insertPlanProjectFlowMation(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.insertPlanProjectFlowMation(inputObject, outputObject); + } + + /** + * 删除项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/deletePlanProjectFlowMationById") + public void deletePlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.deletePlanProjectFlowMationById(inputObject, outputObject); + } + + /** + * 编辑项目规划-项目流程图表信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/queryPlanProjectFlowMationToEditById") + public void queryPlanProjectFlowMationToEditById(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.queryPlanProjectFlowMationToEditById(inputObject, outputObject); + } + + /** + * 编辑项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/editPlanProjectFlowMationById") + public void editPlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.editPlanProjectFlowMationById(inputObject, outputObject); + } + + /** + * 获取项目流程图内容进行设计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/queryPlanProjectFlowJsonContentMationById") + public void queryPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.queryPlanProjectFlowJsonContentMationById(inputObject, outputObject); + } + + /** + * 设计项目流程图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/PlanProjectFlowController/editPlanProjectFlowJsonContentMationById") + public void editPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject) { + planProjectFlowService.editPlanProjectFlowJsonContentMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectDao.java new file mode 100644 index 0000000..50b31ad --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.dao; + +import java.util.List; +import java.util.Map; + +public interface PlanProjectDao { + + List> queryPlanProjectList(Map map); + + int insertPlanProjectMation(Map map); + + Map judgePlanProjectName(Map map); + + int deletePlanProjectMationById(Map map); + + Map queryPlanProjectMationToEditById(Map map); + + int editPlanProjectMationById(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectFlowDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectFlowDao.java new file mode 100644 index 0000000..b74da06 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/dao/PlanProjectFlowDao.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.dao; + +import java.util.List; +import java.util.Map; + +public interface PlanProjectFlowDao { + + List> queryPlanProjectFlowList(Map map); + + int insertPlanProjectFlowMation(Map map); + + Map queryPlanProjectFlowMationByName(Map map); + + int deletePlanProjectFlowMationById(Map map); + + Map queryPlanProjectFlowMationToEditById(Map map); + + Map queryPlanProjectFlowMationByNameAndId(Map map); + + int editPlanProjectFlowMationById(Map map); + + Map queryChildNumMationById(Map map); + + Map queryPlanProjectFlowJsonContentMationById(Map map); + + int editPlanProjectFlowJsonContentMationById(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectFlowService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectFlowService.java new file mode 100644 index 0000000..b1e5104 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectFlowService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface PlanProjectFlowService { + + void queryPlanProjectFlowList(InputObject inputObject, OutputObject outputObject); + + void insertPlanProjectFlowMation(InputObject inputObject, OutputObject outputObject); + + void deletePlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject); + + void queryPlanProjectFlowMationToEditById(InputObject inputObject, OutputObject outputObject); + + void editPlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject); + + void queryPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject); + + void editPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectService.java new file mode 100644 index 0000000..a7cfd83 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/PlanProjectService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface PlanProjectService { + + void queryPlanProjectList(InputObject inputObject, OutputObject outputObject); + + void insertPlanProjectMation(InputObject inputObject, OutputObject outputObject); + + void deletePlanProjectMationById(InputObject inputObject, OutputObject outputObject); + + void queryPlanProjectMationToEditById(InputObject inputObject, OutputObject outputObject); + + void editPlanProjectMationById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectFlowServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectFlowServiceImpl.java new file mode 100644 index 0000000..767ca1f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectFlowServiceImpl.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.service.impl; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.eve.businessflow.dao.PlanProjectFlowDao; +import com.skyeye.eve.businessflow.service.PlanProjectFlowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +public class PlanProjectFlowServiceImpl implements PlanProjectFlowService { + + @Autowired + private PlanProjectFlowDao planProjectFlowDao; + + /** + * 获取项目规划-项目流程图表列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPlanProjectFlowList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = planProjectFlowDao.queryPlanProjectFlowList(map); + if (!beans.isEmpty()) { + beans.forEach(bean -> { + if ("1".equals(bean.get("isParent").toString())) { + bean.put("isParent", true); + } else { + bean.put("isParent", false); + } + }); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + /** + * 添加项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertPlanProjectFlowMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectFlowDao.queryPlanProjectFlowMationByName(map); + if (bean == null) { + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + planProjectFlowDao.insertPlanProjectFlowMation(map); + } else { + outputObject.setreturnMessage("该项目规划-项目流程图表名称已存在,不可进行二次保存"); + } + } + + /** + * 删除项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deletePlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectFlowDao.queryChildNumMationById(map); + if (Integer.parseInt(bean.get("childNum").toString()) == 0) { + // 判断是否有子项 + planProjectFlowDao.deletePlanProjectFlowMationById(map); + } else { + outputObject.setreturnMessage("该目录下存在子项,无法直接删除。"); + } + + } + + /** + * 编辑项目规划-项目流程图表信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPlanProjectFlowMationToEditById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectFlowDao.queryPlanProjectFlowMationToEditById(map); + outputObject.setBean(bean); + outputObject.settotal(1); + } + + /** + * 编辑项目规划-项目流程图表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editPlanProjectFlowMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectFlowDao.queryPlanProjectFlowMationByNameAndId(map); + if (bean == null) { + planProjectFlowDao.editPlanProjectFlowMationById(map); + } else { + outputObject.setreturnMessage("该项目规划-项目流程图表名称已存在,不可进行二次保存"); + } + } + + /** + * 获取项目流程图内容进行设计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectFlowDao.queryPlanProjectFlowJsonContentMationById(map); + outputObject.setBean(bean); + } + + /** + * 设计项目流程图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editPlanProjectFlowJsonContentMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + planProjectFlowDao.editPlanProjectFlowJsonContentMationById(map); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectServiceImpl.java new file mode 100644 index 0000000..1aa74ed --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/businessflow/service/impl/PlanProjectServiceImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.businessflow.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.businessflow.dao.PlanProjectDao; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.eve.businessflow.service.PlanProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +public class PlanProjectServiceImpl implements PlanProjectService { + + @Autowired + private PlanProjectDao planProjectDao; + + @Autowired + private IAuthUserService iAuthUserService; + + /** + * 获取业务流程规划列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPlanProjectList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = planProjectDao.queryPlanProjectList(map); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertPlanProjectMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectDao.judgePlanProjectName(map); + if (bean == null) { + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + planProjectDao.insertPlanProjectMation(map); + } else { + outputObject.setreturnMessage("该业务流程规划名称已存在."); + } + } + + /** + * 删除业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deletePlanProjectMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + planProjectDao.deletePlanProjectMationById(map); + } + + /** + * 编辑业务流程规划时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPlanProjectMationToEditById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectDao.queryPlanProjectMationToEditById(map); + outputObject.setBean(bean); + outputObject.settotal(1); + } + + /** + * 编辑业务流程规划 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editPlanProjectMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = planProjectDao.judgePlanProjectName(map); + if (bean == null) { + Map user = inputObject.getLogParams(); + map.put("lastUpdateId", user.get("id")); + map.put("lastUpdateTime", DateUtil.getTimeAndToString()); + planProjectDao.editPlanProjectMationById(map); + } else { + outputObject.setreturnMessage("该业务流程规划名称已存在."); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/classenum/ConferenceState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/classenum/ConferenceState.java new file mode 100644 index 0000000..8ae21a4 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/classenum/ConferenceState.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ConferenceState + * @Description: 会议室状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ConferenceState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + REPAIR(2, "维修", true, false), + SCRAP(3, "报废", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ConferenceState bean : ConferenceState.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomController.java new file mode 100644 index 0000000..5545a6a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomController.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.conference.entity.ConferenceRoom; +import com.skyeye.eve.conference.service.ConferenceRoomService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ConferenceRoomController + * @Description: 会议室管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 15:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "会议室管理", tags = "会议室管理", modelName = "会议室模块") +public class ConferenceRoomController { + + @Autowired + private ConferenceRoomService conferenceRoomService; + + /** + * 查询会议室列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroom001", value = "查询会议室列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ConferenceRoomController/queryConferenceRoomList") + public void queryConferenceRoomList(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改会议室信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeConferenceRoom", value = "新增/修改会议室信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConferenceRoom.class) + @RequestMapping("/post/ConferenceRoomController/writeConferenceRoom") + public void writeConferenceRoom(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除会议室信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroom003", value = "根据id删除会议室信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomController/deleteConferenceRoomById") + public void deleteConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.deleteById(inputObject, outputObject); + } + + /** + * 会议室恢复正常 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroom004", value = "会议室恢复正常", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomController/normalConferenceRoomById") + public void normalConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.normalConferenceRoomById(inputObject, outputObject); + } + + /** + * 会议室维修 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroom005", value = "会议室维修", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomController/repairConferenceRoomById") + public void repairConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.repairConferenceRoomById(inputObject, outputObject); + } + + /** + * 会议室报废 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroom006", value = "会议室报废", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomController/scrapConferenceRoomById") + public void scrapConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.scrapConferenceRoomById(inputObject, outputObject); + } + + /** + * 根据id查询会议室信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryConferenceRoomById", value = "根据id查询会议室信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomController/queryConferenceRoomById") + public void queryConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.selectById(inputObject, outputObject); + } + + /** + * 获取所有会议室列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroomreserve008", value = "获取所有会议室列表", method = "GET", allUse = "2") + @RequestMapping("/post/ConferenceRoomController/queryAllConferenceRoomList") + public void queryAllConferenceRoomList(InputObject inputObject, OutputObject outputObject) { + conferenceRoomService.queryAllConferenceRoomList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomReserveController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomReserveController.java new file mode 100644 index 0000000..054119a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/controller/ConferenceRoomReserveController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.conference.entity.ConferenceRoomReserve; +import com.skyeye.eve.conference.service.ConferenceRoomReserveService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ConferenceRoomReserveController + * @Description: 会议室预定申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 14:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "会议室预定", tags = "会议室预定", modelName = "会议室模块") +public class ConferenceRoomReserveController { + + @Autowired + private ConferenceRoomReserveService conferenceRoomReserveService; + + /** + * 获取我发起的会议室预定申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroomreserve001", value = "获取我发起的会议室预定申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ConferenceRoomReserveController/queryConferenceRoomReserveList") + public void queryConferenceRoomReserveList(InputObject inputObject, OutputObject outputObject) { + conferenceRoomReserveService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑会议室预定申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeConferenceRoomReserve", value = "新增/编辑会议室预定申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConferenceRoomReserve.class) + @RequestMapping("/post/ConferenceRoomReserveController/writeConferenceRoomReserve") + public void writeConferenceRoomReserve(InputObject inputObject, OutputObject outputObject) { + conferenceRoomReserveService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 会议室预定申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroomreserve006", value = "会议室预定申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ConferenceRoomReserveController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + conferenceRoomReserveService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废会议室预定申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroomreserve007", value = "作废会议室预定申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConferenceRoomReserveController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + conferenceRoomReserveService.invalid(inputObject, outputObject); + } + + /** + * 撤销会议室预定申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "conferenceroomreserve010", value = "撤销会议室预定申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ConferenceRoomReserveController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + conferenceRoomReserveService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomDao.java new file mode 100644 index 0000000..9ed3ef3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.dao; + +import com.skyeye.eve.conference.entity.ConferenceRoom; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ConferenceRoomDao + * @Description: 会议室管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 15:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConferenceRoomDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomReserveDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomReserveDao.java new file mode 100644 index 0000000..bf04bbd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/dao/ConferenceRoomReserveDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.dao; + +import com.skyeye.eve.conference.entity.ConferenceRoomReserve; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ConferenceRoomReserveDao + * @Description: 会议室预定申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 14:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConferenceRoomReserveDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoom.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoom.java new file mode 100644 index 0000000..d017e35 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoom.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ConferenceRoom + * @Description: 会议室实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/6 9:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "assistant:conferenceRoom", cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "conference_room") +@ApiModel("会议室实体类") +public class ConferenceRoom extends BaseGeneralInfo { + + @TableField(value = "room_num") + @Property(value = "会议室编号") + private String roomNum; + + @TableField(value = "img") + @ApiModelProperty(value = "会议室图片", required = "required") + private String img; + + @TableField(value = "capacity") + @ApiModelProperty(value = "会议室容量", required = "required,num") + private Integer capacity; + + @TableField(value = "`position`") + @ApiModelProperty(value = "会议室位置") + private String position; + + @TableField(value = "equipment") + @ApiModelProperty(value = "内部设备") + private String equipment; + + @TableField(value = "room_admin") + @ApiModelProperty(value = "管理人id") + private String roomAdmin; + + @TableField(exist = false) + @Property(value = "管理人") + private Map roomAdminMation; + + @TableField(value = "state") + @Property(value = "会议室状态,参考#ConferenceState") + private Integer state; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoomReserve.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoomReserve.java new file mode 100644 index 0000000..c5315ec --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/entity/ConferenceRoomReserve.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +/** + * @ClassName: ConferenceRoomReserve + * @Description: 会议室预定申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:conferenceRoom:reserve", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "conference_room_reserve") +@ApiModel("会议室预定申请实体类") +public class ConferenceRoomReserve extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String title; + + @TableField("conference_room_id") + @ApiModelProperty(value = "会议室id", required = "required") + private String conferenceRoomId; + + @TableField(exist = false) + @Property(value = "会议室信息") + private ConferenceRoom conferenceRoomMation; + + @TableField("reserve_reason") + @ApiModelProperty(value = "使用事由", required = "required") + private String reserveReason; + + @TableField("start_time") + @ApiModelProperty(value = "开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间", required = "required") + private String endTime; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomReserveService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomReserveService.java new file mode 100644 index 0000000..233b424 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomReserveService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.conference.entity.ConferenceRoomReserve; + +/** + * @ClassName: ConferenceRoomReserveService + * @Description: 会议室预定申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 14:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConferenceRoomReserveService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomService.java new file mode 100644 index 0000000..fa7fee9 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/ConferenceRoomService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.conference.entity.ConferenceRoom; + +/** + * @ClassName: ConferenceRoomService + * @Description: 会议室管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 15:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConferenceRoomService extends SkyeyeBusinessService { + + void normalConferenceRoomById(InputObject inputObject, OutputObject outputObject); + + void repairConferenceRoomById(InputObject inputObject, OutputObject outputObject); + + void scrapConferenceRoomById(InputObject inputObject, OutputObject outputObject); + + void queryAllConferenceRoomList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomReserveServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomReserveServiceImpl.java new file mode 100644 index 0000000..0d5ee44 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomReserveServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.conference.dao.ConferenceRoomReserveDao; +import com.skyeye.eve.conference.entity.ConferenceRoomReserve; +import com.skyeye.eve.conference.service.ConferenceRoomReserveService; +import com.skyeye.eve.conference.service.ConferenceRoomService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: ConferenceRoomReserveServiceImpl + * @Description: 会议室预定申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 14:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "会议室预定", groupName = "会议室模块", flowable = true) +public class ConferenceRoomReserveServiceImpl extends SkyeyeFlowableServiceImpl implements ConferenceRoomReserveService { + + @Autowired + private ConferenceRoomService conferenceRoomService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConferenceRoomReserve::getCreateId), userId); + return queryWrapper; + } + + @Override + public ConferenceRoomReserve selectById(String id) { + ConferenceRoomReserve conferenceRoomReserve = super.selectById(id); + // 获取会议室信息 + conferenceRoomService.setDataMation(conferenceRoomReserve, ConferenceRoomReserve::getConferenceRoomId); + return conferenceRoomReserve; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomServiceImpl.java new file mode 100644 index 0000000..880ec22 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/conference/service/impl/ConferenceRoomServiceImpl.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.conference.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.conference.classenum.ConferenceState; +import com.skyeye.eve.conference.dao.ConferenceRoomDao; +import com.skyeye.eve.conference.entity.ConferenceRoom; +import com.skyeye.eve.conference.service.ConferenceRoomService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ConferenceRoomServiceImpl + * @Description: 会议室管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "会议室管理", groupName = "会议室模块") +public class ConferenceRoomServiceImpl extends SkyeyeBusinessServiceImpl implements ConferenceRoomService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setMationForMap(beans, "roomAdmin", "roomAdminMation"); + return beans; + } + + @Override + public void createPrepose(ConferenceRoom entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + entity.setRoomNum(oddNumber); + entity.setState(ConferenceState.NORMAL.getKey()); + } + + @Override + public ConferenceRoom selectById(String id) { + ConferenceRoom conferenceRoom = super.selectById(id); + conferenceRoom.setRoomAdminMation(iAuthUserService.queryDataMationById(conferenceRoom.getRoomAdmin())); + return conferenceRoom; + } + + /** + * 会议室恢复正常 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void normalConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + ConferenceRoom conferenceRoom = selectById(id); + if (conferenceRoom.getState().equals(ConferenceState.REPAIR.getKey()) || conferenceRoom.getState().equals(ConferenceState.SCRAP.getKey())) { + // 维修或者报废可以恢复正常 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), ConferenceState.NORMAL.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 会议室维修 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void repairConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + ConferenceRoom conferenceRoom = selectById(id); + if (conferenceRoom.getState().equals(ConferenceState.NORMAL.getKey()) || conferenceRoom.getState().equals(ConferenceState.SCRAP.getKey())) { + // 正常或者报废可以维修 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), ConferenceState.REPAIR.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 会议室报废 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void scrapConferenceRoomById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + ConferenceRoom conferenceRoom = selectById(id); + if (conferenceRoom.getState().equals(ConferenceState.NORMAL.getKey()) || conferenceRoom.getState().equals(ConferenceState.REPAIR.getKey())) { + // 正常或者维修可以报废 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), ConferenceState.SCRAP.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 获取会议室列表用于预定选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllConferenceRoomList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConferenceRoom::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List conferenceRoomList = list(queryWrapper); + outputObject.setBeans(conferenceRoomList); + outputObject.settotal(conferenceRoomList.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DefaultFolder.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DefaultFolder.java new file mode 100644 index 0000000..cc1c134 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DefaultFolder.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.constans.CommonNumConstants; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DefaultFolder + * @Description: 默认的文件夹 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DefaultFolder implements SkyeyeEnumClass { + + FAVORITES("1", "收藏夹", "../../assets/images/cloud/my-favorites-icon.png", true, false), + FOLDER("2", "我的文档", "../../assets/images/cloud/my-folder-icon.png", true, false), + SKYDRIVE("3", "企业网盘", "../../assets/images/cloud/skydrive-icon.png", true, false); + + private String key; + + private String value; + + private String icon; + + private Boolean show; + + private Boolean isDefault; + + public static List> getFileConsoleISDefaultFolder() { + List> beans = new ArrayList<>(); + for (DefaultFolder bean : DefaultFolder.values()) { + beans.add(fileConsoleNode(bean)); + } + return beans; + } + + /** + * 构造文件树节点对象 + * + * @param bean + * @return + */ + public static Map fileConsoleNode(DefaultFolder bean) { + Map node = new HashMap<>(); + node.put("id", bean.getKey()); + node.put("name", bean.getValue()); + node.put("pId", CommonNumConstants.NUM_ZERO); + node.put("isParent", CommonNumConstants.NUM_ONE); + node.put("icon", bean.getIcon()); + return node; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DickCloudType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DickCloudType.java new file mode 100644 index 0000000..a52e94c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/DickCloudType.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; + +/** + * @ClassName: DickCloudType + * @Description: 文件和文件夹的类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DickCloudType implements SkyeyeEnumClass { + + FOLDER("folder", "文件夹", true, false), + FILE("file", "文件", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getTypeName(String key) { + DickCloudType item = Arrays.stream(DickCloudType.values()) + .filter(bean -> key.equalsIgnoreCase(bean.getKey())).findFirst().orElse(null); + if (item == null) { + return StrUtil.EMPTY; + } + return item.getValue(); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FileType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FileType.java new file mode 100644 index 0000000..67abf98 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FileType.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.constans.CommonNumConstants; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; + +/** + * @ClassName: FileType + * @Description: 文件类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FileType implements SkyeyeEnumClass { + + IMAGE_IS_PNG("png", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_JPG("jpg", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_XBM("xbm", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_BMP("bmp", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_WEBP("webp", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_JPEG("jpeg", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_SVGZ("svgz", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_GIT("git", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_ICO("ico", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_TIFF("tiff", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_SVG("svg", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_JIFF("jiff", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_PJPEG("pjpeg", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_PJP("pjp", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + IMAGE_IS_TIF("tif", CommonNumConstants.NUM_ONE, StrUtil.EMPTY, false, false), + + OFFICE_IS_DOCX("docx", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/doc.png", false, false), + OFFICE_IS_DOC("doc", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/doc.png", false, false), + OFFICE_IS_XLS("xls", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/xls.png", false, false), + OFFICE_IS_XLSX("xlsx", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/xls.png", false, false), + OFFICE_IS_PPT("ppt", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/ppt.png", false, false), + OFFICE_IS_PPTX("pptx", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/pptx.png", false, false), + OFFICE_IS_WPS("wps", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/wps-icon.png", false, false), + OFFICE_IS_ET("et", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/ppt.png", false, false), + OFFICE_IS_DPS("dps", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/xls.png", false, false), + OFFICE_IS_CSV("csv", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/csv.png", false, false), + OFFICE_IS_PDF("pdf", CommonNumConstants.NUM_TWO, "../../assets/images/cloud/pdf.png", false, false), + + VEDIO_IS_MP4("mp4", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS_RM("rm", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS_RMVB("rmvb", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS_WMV("wmv", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS_AVI("avi", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS3GP("3gp", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + VEDIO_IS_MKV("mkv", CommonNumConstants.NUM_THREE, StrUtil.EMPTY, false, false), + + PACKAGE_IS_ZIP("zip", CommonNumConstants.NUM_FOUR, StrUtil.EMPTY, false, false), + PACKAGE_IS_RAR("rar", CommonNumConstants.NUM_FOUR, StrUtil.EMPTY, false, false), + + ACE_IS_TXT("txt", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/txt.png", false, false), + ACE_IS_SQL("sql", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/sql-icon.png", false, false), + ACE_IS_JAVA("java", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/java-icon.png", false, false), + ACE_IS_CSS("css", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/css-icon.png", false, false), + ACE_IS_HTML("html", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/html.png", false, false), + ACE_IS_HTM("htm", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/html.png", false, false), + ACE_IS_JSON("json", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/json.png", false, false), + ACE_IS_JS("js", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/js.png", false, false), + ACE_IS_TPL("tpl", CommonNumConstants.NUM_FIVE, "../../assets/images/cloud/tpl.png", false, false), + + EPUB_IS("epub", CommonNumConstants.NUM_SIX, StrUtil.EMPTY, false, false); + + private String key; + + // 1.图片 2.办公文件 3.视频 4.压缩包 5.普通文件 6.电子书 + private int type; + + private String defaultLogoIcon; + + private Boolean show; + + private Boolean isDefault; + + /** + * 根据文件后缀获取封面logo + * + * @param fileExt 文件后缀 + * @return 封面logo + */ + public static String getIconByFileExt(String fileExt) { + FileType item = Arrays.stream(FileType.values()) + .filter(bean -> fileExt.equalsIgnoreCase(bean.getKey())).findFirst().orElse(null); + if (item == null) { + return StrUtil.EMPTY; + } + return item.getDefaultLogoIcon(); + } + + /** + * 判断是否是文件系统允许的文件后缀类型 + * + * @param fileExt 文件后缀 + * @param type 文件类型 + * @return false:系统不允许的文件类型;true:系统允许的文件类型 + */ + public static Boolean judgeIsAllowedFileType(String fileExt, int type) { + FileType item = Arrays.stream(FileType.values()) + .filter(bean -> fileExt.equalsIgnoreCase(bean.getKey()) && type == bean.getType()).findFirst().orElse(null); + if (item == null) { + return false; + } + return true; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FolderType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FolderType.java new file mode 100644 index 0000000..e6065df --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/FolderType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FolderType + * @Description: 文件夹类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FolderType implements SkyeyeEnumClass { + + COMPANY(1, "企业网盘", true, false), + PERSONER(2, "私人网盘", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareState.java new file mode 100644 index 0000000..56817f5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareState.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; + +/** + * @ClassName: ShareState + * @Description: 文件分享状态 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShareState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + LOSE_EFFICACY(2, "失效", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getTypeName(Integer key) { + ShareState item = Arrays.stream(ShareState.values()) + .filter(bean -> key.equals(bean.getKey())).findFirst().orElse(null); + if (item == null) { + return StrUtil.EMPTY; + } + return item.getValue(); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareType.java new file mode 100644 index 0000000..41f4b48 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/classenum/ShareType.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; + +/** + * @ClassName: ShareType + * @Description: 文件分享类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShareType implements SkyeyeEnumClass { + + PUBLIC(1, "公开分享", true, false), + PRIVATE(2, "私密分享", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getTypeName(Integer key) { + ShareType item = Arrays.stream(ShareType.values()) + .filter(bean -> key.equals(bean.getKey())).findFirst().orElse(null); + if (item == null) { + return StrUtil.EMPTY; + } + return item.getValue(); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileCatalogController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileCatalogController.java new file mode 100644 index 0000000..8af8888 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileCatalogController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.service.FileCatalogService; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FileCatalogController + * @Description: 文件夹管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 11:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "文件夹管理", tags = "文件夹管理", modelName = "文件夹管理") +public class FileCatalogController { + + @Autowired + private FileCatalogService fileCatalogService; + + /** + * 新增文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertFileCatalog", value = "新增文件夹", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = FileCatalog.class) + @RequestMapping("/post/FileCatalogController/insertFileCatalog") + public void insertFileCatalog(InputObject inputObject, OutputObject outputObject) { + fileCatalogService.createEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileConsoleController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileConsoleController.java new file mode 100644 index 0000000..e8cfe5f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileConsoleController.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.service.FileConsoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysWorkPlanController + * @Description: 文件管理--云盘 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "文件管理", tags = "文件管理", modelName = "文件管理") +public class FileConsoleController { + + @Autowired + private FileConsoleService fileConsoleService; + + /** + * 根据当前用户获取目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole001", value = "根据当前用户获取目录", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "parentId", name = "parentId", value = "父目录id,默认为0", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryFileFolderByUserId") + public void queryFileFolderByUserId(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryFileFolderByUserId(inputObject, outputObject); + } + + /** + * 获取这个目录下的所有文件+目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole003", value = "获取这个目录下的所有文件+目录", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "orderBy", name = "orderBy", value = "排序方式"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryFilesListByFolderId") + public void queryFilesListByFolderId(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryFilesListByFolderId(inputObject, outputObject); + } + + /** + * 删除目录以及目录下的所有文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole004", value = "删除目录以及目录下的所有文件", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "fileList", name = "fileList", value = "要删除的目录id集合,包含 id,fileType", required = "required,json")}) + @RequestMapping("/post/FileConsoleController/deleteFileFolderById") + public void deleteFileFolderById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.deleteFileFolderById(inputObject, outputObject); + } + + /** + * 编辑文件夹或者文件的名称 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editCloudFileFolderById", value = "编辑文件夹或者文件的名称", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "文件夹/文件id", required = "required"), + @ApiImplicitParam(id = "name", name = "name", value = "文件夹/文件的名称", required = "required"), + @ApiImplicitParam(id = "fileType", name = "fileType", value = "文件或者文件夹类型", required = "required")}) + @RequestMapping("/post/FileConsoleController/editCloudFileFolderById") + public void editCloudFileFolderById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.editFileFolderById(inputObject, outputObject); + } + + /** + * 上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertUploadFile", value = "上传文件", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "name", name = "name", value = "文件名", required = "required"), + @ApiImplicitParam(id = "size", name = "size", value = "文件大小", required = "required,num"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件所属目录id", required = "required"), + @ApiImplicitParam(id = "md5", name = "md5", value = "文件唯一标示", required = "required"), + @ApiImplicitParam(id = "chunk", name = "chunk", value = "分块上传,块下标", required = "required"), + @ApiImplicitParam(id = "chunkSize", name = "chunkSize", value = "分块上传时,块的大小,用于最后合并", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertUploadFile") + public void insertUploadFile(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertUploadFile(inputObject, outputObject); + } + + /** + * 上传文件合并块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertUploadFileChunks", value = "上传文件合并块", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "name", name = "name", value = "文件名", required = "required"), + @ApiImplicitParam(id = "size", name = "size", value = "文件大小", required = "required,num"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件所属目录id", required = "required"), + @ApiImplicitParam(id = "md5", name = "md5", value = "文件唯一标示", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertUploadFileChunks") + public void insertUploadFileChunks(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertUploadFileChunks(inputObject, outputObject); + } + + /** + * 文件分块上传检测是否上传 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUploadFileChunksByChunkMd5", value = "文件分块上传检测是否上传", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "md5", name = "md5", value = "文件唯一标示", required = "required"), + @ApiImplicitParam(id = "chunk", name = "chunk", value = "分块上传,块下标", required = "required"), + @ApiImplicitParam(id = "chunkSize", name = "chunkSize", value = "分块上传时,块的大小,用于最后合并", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryUploadFileChunksByChunkMd5") + public void queryUploadFileChunksByChunkMd5(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryUploadFileChunksByChunkMd5(inputObject, outputObject); + } + + /** + * 根据id查询文件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFileConsoleById", value = "根据id查询文件信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryFileConsoleById") + public void queryFileConsoleById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.selectById(inputObject, outputObject); + } + + /** + * office文件编辑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole010", value = "office文件编辑", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "key", name = "key", value = "定义服务用于文档识别的唯一文档标识符", required = "required"), + @ApiImplicitParam(id = "url", name = "url", value = "定义存储源查看或编辑文档的绝对URL", required = "required"), + @ApiImplicitParam(id = "status", name = "status", value = "状态", required = "required")}) + @RequestMapping(value = "/post/FileConsoleController/editUploadOfficeFileById", method = RequestMethod.POST) + public void editUploadOfficeFileById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.editUploadOfficeFileById(inputObject, outputObject); + } + + /** + * 根据当前用户获取总文件大小 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllFileSizeByUserId", value = "根据当前用户获取总文件大小", method = "GET", allUse = "2") + @RequestMapping("/post/FileConsoleController/queryAllFileSizeByUserId") + public void queryAllFileSizeByUserId(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryAllFileSizeByUserId(inputObject, outputObject); + } + + /** + * 分享文件保存 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole023", value = "分享文件保存", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertShareFileListToSave") + public void insertShareFileListToSave(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertShareFileListToSave(inputObject, outputObject); + } + + /** + * 文档在线预览 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole024", value = "文档在线预览", method = "GET", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryFileToShowById") + public void queryFileToShowById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryFileToShowById(inputObject, outputObject); + } + + /** + * 创建空文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createFileToService", value = "创建空文件", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "type", name = "type", value = "文件类型", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/createFileToService") + public void createFileToService(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.createFileToService(inputObject, outputObject); + } + + /** + * 创建副本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole030", value = "创建副本", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertDuplicateCopyToService") + public void insertDuplicateCopyToService(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertDuplicateCopyToService(inputObject, outputObject); + } + + /** + * 获取文件属性 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole031", value = "获取文件属性", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryFileMationById") + public void queryFileMationById(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryFileMationById(inputObject, outputObject); + } + + /** + * 文件打包 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole032", value = "文件打包", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertFileMationToPackageToFolder") + public void insertFileMationToPackageToFolder(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertFileMationToPackageToFolder(inputObject, outputObject); + } + + /** + * 压缩包解压 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole033", value = "压缩包解压", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertFileMationPackageToFolder") + public void insertFileMationPackageToFolder(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertFileMationPackageToFolder(inputObject, outputObject); + } + + /** + * 文件或者文件夹复制 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole034", value = "文件或者文件夹复制", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertPasteCopyToService") + public void insertPasteCopyToService(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertPasteCopyToService(inputObject, outputObject); + } + + /** + * 文件或者文件夹剪切 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole035", value = "文件或者文件夹剪切", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertPasteCutToService") + public void insertPasteCutToService(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertPasteCutToService(inputObject, outputObject); + } + + /** + * office文件编辑获取修改时间作为最新的key + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole036", value = "office文件编辑获取修改时间作为最新的key", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConsoleController/queryOfficeUpdateTimeToKey") + public void queryOfficeUpdateTimeToKey(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryOfficeUpdateTimeToKey(inputObject, outputObject); + } + + /** + * 文件统计报表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole037", value = "文件统计报表", method = "GET", allUse = "2") + @RequestMapping("/post/FileConsoleController/queryFileNumStatistics") + public void queryFileNumStatistics(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.queryFileNumStatistics(inputObject, outputObject); + } + + /** + * 文件打包下载 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole038", value = "文件打包下载", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jsonStr", name = "jsonStr", value = "保存的文件数组", required = "required")}) + @RequestMapping("/post/FileConsoleController/insertFileMationToPackageDownload") + public void insertFileMationToPackageDownload(InputObject inputObject, OutputObject outputObject) { + fileConsoleService.insertFileMationToPackageDownload(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileRecycleBinController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileRecycleBinController.java new file mode 100644 index 0000000..80e6e7b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileRecycleBinController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.service.FileRecycleBinService; +import com.skyeye.eve.diskcloud.entity.FileRecycleBin; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FileRecycleBinController + * @Description: 回收站控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 22:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "回收站管理", tags = "回收站管理", modelName = "回收站管理") +public class FileRecycleBinController { + + @Autowired + private FileRecycleBinService fileRecycleBinService; + + /** + * 加入回收站 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertFileCatalogToRecycle", value = "加入回收站", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = FileRecycleBin.class) + @RequestMapping("/post/FileRecycleBinController/insertFileCatalogToRecycle") + public void insertFileCatalogToRecycle(InputObject inputObject, OutputObject outputObject) { + fileRecycleBinService.createEntity(inputObject, outputObject); + } + + /** + * 我的回收站 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole014", value = "我的回收站", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FileRecycleBinController/queryFileRecycleBinList") + public void queryFileRecycleBinList(InputObject inputObject, OutputObject outputObject) { + fileRecycleBinService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id从回收站删除数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFileRecycleBinById", value = "根据id从回收站删除数据", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileRecycleBinController/deleteFileRecycleBinById") + public void deleteFileRecycleBinById(InputObject inputObject, OutputObject outputObject) { + fileRecycleBinService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileShareController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileShareController.java new file mode 100644 index 0000000..946867e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/controller/FileShareController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.entity.FileShare; +import com.skyeye.eve.diskcloud.service.FileShareService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FileShareController + * @Description: 文件分享控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/18 11:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "文件分享管理", tags = "文件分享管理", modelName = "文件分享管理") +public class FileShareController { + + @Autowired + private FileShareService fileShareService; + + /** + * 文件分享 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertFileToShare", value = "文件分享", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = FileShare.class) + @RequestMapping("/post/FileShareController/insertFileToShare") + public void insertFileToShare(InputObject inputObject, OutputObject outputObject) { + fileShareService.createEntity(inputObject, outputObject); + } + + /** + * 文件分享列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShareFileList", value = "我的文件分享列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FileShareController/queryShareFileList") + public void queryShareFileList(InputObject inputObject, OutputObject outputObject) { + fileShareService.queryPageList(inputObject, outputObject); + } + + /** + * 删除文件分享外链 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShareFileById", value = "删除文件分享外链", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileShareController/deleteShareFileById") + public void deleteShareFileById(InputObject inputObject, OutputObject outputObject) { + fileShareService.deleteById(inputObject, outputObject); + } + + /** + * 文件共享输入密码时获取文件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShareFileMationById", value = "文件共享输入密码时获取文件信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileShareController/queryShareFileMationById") + public void queryShareFileMationById(InputObject inputObject, OutputObject outputObject) { + fileShareService.queryShareFileMationById(inputObject, outputObject); + } + + /** + * 文件共享输入密码时校验 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole020", value = "文件共享输入密码时校验", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "sharePassword", name = "sharePassword", value = "密码", required = "required")}) + @RequestMapping("/post/FileShareController/checkShareFilePwdMation") + public void checkShareFilePwdMation(InputObject inputObject, OutputObject outputObject) { + fileShareService.checkShareFilePwdMation(inputObject, outputObject); + } + + /** + * 获取分享文件基础信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole021", value = "获取分享文件基础信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileShareController/queryShareFileBaseMationById") + public void queryShareFileBaseMationById(InputObject inputObject, OutputObject outputObject) { + fileShareService.selectById(inputObject, outputObject); + } + + /** + * 根据父id获取该id下分享的文件和文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fileconsole022", value = "根据父id获取该id下分享的文件和文件夹", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "folderId", name = "folderId", value = "文件夹id", required = "required")}) + @RequestMapping("/post/FileShareController/queryShareFileListByParentId") + public void queryShareFileListByParentId(InputObject inputObject, OutputObject outputObject) { + fileShareService.queryShareFileListByParentId(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileCatalogDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileCatalogDao.java new file mode 100644 index 0000000..5c939cd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileCatalogDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileCatalogDao + * @Description: 文件夹管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 11:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileCatalogDao extends SkyeyeBaseMapper { + + List> queryFolderAndChildList(@Param("ids") List ids, @Param("deleteFlag") Integer deleteFlag); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileConsoleDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileConsoleDao.java new file mode 100644 index 0000000..e25f138 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileConsoleDao.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.diskcloud.entity.FileConsole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileConsoleDao + * @Description: 文件管库数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 17:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileConsoleDao extends SkyeyeBaseMapper { + + List> queryFileFolderByUserIdAndParentId(Map map); + + List> queryFilesListByFolderId(Map map); + + List> queryChildFileListByFolder(@Param("list") List> folderNew, + @Param("deleteFlag") Integer deleteFlag); + + int insertFolderList(List> folderNew); + + int insertShareFileListByList(List> fileNew); + + List> queryShareFileListByFileList(@Param("ids") List ids, + @Param("deleteFlag") Integer deleteFlag); + + Map queryAllNumFile(@Param("deleteFlag") Integer deleteFlag); + + Map queryAllNumFileToday(@Param("deleteFlag") Integer deleteFlag); + + Map queryAllNumFileThisWeek(@Param("deleteFlag") Integer deleteFlag); + + List> queryFileTypeNum(@Param("deleteFlag") Integer deleteFlag); + + List> queryFileStorageNum(@Param("deleteFlag") Integer deleteFlag); + + List> queryNewFileNum(@Param("deleteFlag") Integer deleteFlag); + + List> queryFileTypeNumSevenDay(@Param("deleteFlag") Integer deleteFlag); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileRecycleBinDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileRecycleBinDao.java new file mode 100644 index 0000000..e28f1a3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileRecycleBinDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.diskcloud.entity.FileRecycleBin; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileRecycleBinDao + * @Description: 回收站数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 22:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileRecycleBinDao extends SkyeyeBaseMapper { + + List> queryFileRecycleBinList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileShareDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileShareDao.java new file mode 100644 index 0000000..5f2024b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/dao/FileShareDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.diskcloud.entity.FileShare; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileShareDao + * @Description: 文件分享数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/18 11:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileShareDao extends SkyeyeBaseMapper { + + List> queryShareFileList(CommonPageInfo pageInfo); + + List> queryShareFileFirstListByParentId(@Param("id") String id); + + List> queryShareFileListByParentId(@Param("folderId") String folderId, + @Param("deleteFlag") Integer deleteFlag); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileCatalog.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileCatalog.java new file mode 100644 index 0000000..78ffc7e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileCatalog.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: FileCatalog + * @Description: 文件夹实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 11:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "file_catalog") +@RedisCacheField(name = "file:catalog", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel("文件夹实体类") +public class FileCatalog extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "文件夹名称", required = "required") + private String name; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "所属目录", required = "required") + private String parentId; + + @TableField(value = "source_id") + @ApiModelProperty(value = "来源id") + private String sourceId; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @Property("文件夹logo") + private String logoPath; + + @TableField(exist = false) + @Property("文件夹") + private String type; + + @TableField(exist = false) + @Property("转换后的文件/文件夹的大小") + private String turnSize; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileConsole.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileConsole.java new file mode 100644 index 0000000..ee28ea8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileConsole.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: FileConsole + * @Description: 文件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 12:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "file_catelog_papers") +@RedisCacheField(name = "file:console", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel("文件实体类") +public class FileConsole extends OperatorUserInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @Property(value = "文件名称") + private String name; + + @TableField(value = "thumbnail") + @Property(value = "文件缩略图") + private String thumbnail; + + @TableField(value = "address") + @Property(value = "文件地址") + private String address; + + @TableField(value = "type") + @Property(value = "文件类型,参考#FileType") + private String type; + + @TableField(value = "size") + @Property(value = "文件大小") + private Integer size; + + @TableField(value = "size_type") + @Property(value = "文件大小单位 bytes") + private String sizeType; + + @TableField(value = "chunk") + @Property(value = "分块上传,块下标") + private Integer chunk; + + @TableField(value = "chunk_size") + @Property(value = "分块上传时,块的大小,用于最后合并") + private String chunkSize; + + @TableField(value = "file_md5") + @Property(value = "文件唯一标示") + private String fileMd5; + + @TableField(value = "parent_id") + @Property(value = "所属目录") + private String parentId; + + @TableField(value = "source_id") + @Property(value = "来源id") + private String sourceId; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @Property("转换后的文件/文件夹的大小") + private String turnSize; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileRecycleBin.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileRecycleBin.java new file mode 100644 index 0000000..8a36ab4 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileRecycleBin.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: FileRecycleBin + * @Description: 回收站实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 21:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "file_catelog_recycle_bin") +@RedisCacheField(name = "file:recycleBin", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel("回收站实体类") +public class FileRecycleBin extends OperatorUserInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "file_id") + @ApiModelProperty(value = "文件或文件夹id", required = "required") + private String fileId; + + @TableField(value = "file_type") + @Property(value = "文件类型,参考#DickCloudType") + private String fileType; + + @TableField(value = "file_name") + @Property(value = "文件或文件夹的名称") + private String fileName; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileShare.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileShare.java new file mode 100644 index 0000000..935cc68 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/entity/FileShare.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: FileShare + * @Description: 文件分享实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/18 11:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "file_catalog_share") +@RedisCacheField(name = "file:share", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel("文件分享实体类") +public class FileShare extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "file_id") + @ApiModelProperty(value = "文件或文件夹id", required = "required") + private String fileId; + + @TableField(value = "file_type") + @Property(value = "文件类型,参考#DickCloudType") + private String fileType; + + @TableField(value = "share_name") + @Property(value = "分享名称") + private String shareName; + + @TableField(value = "share_code") + @Property(value = "分享code 唯一性") + private String shareCode; + + @TableField(value = "share_url") + @Property(value = "分享链接") + private String shareUrl; + + @TableField(value = "share_type") + @ApiModelProperty(value = "分享类型,参考#ShareType", required = "required,num") + private Integer shareType; + + @TableField(value = "share_password") + @Property(value = "如果是私密分享,则是分享秘钥") + private String sharePassword; + + @TableField(value = "state") + @Property(value = "分享状态,参考#ShareState") + private Integer state; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileCatalogService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileCatalogService.java new file mode 100644 index 0000000..bdb1f25 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileCatalogService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.diskcloud.entity.FileCatalog; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileCatalogService + * @Description: 文件夹管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 11:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileCatalogService extends SkyeyeBusinessService { + + void deleteByParentId(String parentId); + + void editNameById(String id, String name, String userId); + + String setParentId(String id); + + List> queryFolderAndChildList(List ids); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileConsoleService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileConsoleService.java new file mode 100644 index 0000000..b4ebf81 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileConsoleService.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.diskcloud.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.entity.FileConsole; + +/** + * @ClassName: FileConsoleService + * @Description: 文件管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 17:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileConsoleService extends SkyeyeBusinessService { + + void editNameById(String id, String name, String userId); + + void queryFileFolderByUserId(InputObject inputObject, OutputObject outputObject); + + void queryFilesListByFolderId(InputObject inputObject, OutputObject outputObject); + + void deleteFileFolderById(InputObject inputObject, OutputObject outputObject); + + void editFileFolderById(InputObject inputObject, OutputObject outputObject); + + void insertUploadFile(InputObject inputObject, OutputObject outputObject); + + void insertUploadFileChunks(InputObject inputObject, OutputObject outputObject); + + void queryUploadFileChunksByChunkMd5(InputObject inputObject, OutputObject outputObject); + + void editUploadOfficeFileById(InputObject inputObject, OutputObject outputObject); + + void queryAllFileSizeByUserId(InputObject inputObject, OutputObject outputObject); + + void insertShareFileListToSave(InputObject inputObject, OutputObject outputObject); + + void queryFileToShowById(InputObject inputObject, OutputObject outputObject); + + void createFileToService(InputObject inputObject, OutputObject outputObject); + + void insertDuplicateCopyToService(InputObject inputObject, OutputObject outputObject); + + void queryFileMationById(InputObject inputObject, OutputObject outputObject); + + void insertFileMationToPackageToFolder(InputObject inputObject, OutputObject outputObject); + + void insertFileMationPackageToFolder(InputObject inputObject, OutputObject outputObject); + + void insertPasteCopyToService(InputObject inputObject, OutputObject outputObject); + + void insertPasteCutToService(InputObject inputObject, OutputObject outputObject); + + void queryOfficeUpdateTimeToKey(InputObject inputObject, OutputObject outputObject); + + void queryFileNumStatistics(InputObject inputObject, OutputObject outputObject); + + void insertFileMationToPackageDownload(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileRecycleBinService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileRecycleBinService.java new file mode 100644 index 0000000..fcfa367 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileRecycleBinService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.diskcloud.entity.FileRecycleBin; + +/** + * @ClassName: FileRecycleBinService + * @Description: 回收站服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 22:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileRecycleBinService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileShareService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileShareService.java new file mode 100644 index 0000000..db45ead --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/FileShareService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.diskcloud.entity.FileShare; + +/** + * @ClassName: FileShareService + * @Description: 文件分享服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/18 11:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FileShareService extends SkyeyeBusinessService { + + void queryShareFileMationById(InputObject inputObject, OutputObject outputObject); + + void checkShareFilePwdMation(InputObject inputObject, OutputObject outputObject); + + void queryShareFileListByParentId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileCatalogServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileCatalogServiceImpl.java new file mode 100644 index 0000000..50125de --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileCatalogServiceImpl.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.diskcloud.classenum.DefaultFolder; +import com.skyeye.eve.diskcloud.dao.FileCatalogDao; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import com.skyeye.eve.diskcloud.service.FileCatalogService; +import com.skyeye.exception.CustomException; +import com.skyeye.constans.DiskCloudConstants; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: FileCatalogServiceImpl + * @Description: 文件夹管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 11:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "文件夹管理", groupName = "文件夹管理") +public class FileCatalogServiceImpl extends SkyeyeBusinessServiceImpl implements FileCatalogService { + + @Override + public void createPrepose(FileCatalog entity) { + String parentId = setParentId(entity.getParentId()); + entity.setParentId(parentId); + entity.setLogoPath(DiskCloudConstants.SYS_FILE_CONSOLE_IS_FOLDER_LOGO_PATH); + } + + @Override + protected void deletePreExecution(FileCatalog entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!StrUtil.equals(entity.getCreateId(), userId)) { + throw new CustomException("无法删除不是自己创建的文件夹"); + } + } + + @Override + public void deleteByParentId(String parentId) { + // 先查询,删除对应的缓存信息 + List childIds = queryByParentId(parentId); + + String userId = InputObject.getLogParamsStatic().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(FileCatalog::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getDeleteFlag), DeleteFlagEnum.DELETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + + refreshCache(childIds); + } + + private List queryByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(FileCatalog::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileCatalog::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List fileCatalogs = list(queryWrapper); + return fileCatalogs.stream().map(FileCatalog::getId).collect(Collectors.toList()); + } + + @Override + public void editNameById(String id, String name, String userId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getName), name); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileCatalog::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(id); + } + + @Override + public String setParentId(String id) { + if (DefaultFolder.FAVORITES.getKey().equals(id) + || DefaultFolder.FOLDER.getKey().equals(id) + || DefaultFolder.SKYDRIVE.getKey().equals(id)) { + // 收藏夹 我的文档 企业网盘 + return id + ","; + } else { + // 根据当前所属目录查询该目录的父id + FileCatalog parentCatalog = selectById(id); + if (ObjectUtil.isNotEmpty(parentCatalog) && StrUtil.isNotEmpty(parentCatalog.getId())) { + return parentCatalog.getParentId() + id + ","; + } else { + throw new CustomException("所属文件夹不存在"); + } + } + } + + @Override + public List> queryFolderAndChildList(List ids) { + return skyeyeBaseMapper.queryFolderAndChildList(ids, DeleteFlagEnum.NOT_DELETE.getKey()); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileConsoleServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileConsoleServiceImpl.java new file mode 100644 index 0000000..f3f12a5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileConsoleServiceImpl.java @@ -0,0 +1,1372 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.artofsolving.jodconverter.DocumentConverter; +import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection; +import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection; +import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.BytesUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.diskcloud.classenum.DefaultFolder; +import com.skyeye.eve.diskcloud.classenum.DickCloudType; +import com.skyeye.eve.diskcloud.classenum.FileType; +import com.skyeye.eve.diskcloud.classenum.FolderType; +import com.skyeye.eve.diskcloud.dao.FileConsoleDao; +import com.skyeye.eve.diskcloud.service.FileCatalogService; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import com.skyeye.eve.diskcloud.entity.FileConsole; +import com.skyeye.eve.diskcloud.service.FileConsoleService; +import com.skyeye.exception.CustomException; +import nl.siegmann.epublib.domain.Book; +import nl.siegmann.epublib.domain.Resource; +import nl.siegmann.epublib.epub.EpubReader; +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.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import javax.imageio.stream.FileImageOutputStream; +import java.io.*; +import java.net.URL; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +/** + * @ClassName: FileConsoleServiceImpl + * @Description: 文件管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "文件管理", groupName = "文件管理") +public class FileConsoleServiceImpl extends SkyeyeBusinessServiceImpl implements FileConsoleService { + + @Autowired + private FileCatalogService fileCatalogService; + + @Autowired + private FileConsoleDao fileConsoleDao; + + /** + * 文件上传时保存文件的路径 + */ + private static final Integer FILE_PATH_TYPE = FileConstants.FileUploadPath.FILE_CONSOLE.getType()[0]; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Value("${server.port}") + private String sysPort; + + private static final Logger LOGGER = LoggerFactory.getLogger(FileConsoleServiceImpl.class); + + /** + * 删除文件 + * + * @param fileAddress 文件地址 + * @param fileThumbnail 文件缩略图地址 + * @param fileType 文件类型 + */ + public void deleteFileByMation(String fileAddress, String fileThumbnail, String fileType) { + FileUtil.deleteFile(fileAddress); + FileUtil.deleteFile(fileThumbnail);//删除缩略图 + if (FileType.judgeIsAllowedFileType(fileType, 5)) {//ace文件 + FileUtil.deleteFile(fileAddress.substring(0, fileAddress.lastIndexOf(".")) + ".pdf");//删除ace转换文件 + } + } + + /** + * 根据当前用户获取目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFileFolderByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 父目录id + String parentId = map.get("parentId").toString(); + if (ToolUtil.isBlank(parentId) || "0".equals(parentId)) { + // 加载一级目录,缓存30天 + List> beans = DefaultFolder.getFileConsoleISDefaultFolder(); + outputObject.setBeans(beans); + } else { + // 加载子目录 + String userId = inputObject.getLogParams().get("id").toString(); + map.put("folderType", this.getFolderType(parentId)); + map.put("userId", userId); + map.put("deleteFlag", DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = fileConsoleDao.queryFileFolderByUserIdAndParentId(map); + outputObject.setBeans(beans); + } + } + + private Integer getFolderType(String folderId) { + if (DefaultFolder.SKYDRIVE.getKey().equals(folderId)) { + // 企业网盘 + return FolderType.COMPANY.getKey(); + } else { + FileCatalog fileCatalog = fileCatalogService.selectById(folderId); + if (ObjectUtil.isNotEmpty(fileCatalog) && StrUtil.isNotEmpty(fileCatalog.getId())) { + if (fileCatalog.getParentId().indexOf("3,") == 0) { + // 企业网盘 + return FolderType.COMPANY.getKey(); + } else { + // 私人 + return FolderType.PERSONER.getKey(); + } + } else { + // 私人 + return FolderType.PERSONER.getKey(); + } + } + } + + /** + * 获取这个目录下的所有文件+目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFilesListByFolderId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + String folderId = map.get("folderId").toString(); + map.put("folderType", this.getFolderType(folderId)); + map.put("deleteFlag", DeleteFlagEnum.NOT_DELETE.getKey()); + this.setOrderByParams(map); + List> beans = fileConsoleDao.queryFilesListByFolderId(map); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + for (Map bean : beans) { + if (!DickCloudType.FOLDER.getKey().equals(bean.get("type").toString())) { + // 不是文件夹 + String size = BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("size").toString())); + bean.put("size", size); + } + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 设置排序字段 + * + * @param map + */ + private void setOrderByParams(Map map) { + String orderBy = map.get("orderBy").toString(); + if (ToolUtil.isBlank(orderBy)) { + map.put("orderByStr", " k.orderBy ASC, k.`name` ASC"); + } else { + if ("1".equals(orderBy)) { + map.put("orderByStr", " k.`name` ASC"); + } else if ("2".equals(orderBy)) { + map.put("orderByStr", " k.createTime DESC"); + } else if ("3".equals(orderBy)) { + map.put("orderByStr", " k.orderBy ASC, k.`name` ASC"); + } else if ("4".equals(orderBy)) { + map.put("orderByStr", " k.size DESC"); + } + } + map.remove("orderBy"); + } + + /** + * 删除目录以及目录下的所有文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteFileFolderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 获取要删除的文件 + String fileList = map.get("fileList").toString(); + List> array = JSONUtil.toList(fileList, null); + // 文件访问基础路径 + String basePath = tPath.replace("images", ""); + for (int i = 0; i < array.size(); i++) { + // 获取id和fileType + String id = array.get(i).get("id").toString(); + String fileType = array.get(i).get("fileType").toString(); + if (DickCloudType.FOLDER.getKey().equals(fileType)) { + // 删除自身目录 + fileCatalogService.deleteById(id); + // 目录下的子文件 + List files = queryByParentId(id); + for (FileConsole file : files) { + // 删除文件 + deleteFileByMation(basePath + file.getAddress(), basePath + file.getThumbnail(), file.getType()); + } + // 删除子文件 + deleteByParentId(id); + List childIds = files.stream().map(FileConsole::getId).collect(Collectors.toList()); + refreshCache(childIds); + // 删除子文件夹 + fileCatalogService.deleteByParentId(id); + } else { + // 操作文件表 + FileConsole fileConsole = selectById(id); + if (ObjectUtil.isNotEmpty(fileConsole) && StrUtil.isNotEmpty(fileConsole.getId())) { + // 删除文件 + deleteFileByMation(basePath + fileConsole.getAddress(), basePath + fileConsole.getThumbnail(), fileConsole.getType()); + deleteById(id); + } + } + } + } + + private List queryByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(FileConsole::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + return list(queryWrapper); + } + + private void deleteByParentId(String parentId) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(FileConsole::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getDeleteFlag), DeleteFlagEnum.DELETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + /** + * 编辑目录名称 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editFileFolderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + String name = map.get("name").toString(); + String fileType = map.get("fileType").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (DickCloudType.FOLDER.getKey().equals(fileType)) { + // 操作目录表 + fileCatalogService.editNameById(id, name, userId); + } else { + //操作文件表 + editNameById(id, name, userId); + } + } + + @Override + public void editNameById(String id, String name, String userId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getName), name); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(id); + } + + /** + * 上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertUploadFile(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器) + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(PutObject.getRequest().getSession().getServletContext()); + // 检查form中是否有enctype="multipart/form-data" + if (multipartResolver.isMultipart(PutObject.getRequest())) { + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + // 将request变成多部分request + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) PutObject.getRequest(); + // 获取multiRequest 中所有的文件名 + Iterator iter = multiRequest.getFileNames(); + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/" + userId; + while (iter.hasNext()) { + // 一次遍历所有文件 + MultipartFile file = multiRequest.getFile(iter.next().toString()); + String fileName = file.getOriginalFilename();// 文件名称 + //得到文件扩展名 + String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); + if (file != null) { + FileUtil.createDirs(basePath); + // 自定义的文件名称 + String newFileName = System.currentTimeMillis() + "." + fileExtName; + String path = basePath + "/" + newFileName; + // 上传 + try { + file.transferTo(new File(path)); + } catch (IOException e) { + throw new CustomException(e); + } + FileConsole fileConsole = new FileConsole(); + fileConsole.setName(map.get("name").toString()); + fileConsole.setSize(Integer.parseInt(map.get("size").toString())); + fileConsole.setParentId(fileCatalogService.setParentId(map.get("folderId").toString())); + fileConsole.setFileMd5(map.get("md5").toString()); + fileConsole.setChunk(Integer.parseInt(map.get("chunk").toString())); + fileConsole.setChunkSize(map.get("chunkSize").toString()); + fileConsole.setType(fileExtName); + fileConsole.setSizeType("bytes"); + String trueFileName = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId + "/" + newFileName; + fileConsole.setAddress(trueFileName); + fileConsole.setThumbnail("-1"); + createEntity(fileConsole, userId); + } + } + } + } + + /** + * 上传文件合并块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertUploadFileChunks(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String md5 = map.get("md5").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + List fileConsoleList = queryFileByMd5(md5); + List fileList = getFileList(fileConsoleList); + String name = map.get("name").toString(); + // 文件后缀 + String fileExtName = name.substring(name.lastIndexOf(".") + 1).toLowerCase(); + // 新文件名 + String newFileName = System.currentTimeMillis() + "." + fileExtName; + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE); + // 文件路径 + String path = basePath + "/" + userId + "/" + newFileName; + FileChannel outChnnel = null; + try { + File outputFile = new File(path); + // 创建文件 + outputFile.createNewFile(); + // 输出流 + outChnnel = new FileOutputStream(outputFile).getChannel(); + // 合并 + FileChannel inChannel; + for (File file : fileList) { + inChannel = new FileInputStream(file).getChannel(); + inChannel.transferTo(0, inChannel.size(), outChnnel); + inChannel.close(); + // 删除分片 + file.delete(); + } + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.close(outChnnel); + } + deleteByMd5(md5); + refreshCache(fileConsoleList.stream().map(FileConsole::getId).collect(Collectors.toList())); + + FileConsole fileConsole = new FileConsole(); + fileConsole.setName(name); + fileConsole.setSize(Integer.parseInt(map.get("size").toString())); + fileConsole.setParentId(fileCatalogService.setParentId(map.get("folderId").toString())); + fileConsole.setChunkSize(map.get("size").toString()); + fileConsole.setType(fileExtName); + fileConsole.setSizeType("bytes"); + String trueFileName = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId + "/" + newFileName; + fileConsole.setAddress(trueFileName); + fileConsole.setThumbnail(getThumbnail(userId, fileExtName, basePath, path, trueFileName)); + createEntity(fileConsole, userId); + } + + private String getThumbnail(String userId, String fileExtName, String basePath, String path, String trueFileName) { + if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_ONE)) { + // 图片 + return trueFileName; + } else if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_SIX)) { + // 电子书 + String picName = System.currentTimeMillis() + ".jpg"; + String newFilename = basePath + "/" + userId + "/" + picName; + writeAndReadQpubFileThumbnail(path, newFilename); + return FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId + "/" + picName; + } else if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_TWO)) { + // office文件缩略图地址 + return FileType.getIconByFileExt(fileExtName); + } else if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_FIVE)) { + // ace文件缩略图地址 + return FileType.getIconByFileExt(fileExtName); + } else if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_THREE)) { + // 视频 + String ffmpegGPath = tPath + "/util/ffmpeg.exe"; + String fileThumbnail = System.currentTimeMillis() + ".jpg"; + FileUtil.createDirs(basePath + "/" + userId + "/ffmpeg/"); + if (ToolUtil.take(path, basePath + "/" + userId + "/ffmpeg/" + fileThumbnail, ffmpegGPath)) { + return FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId + "/ffmpeg/" + fileThumbnail; + } else { + FileUtil.deleteFile(path); + throw new CustomException("上传失败。"); + } + } else if (FileType.judgeIsAllowedFileType(fileExtName, CommonNumConstants.NUM_FOUR)) { + // 压缩包 + return "../../assets/images/rar.png"; + } else { + // 其他 + return "../../assets/images/cloud/other-icon.png"; + } + } + + private List queryFileByMd5(String md5) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getFileMd5), md5); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(FileConsole::getChunk)); + return list(queryWrapper); + } + + private List getFileList(List fileConsoles) { + List fileList = new ArrayList<>(); + for (FileConsole bean : fileConsoles) { + File f = new File(tPath.replace("images", StrUtil.EMPTY) + bean.getAddress()); + fileList.add(f); + } + return fileList; + } + + private void deleteByMd5(String md5) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getFileMd5), md5); + remove(queryWrapper); + } + + /** + * 文件分块上传检测是否上传 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void queryUploadFileChunksByChunkMd5(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String md5 = map.get("md5").toString(); + String chunk = map.get("chunk").toString(); + // 根据块进行查询 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getFileMd5), md5); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getChunk), chunk); + FileConsole fileConsole = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(fileConsole) && StrUtil.isNotEmpty(fileConsole.getId())) { + String fileAddress = tPath.replace("images", StrUtil.EMPTY) + fileConsole.getAddress(); + File checkFile = new File(fileAddress); + String chunkSize = map.get("chunkSize").toString(); + if (checkFile.exists() && checkFile.length() == Integer.parseInt(chunkSize)) { + } else { + // 删除块 + QueryWrapper queryWrapper1 = new QueryWrapper<>(); + queryWrapper1.eq(MybatisPlusUtil.toColumns(FileConsole::getFileMd5), md5); + queryWrapper1.eq(MybatisPlusUtil.toColumns(FileConsole::getChunk), chunk); + remove(queryWrapper1); + outputObject.setreturnMessage("文件上传失败"); + } + } else { + outputObject.setreturnMessage("文件上传失败"); + } + } + + /** + * office文件编辑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUploadOfficeFileById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + int status = Integer.parseInt(map.get("status").toString()); + // 当我们关闭编辑窗口后,十秒钟左右onlyoffice会将它存储的我们的编辑后的文件,,此时status = 2 + if (status == 2 || status == 3) {//MustSave, Corrupted + String id = map.get("key").toString().split("-")[0]; + try { + // 新文件地址 + URL url = new URL(map.get("url").toString()); + java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection(); + InputStream stream = connection.getInputStream(); + if (stream == null) { + outputObject.setreturnMessage("Stream is null"); + return; + } + // 从请求中获取要覆盖的文件参数定义"path" + FileConsole fileConsole = selectById(id); + String fileAddress = tPath.replace("images", StrUtil.EMPTY) + fileConsole.getAddress(); + File savedFile = new File(fileAddress); + try (FileOutputStream out = new FileOutputStream(savedFile)) { + int read; + final byte[] bytes = new byte[1024]; + while ((read = stream.read(bytes)) != -1) { + out.write(bytes, 0, read); + } + out.flush(); + } + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConsole::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(id); + + connection.disconnect(); + outputObject.setErroCode(1); + } catch (Exception e) { + throw new CustomException(e); + } + } + } + + /** + * 根据当前用户获取总文件大小 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllFileSizeByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + + // 查询当前登陆人的【我的文档】下的所有未删除的文件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(FileConsole::getParentId) + ", ','), CONCAT(',', {0}, ','))", DefaultFolder.FOLDER.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileConsole::getCreateId), userId); + List fileConsoles = list(queryWrapper); + + if (CollectionUtil.isNotEmpty(fileConsoles)) { + long sum = fileConsoles.stream().mapToLong(FileConsole::getSize).sum(); + String size = BytesUtil.sizeFormatNum2String(sum); + map.put("size", size); + } else { + map.clear(); + map.put("size", "0KB"); + } + outputObject.setBean(map); + } + + /** + * 分享文件保存 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertShareFileListToSave(InputObject inputObject, OutputObject outputObject) { + setCopyFileMation(inputObject); + } + + private void setCopyFileMation(InputObject inputObject) { + Map map = inputObject.getParams(); + List> array = JSONUtil.toList(map.get("jsonStr").toString(), null);//获取数据信息 + String userId = inputObject.getLogParams().get("id").toString(); + String folderId = fileCatalogService.setParentId(map.get("folderId").toString()); + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/" + userId; + String visitPath = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId; + List folderBeans = new ArrayList<>(); + List fileBeans = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + Map object = array.get(i); + if (DickCloudType.FOLDER.getKey().equals(object.get("rowType").toString())) {//文件夹 + folderBeans.add(object.get("rowId").toString()); + } else { + fileBeans.add(object.get("rowId").toString()); + } + } + if (!folderBeans.isEmpty()) {//选择保存的文件夹不为空 + List> folderNew = fileCatalogService.queryFolderAndChildList(folderBeans); + List> fileNew = skyeyeBaseMapper.queryChildFileListByFolder(folderNew, DeleteFlagEnum.NOT_DELETE.getKey()); + for (Map folder : folderNew) {//重置父id + String[] str = folder.get("parentId").toString().split(","); + folder.put("directParentId", str[str.length - 1]); + folder.put("newId", ToolUtil.getSurFaceId()); + } + //将数据转化为树的形式,方便进行父id重新赋值 + folderNew = ToolUtil.listToTree(folderNew, "id", "directParentId", "children"); + ToolUtil.FileListParentISEdit(folderNew, folderId);//替换父id + folderNew = ToolUtil.FileTreeTransList(folderNew);//将树转为list + for (Map folder : folderNew) { + folder.put("createId", userId); + folder.put("createTime", DateUtil.getTimeAndToString()); + } + //为文件重置新parentId参数 + for (Map folder : folderNew) { + String parentId = folder.get("parentId").toString() + folder.get("id").toString() + ","; + String newParentId = folder.get("newParentId").toString() + folder.get("newId").toString() + ","; + for (Map file : fileNew) { + if (parentId.equals(file.get("parentId").toString())) { + file.put("newParentId", newParentId); + } + } + } + //为文件重置新参数 + for (Map file : fileNew) { + setCopyFileMation(userId, basePath, visitPath, file); + } + if (!folderNew.isEmpty()) { + fileConsoleDao.insertFolderList(folderNew); + } + if (!fileNew.isEmpty()) { + fileConsoleDao.insertShareFileListByList(fileNew); + } + } + if (!fileBeans.isEmpty()) {//选择保存的文件不为空 + List> fileNew = fileConsoleDao.queryShareFileListByFileList(fileBeans, DeleteFlagEnum.NOT_DELETE.getKey()); + //为文件重置新参数 + for (Map file : fileNew) { + file.put("newParentId", folderId); + setCopyFileMation(userId, basePath, visitPath, file); + } + fileConsoleDao.insertShareFileListByList(fileNew); + } + } + + private void setCopyFileMation(String userId, String basePath, String visitPath, Map file) { + file.put("newId", ToolUtil.getSurFaceId()); + file.put("createId", userId); + file.put("createTime", DateUtil.getTimeAndToString()); + String fileExtName = file.get("type").toString().toLowerCase(); + String newFileName = System.currentTimeMillis() + "." + fileExtName;//新文件名 + String path = basePath + "/" + newFileName;//文件新路径 + String oldPath = tPath.replace("images", "") + file.get("address").toString();//原始路径 + String trueFileName = visitPath + "/" + newFileName;//数据库存储路径 + file.put("address", trueFileName); + if (FileType.judgeIsAllowedFileType(fileExtName, 1)) {//图片 + file.put("thumbnail", trueFileName);//缩略图 + } else if (FileType.judgeIsAllowedFileType(fileExtName, 6)) {//电子书 + String oldFileThumbnail = tPath.replace("images", "") + file.get("thumbnail").toString(); + String fileThunbnailName = String.valueOf(System.currentTimeMillis()); + String fileThumbnailpath = basePath + "/" + fileThunbnailName + ".png"; + file.put("thumbnail", visitPath + "/" + fileThunbnailName + ".png");//缩略图 + ToolUtil.NIOCopyFile(oldFileThumbnail, fileThumbnailpath); + } else if (FileType.judgeIsAllowedFileType(fileExtName, 3)) {//视频 + String oldFileThumbnail = tPath.replace("images", "") + file.get("thumbnail").toString(); + String fileThunbnailName = String.valueOf(System.currentTimeMillis()); + String fileThumbnailpath = basePath + "/ffmpeg/" + fileThunbnailName + ".png";//缩略图新路径 + file.put("thumbnail", visitPath + "/ffmpeg/" + fileThunbnailName + ".png");//缩略图 + ToolUtil.NIOCopyFile(oldFileThumbnail, fileThumbnailpath); + } + ToolUtil.NIOCopyFile(oldPath, path); + } + + /** + * 文档在线预览 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFileToShowById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + FileConsole fileConsole = selectById(id); + String fileType = fileConsole.getType(); + String filePath = tPath.replace("images", "") + fileConsole.getAddress();//文件路径 + + if ("txt".equals(fileType)) {//ace文件 + File docFile = new File(filePath); + File pdfFile; + if (filePath.contains(".")) { + pdfFile = new File(filePath.substring(0, filePath.lastIndexOf(".")) + ".pdf"); + } else { + pdfFile = new File(filePath + ".pdf"); + } + /*判断即将要转换的文件是否真实存在*/ + if (docFile.exists()) { + /*判断改文件是否已经被转换过,若已经转换则直接预览*/ + if (!pdfFile.exists()) { + /*打开OpenOffice连接,*/ + OpenOfficeConnection connection = new SocketOpenOfficeConnection(Integer.parseInt(sysPort)); + try { + connection.connect(); + DocumentConverter converter = new OpenOfficeDocumentConverter(connection); + converter.convert(docFile, pdfFile); + connection.disconnect(); + filePath = pdfFile.getPath(); //文件转换之后的路径 + PutObject.getResponse().setContentType("application/pdf"); + } catch (Exception e) { + LOGGER.warn("connection failed, message is {}", e); + } finally { + // 发生exception时, connection不会自动切断, 程序会一直挂着 + try { + if (connection != null) { + connection.disconnect(); + } + } catch (Exception e) { + LOGGER.warn("close connection failed, message is {}", e); + } + } + } else { + filePath = pdfFile.getPath(); //文件已经转换过 + PutObject.getResponse().setContentType("application/pdf"); + } + } else { + outputObject.setreturnMessage("需要预览的文档在服务器中不存在!"); + return; + } + } + + /*将文件写入输出流,显示在界面上,实现预览效果*/ + FileInputStream fis = null; + OutputStream os = null; + try { + fis = new FileInputStream(filePath); + os = PutObject.getResponse().getOutputStream(); + int count; + byte[] buffer = new byte[1024 * 1024]; + while ((count = fis.read(buffer)) != -1) { + os.write(buffer, 0, count); + } + if ("java".equals(fileType) || "sql".equals(fileType) || "css".equals(fileType) || "tpl".equals(fileType) + || "json".equals(fileType) || "js".equals(fileType)) { + os.write(("").getBytes()); + } + os.flush(); + } catch (IOException e) { + LOGGER.warn("write failed, message is {}", e); + } finally { + FileUtil.close(os); + FileUtil.close(fis); + } + } + + /** + * 创建空文件 + * + * @param fileExtName 文件后缀 + * @param userId 用户id + * @param folderId 所属文件夹id + */ + public void createNewFileOrFolder(String fileExtName, String userId, String folderId) { + String newFileName = System.currentTimeMillis() + "." + fileExtName;//新文件名 + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/" + userId; + FileUtil.createDirs(basePath); + String visitPath = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId; + String path = basePath + "/" + newFileName; + createFile(fileExtName, path); + + FileConsole fileConsole = new FileConsole(); + fileConsole.setName("新建文件" + "." + fileExtName); + fileConsole.setSize(CommonNumConstants.NUM_ZERO); + fileConsole.setParentId(fileCatalogService.setParentId(folderId)); + fileConsole.setChunk(CommonNumConstants.NUM_ZERO); + fileConsole.setChunkSize(CommonNumConstants.NUM_ZERO.toString()); + fileConsole.setType(fileExtName); + fileConsole.setSizeType("bytes"); + String trueFileName = visitPath + "/" + newFileName; + fileConsole.setAddress(trueFileName); + fileConsole.setThumbnail(FileType.getIconByFileExt(fileExtName)); + createEntity(fileConsole, userId); + } + + /** + * 创建文件 + * + * @param fileExtName 文件后缀 + * @param path 文件地址 + */ + private void createFile(String fileExtName, String path) { + if (FileType.OFFICE_IS_DOCX.getKey().equalsIgnoreCase(fileExtName)) { + FileUtil.createNewDocxFile(path); + } else if (FileType.OFFICE_IS_XLSX.getKey().equalsIgnoreCase(fileExtName)) { + FileUtil.createNewExcelFile(path); + } else if (FileType.OFFICE_IS_PPT.getKey().equalsIgnoreCase(fileExtName)) { + FileUtil.createNewPPtFile(path); + } else { + FileUtil.createNewSimpleFile(path); + } + } + + /** + * 新建word文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void createFileToService(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + createNewFileOrFolder(map.get("type").toString(), inputObject.getLogParams().get("id").toString(), map.get("folderId").toString()); + } + + /** + * 创建副本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertDuplicateCopyToService(InputObject inputObject, OutputObject outputObject) { + setCopyFileMation(inputObject); + } + + /** + * 获取文件属性 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFileMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + FileCatalog fileCatalog = fileCatalogService.selectById(id); + if (ObjectUtil.isNotEmpty(fileCatalog) && StrUtil.isNotEmpty(fileCatalog.getId())) { + iAuthUserService.setName(fileCatalog, "createId", "createName"); + fileCatalog.setType(DickCloudType.FOLDER.getValue()); + fileCatalog.setTurnSize("0KB"); + outputObject.setBean(fileCatalog); + } + + FileConsole fileConsole = selectById(id); + if (ObjectUtil.isNotEmpty(fileConsole) && StrUtil.isNotEmpty(fileConsole.getId())) { + iAuthUserService.setName(fileConsole, "createId", "createName"); + fileConsole.setType(DickCloudType.FILE.getValue()); + fileConsole.setTurnSize(BytesUtil.sizeFormatNum2String(fileConsole.getSize())); + outputObject.setBean(fileConsole); + } + } + + /** + * 文件打包 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertFileMationToPackageToFolder(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> array = JSONUtil.toList(map.get("jsonStr").toString(), null); + String userId = inputObject.getLogParams().get("id").toString(); + String folderId = fileCatalogService.setParentId(map.get("folderId").toString()); + List folderBeans = new ArrayList<>(); + List fileBeans = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + Map object = array.get(i); + if (DickCloudType.FOLDER.getKey().equals(object.get("rowType").toString())) {//文件夹 + folderBeans.add(object.get("rowId").toString()); + } else { + fileBeans.add(object.get("rowId").toString()); + } + } + + // 加载数据 + List> dowlLoadFile = new ArrayList<>(); + if (!folderBeans.isEmpty()) { + // 选择保存的文件夹不为空 + List> folderNew = fileCatalogService.queryFolderAndChildList(folderBeans); + List> fileNew = skyeyeBaseMapper.queryChildFileListByFolder(folderNew, DeleteFlagEnum.NOT_DELETE.getKey()); + dowlLoadFile.addAll(folderNew); + dowlLoadFile.addAll(fileNew); + } + if (!fileBeans.isEmpty()) { + // 选择保存的文件不为空 + List> fileNew = skyeyeBaseMapper.queryShareFileListByFileList(fileBeans, DeleteFlagEnum.NOT_DELETE.getKey()); + dowlLoadFile.addAll(fileNew); + } + + if (!dowlLoadFile.isEmpty()) { + for (Map folder : dowlLoadFile) { + // 重置父id + String[] str = folder.get("parentId").toString().split(","); + folder.put("directParentId", str[str.length - 1]); + } + //将数据转化为树的形式,方便进行父id重新赋值 + dowlLoadFile = ToolUtil.listToTree(dowlLoadFile, "id", "directParentId", "children"); + //打包 + String fileName = String.valueOf(System.currentTimeMillis());//压缩包文件名 + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/" + userId; + String visitPath = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId; + String strZipPath = basePath + "/" + fileName + ".zip"; + File zipFile = new File(strZipPath); + if (zipFile.exists()) { + outputObject.setreturnMessage("该文件已存在,生成失败。"); + return; + } else { + ZipOutputStream out = null; + try { + out = new ZipOutputStream(new FileOutputStream(strZipPath)); + ToolUtil.recursionZip(out, dowlLoadFile, "", tPath.replace("images", ""), 2); + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.close(out); + } + } + + FileConsole fileConsole = new FileConsole(); + fileConsole.setName("压缩文件" + "." + FileType.PACKAGE_IS_ZIP.getKey()); + fileConsole.setSize((int) zipFile.length()); + fileConsole.setParentId(folderId); + fileConsole.setChunkSize(String.valueOf(zipFile.length())); + fileConsole.setType(FileType.PACKAGE_IS_ZIP.getKey()); + fileConsole.setSizeType("bytes"); + String trueFileName = visitPath + "/" + fileName + "." + FileType.PACKAGE_IS_ZIP.getKey(); + fileConsole.setAddress(trueFileName); + fileConsole.setThumbnail("../../assets/images/rar.png"); + createEntity(fileConsole, userId); + } else { + outputObject.setreturnMessage("未找到要打包的文件."); + } + } + + /** + * 压缩包解压 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertFileMationPackageToFolder(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + FileConsole fileConsole = selectById(id); + if (FileType.judgeIsAllowedFileType(fileConsole.getType(), 4)) {//压缩包 + String userId = inputObject.getLogParams().get("id").toString(); + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/" + userId + "/"; + String visitPath = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + userId; + String zipfile = tPath.replace("images", "") + fileConsole.getAddress();//压缩包文件 + if (new File(zipfile).exists()) { + ZipEntry entry; + ZipFile zip = null; + // 封装解压后的路径 + BufferedOutputStream bos = null; + // 封装待解压文件路径 + BufferedInputStream bis = null; + List> beans = new ArrayList<>(); + try { + // 设置,默认是UTF-8 + Charset charset = Charset.forName("GBK"); + zip = new ZipFile(zipfile, charset); + Map bean; + Enumeration enums = (Enumeration) zip.entries(); + String fileName = "";//文件名称 + String fileZipPath = "";//文件路径--作为文件父id + String newSaveFileName = "";//新文件保存名称 + while (enums.hasMoreElements()) { + entry = enums.nextElement(); + bean = new HashMap<>(); + if (entry.isDirectory()) { + fileName = ToolUtil.getSubStr("/" + entry.getName(), 2);//文件名 + fileZipPath = entry.getName().replace(fileName, "");//文件路径--作为文件父id + if (ToolUtil.isBlank(fileZipPath)) { + bean.put("parentId", "0"); + } else { + bean.put("parentId", fileZipPath); + } + bean.put("originalName", entry.getName()); + bean.put("id", entry.getName()); + bean.put("newId", ToolUtil.getSurFaceId()); + bean.put("name", fileName.replace("/", "")); + bean.put("address", ""); + bean.put("fileExtName", DickCloudType.FOLDER.getKey()); + beans.add(bean); + } else { + fileName = entry.getName().substring(("/" + entry.getName()).lastIndexOf("/"));//文件名 + fileZipPath = entry.getName().replace(fileName, "");//文件路径--作为文件父id + newSaveFileName = String.valueOf(System.currentTimeMillis()); + if (ToolUtil.isBlank(fileZipPath)) { + bean.put("parentId", "0"); + } else { + bean.put("parentId", fileZipPath); + } + bean.put("originalName", entry.getName()); + bean.put("id", entry.getName()); + bean.put("newId", ToolUtil.getSurFaceId()); + bean.put("name", fileName); + bean.put("address", visitPath + "/" + newSaveFileName + "." + fileName.substring(fileName.lastIndexOf(".") + 1)); + bean.put("fileExtName", fileName.substring(fileName.lastIndexOf(".") + 1)); + beans.add(bean); + bos = new BufferedOutputStream(new FileOutputStream(basePath + newSaveFileName + "." + fileName.substring(fileName.lastIndexOf(".") + 1))); + // 获取条目流 + bis = new BufferedInputStream(zip.getInputStream(entry)); + byte[] buf = new byte[1024]; + int len; + while ((len = bis.read(buf)) != -1) { + bos.write(buf, 0, len); + } + bos.close(); + } + } + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.close(bis); + FileUtil.close(bos); + FileUtil.close(zip); + } + beans = ToolUtil.listToTree(beans, "id", "parentId", "children"); + ToolUtil.FileListParentISEdit(beans, fileConsole.getParentId());//替换父id + beans = ToolUtil.FileTreeTransList(beans);//将树转为list + List> folderList = ToolUtil.getFolderByList(beans);//获取集合中的文件夹 + List> fileList = ToolUtil.getFileByList(beans);//获取集合中的文件 + for (Map item : folderList) {//文件夹 + item.put("deleteFlag", DeleteFlagEnum.NOT_DELETE.getKey()); + item.put("createId", userId); + item.put("createTime", DateUtil.getTimeAndToString()); + } + if (!folderList.isEmpty()) { + fileConsoleDao.insertFolderList(folderList); + } + for (Map item : fileList) {//文件 + File f = new File(tPath.replace("images", "") + item.get("address").toString()); + item.put("sizeType", "bytes");//文件大小单位 + item.put("size", f.length());//文件大小 + item.put("chunk", 0);//文件整合完之后的序号 默认0 + item.put("chunkSize", f.length());//文件整合之后的大小 + String fileExtName = item.get("fileExtName").toString(); + if (FileType.judgeIsAllowedFileType(fileExtName, 1)) {//图片 + item.put("thumbnail", item.get("address").toString());//文件缩略图地址 + } else if (FileType.judgeIsAllowedFileType(fileExtName, 6)) {//电子书 + String picName = System.currentTimeMillis() + ".jpg"; + String newFilename = basePath + picName; + writeAndReadQpubFileThumbnail(tPath.replace("images", "") + item.get("address").toString(), newFilename); + // 文件缩略图地址 + item.put("thumbnail", visitPath + "/" + picName); + } else if (FileType.judgeIsAllowedFileType(fileExtName, 2)) { + // office文件缩略图地址 + item.put("thumbnail", FileType.getIconByFileExt(fileExtName)); + } else if (FileType.judgeIsAllowedFileType(fileExtName, 5)) { + // ace文件缩略图地址 + item.put("thumbnail", FileType.getIconByFileExt(fileExtName)); + } else if (FileType.judgeIsAllowedFileType(fileExtName, 3)) {//视频 + String ffmpegGPath = tPath + "/util/ffmpeg.exe";//工具路径 + String fileThumbnail = String.valueOf(System.currentTimeMillis()) + ".jpg"; + FileUtil.createDirs(basePath + "ffmpeg/"); + if (ToolUtil.take(tPath.replace("images", "") + item.get("address").toString(), basePath + "ffmpeg/" + fileThumbnail, ffmpegGPath)) { + item.put("thumbnail", visitPath + "/ffmpeg/" + fileThumbnail); + } else { + FileUtil.deleteFile(tPath.replace("images", "") + item.get("address").toString()); + outputObject.setreturnMessage("上传失败。"); + return; + } + } else if (FileType.judgeIsAllowedFileType(fileExtName, 4)) {//压缩包 + item.put("thumbnail", "../../assets/images/rar.png");//文件缩略图地址 + } else {//其他 + item.put("thumbnail", "../../assets/images/cloud/other-icon.png");//文件缩略图地址 + } + item.put("deleteFlag", DeleteFlagEnum.NOT_DELETE.getKey()); + item.put("createId", userId); + item.put("createTime", DateUtil.getTimeAndToString()); + } + if (!fileList.isEmpty()) { + fileConsoleDao.insertShareFileListByList(fileList); + } + } else { + outputObject.setreturnMessage("该文件已不存在。"); + } + } else { + outputObject.setreturnMessage("文件类型不正确,无法进行解压。"); + } + } + + /** + * 文件或者文件夹复制 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPasteCopyToService(InputObject inputObject, OutputObject outputObject) { + setCopyFileMation(inputObject); + } + + /** + * 文件或者文件夹剪切 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPasteCutToService(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> array = JSONUtil.toList(map.get("jsonStr").toString(), null);//获取数据信息 + String userId = inputObject.getLogParams().get("id").toString(); + String folderId = fileCatalogService.setParentId(map.get("folderId").toString()); + List folderBeans = new ArrayList<>(); + List fileBeans = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + Map object = array.get(i); + if (DickCloudType.FOLDER.getKey().equals(object.get("rowType").toString())) {//文件夹 + folderBeans.add(object.get("rowId").toString()); + } else { + fileBeans.add(object.get("rowId").toString()); + } + } + if (!folderBeans.isEmpty()) {//选择保存的文件夹不为空 + List> folderNew = fileCatalogService.queryFolderAndChildList(folderBeans); + if (!folderNew.isEmpty()) {//删除之前的信息 + fileCatalogService.deleteById(folderNew.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList())); + } + List> fileNew = fileConsoleDao.queryChildFileListByFolder(folderNew, DeleteFlagEnum.NOT_DELETE.getKey()); + if (!fileNew.isEmpty()) {//删除之前的信息 + deleteById(fileNew.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList())); + } + for (Map folder : folderNew) {//重置父id + String[] str = folder.get("parentId").toString().split(","); + folder.put("directParentId", str[str.length - 1]); + folder.put("newId", ToolUtil.getSurFaceId()); + } + // 将数据转化为树的形式,方便进行父id重新赋值 + folderNew = ToolUtil.listToTree(folderNew, "id", "directParentId", "children"); + ToolUtil.FileListParentISEdit(folderNew, folderId);//替换父id + folderNew = ToolUtil.FileTreeTransList(folderNew);//将树转为list + for (Map folder : folderNew) { + folder.put("createId", userId); + folder.put("createTime", DateUtil.getTimeAndToString()); + } + // 为文件重置新parentId参数 + for (Map folder : folderNew) { + String parentId = folder.get("parentId").toString() + folder.get("id").toString() + ","; + String newParentId = folder.get("newParentId").toString() + folder.get("newId").toString() + ","; + for (Map file : fileNew) { + if (parentId.equals(file.get("parentId").toString())) { + file.put("newParentId", newParentId); + } + } + } + //为文件重置新参数 + for (Map file : fileNew) { + file.put("newId", ToolUtil.getSurFaceId()); + file.put("createId", userId); + file.put("createTime", DateUtil.getTimeAndToString()); + } + if (!folderNew.isEmpty()) { + fileConsoleDao.insertFolderList(folderNew); + } + if (!fileNew.isEmpty()) { + fileConsoleDao.insertShareFileListByList(fileNew); + } + } + if (!fileBeans.isEmpty()) {//选择保存的文件不为空 + List> fileNew = fileConsoleDao.queryShareFileListByFileList(fileBeans, DeleteFlagEnum.NOT_DELETE.getKey()); + if (!fileNew.isEmpty()) {//删除之前的信息 + deleteById(fileNew.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList())); + } + //为文件重置新参数 + for (Map file : fileNew) { + file.put("newParentId", folderId); + file.put("newId", ToolUtil.getSurFaceId()); + file.put("createId", userId); + file.put("createTime", DateUtil.getTimeAndToString()); + } + fileConsoleDao.insertShareFileListByList(fileNew); + } + } + + /** + * office文件编辑获取修改时间作为最新的key + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryOfficeUpdateTimeToKey(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + FileConsole fileConsole = selectById(id); + outputObject.setBean(fileConsole); + } + + /** + * 文件统计报表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFileNumStatistics(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + //文件总数量和总存储 + Map allNum = skyeyeBaseMapper.queryAllNumFile(DeleteFlagEnum.NOT_DELETE.getKey()); + allNum.put("fileSizeZh", BytesUtil.sizeFormatNum2String(Long.parseLong(allNum.get("fileSize").toString()))); + //今日新增的文件总数量和总存储 + Map allNumToday = skyeyeBaseMapper.queryAllNumFileToday(DeleteFlagEnum.NOT_DELETE.getKey()); + allNumToday.put("fileSizeZh", BytesUtil.sizeFormatNum2String(Long.parseLong(allNumToday.get("fileSize").toString()))); + //本周新增的文件总数量和总存储 + Map allNumThisWeek = skyeyeBaseMapper.queryAllNumFileThisWeek(DeleteFlagEnum.NOT_DELETE.getKey()); + allNumThisWeek.put("fileSizeZh", BytesUtil.sizeFormatNum2String(Long.parseLong(allNumThisWeek.get("fileSize").toString()))); + //文件类型占比 + List> fileTypeNum = skyeyeBaseMapper.queryFileTypeNum(DeleteFlagEnum.NOT_DELETE.getKey()); + Map fileTypeNumEntity = new HashMap<>(); + String fileTypeNumStr = ""; + for (Map en : fileTypeNum) { + fileTypeNumStr += en.get("name").toString() + ","; + } + fileTypeNumEntity.put("fileTypeNum", fileTypeNum); + fileTypeNumEntity.put("fileTypeNumStr", fileTypeNumStr); + //文件存储占比(前三) + List> fileStorageNum = skyeyeBaseMapper.queryFileStorageNum(DeleteFlagEnum.NOT_DELETE.getKey()); + //本年度新增文件数 + List> newFileNum = skyeyeBaseMapper.queryNewFileNum(DeleteFlagEnum.NOT_DELETE.getKey()); + //近七天新增文件类型数 + List> fileTypeNumSevenDay = skyeyeBaseMapper.queryFileTypeNumSevenDay(DeleteFlagEnum.NOT_DELETE.getKey()); + + map.clear(); + map.put("allNum", allNum); + map.put("allNumToday", allNumToday); + map.put("allNumThisWeek", allNumThisWeek); + map.put("fileTypeNumEntity", fileTypeNumEntity); + map.put("fileStorageNum", fileStorageNum); + map.put("newFileNum", newFileNum); + map.put("fileTypeNumSevenDay", fileTypeNumSevenDay); + outputObject.setBean(map); + } + + /** + * 文件打包下载 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertFileMationToPackageDownload(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> array = JSONUtil.toList(map.get("jsonStr").toString(), null);//获取数据信息 + String trueFileName;//文件存储路径 + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + // 创建前端传来的数据对象 + List folderBeans = new ArrayList<>(); + List fileBeans = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + Map object = array.get(i); + if (DickCloudType.FOLDER.getKey().equals(object.get("rowType").toString())) {//文件夹 + folderBeans.add(object.get("rowId").toString()); + } else { + fileBeans.add(object.get("rowId").toString()); + } + } + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FILE_PATH_TYPE) + "/temporaryfile/" + userId + "/"; + FileUtil.createDirs(basePath); + //加载数据 + List> dowlLoadFile = new ArrayList<>(); + if (!folderBeans.isEmpty()) {//选择保存的文件夹不为空 + List> folderNew = fileCatalogService.queryFolderAndChildList(folderBeans); + List> fileNew = skyeyeBaseMapper.queryChildFileListByFolder(folderNew, DeleteFlagEnum.NOT_DELETE.getKey()); + dowlLoadFile.addAll(folderNew); + dowlLoadFile.addAll(fileNew); + } + if (!fileBeans.isEmpty()) {//选择保存的文件不为空 + List> fileNew = skyeyeBaseMapper.queryShareFileListByFileList(fileBeans, DeleteFlagEnum.NOT_DELETE.getKey()); + dowlLoadFile.addAll(fileNew); + } + + //创建压缩包 + if (!dowlLoadFile.isEmpty()) { + for (Map bean : dowlLoadFile) {//重置父id + String[] str = bean.get("parentId").toString().split(","); + bean.put("directParentId", str[str.length - 1]); + bean.put("fileName", bean.get("name")); + bean.put("fileType", bean.get("type")); + bean.put("fileAddress", bean.get("address")); + } + //将数据转化为树的形式,方便进行父id重新赋值 + dowlLoadFile = ToolUtil.listToTree(dowlLoadFile, "id", "directParentId", "children"); + //打包 + String fileName = String.valueOf(System.currentTimeMillis());//压缩包文件名 + String strZipPath = basePath + fileName + ".zip"; + File zipFile = new File(strZipPath); + if (zipFile.exists()) { + outputObject.setreturnMessage("该文件已存在,生成失败。"); + return; + } else { + ZipOutputStream out = null; + try { + out = new ZipOutputStream(new FileOutputStream(strZipPath)); + ToolUtil.recursionZip(out, dowlLoadFile, "", tPath.replace("images", ""), 2); + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.close(out); + } + } + trueFileName = FileConstants.FileUploadPath.getVisitPath(FILE_PATH_TYPE) + "temporaryfile/" + userId + "/" + fileName + ".zip"; + } else { + outputObject.setreturnMessage("未找到要打包的文件."); + return; + } + map.clear(); + map.put("fileAddress", trueFileName);//文件地址 + outputObject.setBean(map); + } + + /** + * 获取并写入epub电子书的缩略图 + * + * @param epubFilePath epub电子书文件地址 + * @param thumbnailPicPath 缩略图图片地址 + */ + private void writeAndReadQpubFileThumbnail(String epubFilePath, String thumbnailPicPath) { + FileImageOutputStream imgout = null; + try { + EpubReader epubReader = new EpubReader(); + Book book = epubReader.readEpub(new FileInputStream(epubFilePath)); + Resource resource = book.getResources().getByHref("Images/cover.jpg"); + byte[] p = resource.getData(); + imgout = new FileImageOutputStream(new File(thumbnailPicPath)); + imgout.write(p, 0, p.length); + } catch (IOException e) { + throw new CustomException(e); + } finally { + FileUtil.close(imgout); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileRecycleBinServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileRecycleBinServiceImpl.java new file mode 100644 index 0000000..9e4ab90 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileRecycleBinServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.diskcloud.classenum.DickCloudType; +import com.skyeye.eve.diskcloud.dao.FileRecycleBinDao; +import com.skyeye.eve.diskcloud.service.FileCatalogService; +import com.skyeye.eve.diskcloud.service.FileRecycleBinService; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import com.skyeye.eve.diskcloud.entity.FileConsole; +import com.skyeye.eve.diskcloud.entity.FileRecycleBin; +import com.skyeye.eve.diskcloud.service.FileConsoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileRecycleBinServiceImpl + * @Description: 回收站服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/17 22:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "回收站管理", groupName = "回收站管理") +public class FileRecycleBinServiceImpl extends SkyeyeBusinessServiceImpl implements FileRecycleBinService { + + @Autowired + private FileConsoleService fileConsoleService; + + @Autowired + private FileCatalogService fileCatalogService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryFileRecycleBinList(pageInfo); + beans.forEach(bean -> { + bean.put("fileTypeName", DickCloudType.getTypeName(bean.get("fileType").toString())); + }); + return beans; + } + + @Override + public void createPrepose(FileRecycleBin entity) { + FileCatalog fileCatalog = fileCatalogService.selectById(entity.getFileId()); + if (ObjectUtil.isNotEmpty(fileCatalog) && StrUtil.isNotEmpty(fileCatalog.getId())) { + entity.setFileType(DickCloudType.FOLDER.getKey()); + entity.setFileName(fileCatalog.getName()); + } + + FileConsole fileConsole = fileConsoleService.selectById(entity.getFileId()); + if (ObjectUtil.isNotEmpty(fileConsole) && StrUtil.isNotEmpty(fileConsole.getId())) { + entity.setFileType(DickCloudType.FILE.getKey()); + entity.setFileName(fileConsole.getName()); + } + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileShareServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileShareServiceImpl.java new file mode 100644 index 0000000..96835ac --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/diskcloud/service/impl/FileShareServiceImpl.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.diskcloud.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.BytesUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.diskcloud.classenum.DickCloudType; +import com.skyeye.eve.diskcloud.classenum.ShareState; +import com.skyeye.eve.diskcloud.classenum.ShareType; +import com.skyeye.eve.diskcloud.dao.FileShareDao; +import com.skyeye.eve.diskcloud.entity.FileCatalog; +import com.skyeye.eve.diskcloud.entity.FileConsole; +import com.skyeye.eve.diskcloud.entity.FileShare; +import com.skyeye.eve.diskcloud.service.FileCatalogService; +import com.skyeye.eve.diskcloud.service.FileConsoleService; +import com.skyeye.eve.diskcloud.service.FileShareService; +import com.skyeye.exception.CustomException; +import com.skyeye.constans.DiskCloudConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FileShareServiceImpl + * @Description: 文件分享服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/18 11:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "文件分享管理", groupName = "文件分享管理") +public class FileShareServiceImpl extends SkyeyeBusinessServiceImpl implements FileShareService { + + @Autowired + private FileConsoleService fileConsoleService; + + @Autowired + private FileCatalogService fileCatalogService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryShareFileList(pageInfo); + beans.forEach(bean -> { + bean.put("fileTypeName", DickCloudType.getTypeName(bean.get("fileType").toString())); + bean.put("shareTypeName", ShareType.getTypeName(Integer.parseInt(bean.get("shareType").toString()))); + bean.put("stateName", ShareState.getTypeName(Integer.parseInt(bean.get("state").toString()))); + }); + return beans; + } + + @Override + public void createPrepose(FileShare entity) { + FileCatalog fileCatalog = fileCatalogService.selectById(entity.getFileId()); + if (ObjectUtil.isNotEmpty(fileCatalog) && StrUtil.isNotEmpty(fileCatalog.getId())) { + entity.setFileType(DickCloudType.FOLDER.getKey()); + entity.setShareName(fileCatalog.getName()); + } + + FileConsole fileConsole = fileConsoleService.selectById(entity.getFileId()); + if (ObjectUtil.isNotEmpty(fileConsole) && StrUtil.isNotEmpty(fileConsole.getId())) { + entity.setFileType(DickCloudType.FILE.getKey()); + entity.setShareName(fileConsole.getName()); + } + if (ShareType.PRIVATE.getKey().equals(entity.getShareType())) { + // 有提取码 + entity.setSharePassword(ToolUtil.getFourWord()); + } + entity.setShareUrl(DiskCloudConstants.getFileShareUrl(StrUtil.EMPTY)); + entity.setShareCode(ToolUtil.randomStr(0, 20)); + entity.setState(ShareState.NORMAL.getKey()); + } + + @Override + protected void createPostpose(FileShare entity, String userId) { + String shareUrl = DiskCloudConstants.getFileShareUrl(entity.getId()); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, entity.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(FileShare::getShareUrl), shareUrl); + update(updateWrapper); + } + + @Override + public void queryShareFileMationById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + FileShare fileShare = selectById(id); + if (ObjectUtil.isEmpty(fileShare) || StrUtil.isEmpty(fileShare.getId())) { + throw new CustomException("该数据不存在"); + } + fileShare.setSharePassword(StrUtil.EMPTY); + iAuthUserService.setDataMation(fileShare, FileShare::getCreateId); + outputObject.setBean(fileShare); + } + + @Override + public void checkShareFilePwdMation(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + String sharePassword = inputObject.getParams().get("sharePassword").toString(); + FileShare fileShare = selectById(id); + if (ObjectUtil.isEmpty(fileShare)) { + throw new CustomException("该数据不存在"); + } + if (!StrUtil.equalsIgnoreCase(fileShare.getSharePassword(), sharePassword)) { + throw new CustomException("提取码输入错误"); + } + } + + @Override + public void queryShareFileListByParentId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String folderId = map.get("folderId").toString(); + String id = map.get("id").toString(); + List> beans; + if ("-1".equals(folderId)) { + // 加载初始目录 + beans = skyeyeBaseMapper.queryShareFileFirstListByParentId(id); + } else { + // 加载子目录 + beans = skyeyeBaseMapper.queryShareFileListByParentId(folderId, DeleteFlagEnum.NOT_DELETE.getKey()); + } + for (Map bean : beans) { + if (!DickCloudType.FOLDER.getKey().equals(bean.get("fileType").toString())) { + // 不是文件夹 + String size = BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("fileSize").toString())); + bean.put("fileSize", size); + } + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/classenum/EmailState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/classenum/EmailState.java new file mode 100644 index 0000000..34a7620 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/classenum/EmailState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: EmailState + * @Description: 邮件状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum EmailState implements SkyeyeEnumClass { + + DRAFT(0, "草稿", true, false), + NORMAL(1, "正常", true, false), + DELETE(2, "已删除", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailController.java new file mode 100644 index 0000000..ee9e800 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailController.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.email.entity.EmailParams; +import com.skyeye.eve.email.service.EmailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EmailController + * @Description: 邮件控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 9:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "邮件管理", tags = "邮件管理", modelName = "邮件管理") +public class EmailController { + + @Autowired + private EmailService emailService; + + /** + * 获取我的收件箱内容 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail004", value = "获取我的收件箱内容", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EmailController/queryInboxEmailListByEmailId") + public void queryInboxEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + emailService.queryPageList(inputObject, outputObject); + } + + /** + * 获取我的已发送邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail007", value = "获取我的已发送邮件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EmailController/querySendedEmailListByEmailId") + public void querySendedEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + emailService.querySendedEmailListByEmailId(inputObject, outputObject); + } + + /** + * 获取我的已删除邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail009", value = "获取我的已删除邮件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EmailController/queryDeleteEmailListByEmailId") + public void queryDeleteEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + emailService.queryDeleteEmailListByEmailId(inputObject, outputObject); + } + + /** + * 获取我的草稿箱邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail011", value = "获取我的草稿箱邮件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EmailController/queryDraftsEmailListByEmailId") + public void queryDraftsEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + emailService.queryDraftsEmailListByEmailId(inputObject, outputObject); + } + + /** + * 根据id查询邮件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail005", value = "根据id查询邮件信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/EmailController/queryEmailById") + public void queryEmailById(InputObject inputObject, OutputObject outputObject) { + emailService.selectById(inputObject, outputObject); + } + + /** + * 发送邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail012", value = "发送邮件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailParams.class) + @RequestMapping("/post/EmailController/insertToSendEmailMationByUserId") + public void insertToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + emailService.insertToSendEmailMationByUserId(inputObject, outputObject); + } + + /** + * 保存邮件为草稿 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail013", value = "保存邮件为草稿", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailParams.class) + @RequestMapping("/post/EmailController/insertToDraftsEmailMationByUserId") + public void insertToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + emailService.insertToDraftsEmailMationByUserId(inputObject, outputObject); + } + + /** + * 草稿邮件修改 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail015", value = "草稿邮件修改", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailParams.class) + @RequestMapping("/post/EmailController/editToDraftsEmailMationByUserId") + public void editToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + emailService.editToDraftsEmailMationByUserId(inputObject, outputObject); + } + + /** + * 草稿箱邮件发送 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail016", value = "保存邮件为草稿", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailParams.class) + @RequestMapping("/post/EmailController/insertToSendEmailMationByEmailId") + public void insertToSendEmailMationByEmailId(InputObject inputObject, OutputObject outputObject) { + emailService.insertToSendEmailMationByEmailId(inputObject, outputObject); + } + + /** + * 转发邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail019", value = "保存邮件为草稿", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailParams.class) + @RequestMapping("/post/EmailController/insertForwardToSendEmailMationByUserId") + public void insertForwardToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + emailService.insertForwardToSendEmailMationByUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailSendModelController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailSendModelController.java new file mode 100644 index 0000000..271d87a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailSendModelController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.email.entity.EmailSendModel; +import com.skyeye.eve.email.service.EmailSendModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EmailSendModelController + * @Description: 邮件发送模板控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/10 8:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "邮件发送模板", tags = "邮件发送模板", modelName = "邮件发送模板") +public class EmailSendModelController { + + @Autowired + private EmailSendModelService emailSendModelService; + + /** + * 获取邮箱发送模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "emailsendmodel001", value = "获取邮箱发送模板列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EmailSendModel/queryEmailSendModelList") + public void queryEmailSendModelList(InputObject inputObject, OutputObject outputObject) { + emailSendModelService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑邮件发送模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeEmailSendModel", value = "新增/编辑邮件发送模板信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = EmailSendModel.class) + @RequestMapping("/post/EmailSendModel/writeEmailSendModel") + public void writeEmailSendModel(InputObject inputObject, OutputObject outputObject) { + emailSendModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取邮件模板详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEmailSendById", value = "根据id获取邮件模板详情", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/EmailSendModel/queryEmailSendById") + public void queryEmailSendById(InputObject inputObject, OutputObject outputObject) { + emailSendModelService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除该模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteEmailSendById", value = "根据id删除该模板", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/EmailSendModel/deleteEmailSendById") + public void deleteEmailSendById(InputObject inputObject, OutputObject outputObject) { + emailSendModelService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailUserController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailUserController.java new file mode 100644 index 0000000..6c2a2c5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/controller/EmailUserController.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.email.entity.EmailUser; +import com.skyeye.eve.email.service.EmailUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EmailUserController + * @Description: 用户绑定的邮箱控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 8:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用户绑定的邮箱", tags = "用户绑定的邮箱", modelName = "用户绑定的邮箱") +public class EmailUserController { + + @Autowired + private EmailUserService emailUserService; + + /** + * 根据用户获取该用户绑定的邮箱信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEmailListByUserId", value = "获取指定年度的客户新增量,联系人新增量", method = "GET", allUse = "2") + @RequestMapping("/post/EmailUserController/queryEmailListByUserId") + public void queryEmailListByUserId(InputObject inputObject, OutputObject outputObject) { + emailUserService.queryEmailListByUserId(inputObject, outputObject); + } + + /** + * 添加邮箱信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createEmailUser", value = "添加邮箱信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EmailUser.class) + @RequestMapping("/post/EmailUserController/createEmailUser") + public void createEmailUser(InputObject inputObject, OutputObject outputObject) { + emailUserService.createEntity(inputObject, outputObject); + } + + /** + * 从服务器上获取收件箱里的邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail003", value = "从服务器上获取收件箱里的邮件", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "emailUserId", name = "emailUserId", value = "用户绑定的邮箱id", required = "required")}) + @RequestMapping("/post/EmailUserController/insertEmailListFromServiceByUserId") + public void insertEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + emailUserService.insertEmailListFromServiceByUserId(inputObject, outputObject); + } + + /** + * 从服务器上获取已发送邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail006", value = "从服务器上获取已发送邮件", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "emailUserId", name = "emailUserId", value = "用户绑定的邮箱id", required = "required")}) + @RequestMapping("/post/EmailUserController/insertSendedEmailListFromServiceByUserId") + public void insertSendedEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + emailUserService.insertSendedEmailListFromServiceByUserId(inputObject, outputObject); + } + + /** + * 从服务器上获取已删除邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail008", value = "从服务器上获取已删除邮件", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "emailUserId", name = "emailUserId", value = "用户绑定的邮箱id", required = "required")}) + @RequestMapping("/post/EmailUserController/insertDelsteEmailListFromServiceByUserId") + public void insertDelsteEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + emailUserService.insertDelsteEmailListFromServiceByUserId(inputObject, outputObject); + } + + /** + * 从服务器上获取草稿箱邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "useremail010", value = "从服务器上获取草稿箱邮件", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "emailUserId", name = "emailUserId", value = "用户绑定的邮箱id", required = "required")}) + @RequestMapping("/post/EmailUserController/insertDraftsEmailListFromServiceByUserId") + public void insertDraftsEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + emailUserService.insertDraftsEmailListFromServiceByUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailDao.java new file mode 100644 index 0000000..f3c5f0c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailDao.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.email.entity.Email; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EmailDao + * @Description: 邮件管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailDao extends SkyeyeBaseMapper { + + List> queryEmailListByEmailId(CommonPageInfo commonPageInfo); + + List> queryEmailListByEmailAddress(@Param("userAddress") String userAddress, @Param("state") Integer state); + + int insertEmailListToServer(List> enclosureBeans); + + int insertEmailEnclosureListToServer(List> beans); + + int editEmailMessageIdByEmailId(Map emailEditMessageId); + + List> queryEmailListByEmailFromAddress(@Param("userAddress") String userAddress, @Param("state") Integer state); + + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailEnclosureDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailEnclosureDao.java new file mode 100644 index 0000000..230fcb8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailEnclosureDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.email.entity.EmailEnclosure; + +/** + * @ClassName: EmailEnclosureDao + * @Description: 邮件附件数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailEnclosureDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailSendModelDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailSendModelDao.java new file mode 100644 index 0000000..f04565c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailSendModelDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.email.entity.EmailSendModel; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EmailSendModelDao + * @Description: 邮件发送模板数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/31 22:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailSendModelDao extends SkyeyeBaseMapper { + + List> queryEmailSendModelList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailUserDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailUserDao.java new file mode 100644 index 0000000..594e4c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/dao/EmailUserDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.email.entity.EmailUser; + +/** + * @ClassName: EmailUserDao + * @Description: 用户绑定的邮箱数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 10:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailUserDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/Email.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/Email.java new file mode 100644 index 0000000..56ead49 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/Email.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Email + * @Description: 邮件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 8:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "email:mail") +@TableName(value = "email_mail", autoResultMap = true) +@ApiModel("邮件实体类") +public class Email extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("content") + @ApiModelProperty(value = "邮件内容", required = "required") + private String content; + + @TableField("send_date") + @Property(value = "发送时间") + private String sendDate; + + @TableField(exist = false) + @Property(value = "发送日期") + private String sendDay; + + @TableField(exist = false) + @Property(value = "具体的发送时间") + private String sendTime; + + @TableField("replay_sign") + @Property(value = "是否需要回复,参考#WhetherEnum") + private Integer replaySign; + + @TableField("is_new") + @Property(value = "是否已读,参考#WhetherEnum") + private Integer isNew; + + @TableField("is_contain_attach") + @Property(value = "是否包含附件,参考#WhetherEnum") + private Integer isContainAttach; + + @TableField("from_people") + @Property(value = "发件人") + private String fromPeople; + + @TableField("to_people") + @ApiModelProperty(value = "收件人", required = "required") + private String toPeople; + + @TableField("to_cc") + @ApiModelProperty(value = "抄送人") + private String toCc; + + @TableField("to_bcc") + @ApiModelProperty(value = "暗送人") + private String toBcc; + + @TableField("message_id") + @Property(value = "消息id") + private String messageId; + + @TableField("create_time") + @Property(value = "创建时间") + private String createTime; + + @TableField("state") + @Property(value = "状态,参考#EmailState") + private Integer state; + + @TableField(exist = false) + @Property(value = "邮件附件id串") + private String emailEnclosure; + + @TableField(exist = false) + @Property(value = "邮件附件信息") + private List emailEnclosureList; + + @TableField(exist = false) + @Property(value = "用户绑定的邮箱id") + private String emailUserId; + + @TableField(exist = false) + @Property(value = "消息任务类型") + private Integer messageJobType; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailEnclosure.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailEnclosure.java new file mode 100644 index 0000000..9c8aeda --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailEnclosure.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: EmailEnclosure + * @Description: 邮件附件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "email_enclosure", autoResultMap = true) +@ApiModel("邮件附件实体类") +public class EmailEnclosure extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("file_name") + @Property(value = "文件名称") + private String fileName; + + @TableField("file_ext_name") + @Property(value = "文件后缀") + private String fileExtName; + + @TableField("file_path") + @Property(value = "文件存储路径") + private String filePath; + + @TableField("file_size") + @Property(value = "文件大小") + private String fileSize; + + @TableField("parent_id") + @Property(value = "所属邮件") + private String parentId; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailParams.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailParams.java new file mode 100644 index 0000000..65d6e91 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailParams.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: EmailParams + * @Description: 邮件发送等操作的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 13:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("邮件发送等操作的实体类") +public class EmailParams extends CommonInfo { + + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @ApiModelProperty(value = "邮件内容", required = "required") + private String content; + + @ApiModelProperty(value = "收件人", required = "required") + private String toPeople; + + @ApiModelProperty(value = "抄送人") + private String toCc; + + @ApiModelProperty(value = "暗送人") + private String toBcc; + + @ApiModelProperty(value = "邮件附件id串") + private String emailEnclosure; + + @ApiModelProperty(value = "用户绑定的邮箱id", required = "required") + private String emailUserId; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailSendModel.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailSendModel.java new file mode 100644 index 0000000..a9b0227 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailSendModel.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: EmailSendModel + * @Description: 邮件发送模板实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 19:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "email:sendModel", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "email_send_model", autoResultMap = true) +@ApiModel("邮件发送模板实体类") +public class EmailSendModel extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("to_people") + @ApiModelProperty(value = "收件人", required = "required") + private String toPeople; + + @TableField("to_cc") + @ApiModelProperty(value = "抄送人") + private String toCc; + + @TableField("to_bcc") + @ApiModelProperty(value = "暗送人") + private String toBcc; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailUser.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailUser.java new file mode 100644 index 0000000..9eabe04 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/entity/EmailUser.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: EmailUser + * @Description: 用户绑定的邮箱实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 10:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"createId", "emailAddress"}) +@RedisCacheField(name = "email:user") +@TableName(value = "email_user", autoResultMap = true) +@ApiModel("用户绑定的邮箱实体类") +public class EmailUser extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("email_address") + @ApiModelProperty(value = "邮箱地址", required = "required") + private String emailAddress; + + @TableField("email_password") + @ApiModelProperty(value = "登录密码", required = "required") + private String emailPassword; + + @TableField("email_check") + @Property(value = "当前用户默认设置的email,参考#WhetherEnum") + private Integer emailCheck; + + @TableField("create_id") + @Property(value = "绑定人") + private String createId; + + @TableField("create_time") + @Property(value = "绑定时间") + private String createTime; +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailEnclosureService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailEnclosureService.java new file mode 100644 index 0000000..8b0e21c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailEnclosureService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.email.entity.EmailEnclosure; + +import java.util.List; + +/** + * @ClassName: EmailEnclosureService + * @Description: 邮件附件服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailEnclosureService extends SkyeyeBusinessService { + + void deleteByObjectId(String objectId); + + List queryByObjectId(String objectId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailSendModelService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailSendModelService.java new file mode 100644 index 0000000..846617a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailSendModelService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.email.entity.EmailSendModel; + +/** + * @ClassName: EmailSendModelService + * @Description: 邮件发送模板服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 21:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailSendModelService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailService.java new file mode 100644 index 0000000..e74bf82 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.email.entity.Email; + +/** + * @ClassName: EmailService + * @Description: 邮件管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailService extends SkyeyeBusinessService { + + void querySendedEmailListByEmailId(InputObject inputObject, OutputObject outputObject); + + void queryDeleteEmailListByEmailId(InputObject inputObject, OutputObject outputObject); + + void queryDraftsEmailListByEmailId(InputObject inputObject, OutputObject outputObject); + + void insertToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject); + + void insertToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject); + + void editToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject); + + void insertToSendEmailMationByEmailId(InputObject inputObject, OutputObject outputObject); + + void insertForwardToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailUserService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailUserService.java new file mode 100644 index 0000000..56b9749 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/EmailUserService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.email.entity.EmailUser; + +/** + * @ClassName: EmailUserService + * @Description: 用户绑定的邮箱服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 10:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EmailUserService extends SkyeyeBusinessService { + + void queryEmailListByUserId(InputObject inputObject, OutputObject outputObject); + + void insertEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject); + + void insertSendedEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject); + + void insertDelsteEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject); + + void insertDraftsEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailEnclosureServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailEnclosureServiceImpl.java new file mode 100644 index 0000000..9d4be24 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailEnclosureServiceImpl.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.email.dao.EmailEnclosureDao; +import com.skyeye.eve.email.entity.EmailEnclosure; +import com.skyeye.eve.email.service.EmailEnclosureService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: EmailEnclosureServiceImpl + * @Description: 邮件附件服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "邮件附件管理", groupName = "邮件附件管理", manageShow = false) +public class EmailEnclosureServiceImpl extends SkyeyeBusinessServiceImpl implements EmailEnclosureService { + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(EmailEnclosure::getParentId), objectId); + remove(queryWrapper); + } + + @Override + public List queryByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(EmailEnclosure::getParentId), objectId); + List emailEnclosureList = list(queryWrapper); + return emailEnclosureList; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailSendModelServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailSendModelServiceImpl.java new file mode 100644 index 0000000..5e0eb31 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailSendModelServiceImpl.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.email.dao.EmailSendModelDao; +import com.skyeye.eve.email.entity.EmailSendModel; +import com.skyeye.eve.email.service.EmailSendModelService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EmailSendModelServiceImpl + * @Description: 邮件发送模板服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/9 21:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "邮件发送模板", groupName = "邮件发送模板") +public class EmailSendModelServiceImpl extends SkyeyeBusinessServiceImpl implements EmailSendModelService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryEmailSendModelList(commonPageInfo); + return beans; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailServiceImpl.java new file mode 100644 index 0000000..b5721f5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailServiceImpl.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.base.handler.enclosure.service.IEnclosureService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.classenum.EmailState; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.email.entity.EmailUser; +import com.skyeye.eve.email.service.EmailService; +import com.skyeye.eve.email.entity.Email; +import com.skyeye.eve.email.entity.EmailEnclosure; +import com.skyeye.eve.email.entity.EmailParams; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.email.service.EmailEnclosureService; +import com.skyeye.eve.email.service.EmailUserService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: EmailServiceImpl + * @Description: 邮件管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 9:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "邮件管理", groupName = "邮件管理") +public class EmailServiceImpl extends SkyeyeBusinessServiceImpl implements EmailService { + + @Autowired + private EmailEnclosureService emailEnclosureService; + + @Autowired + private IEnclosureService iEnclosureService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private EmailUserService emailUserService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = getPageObject(inputObject); + commonPageInfo.setState(String.valueOf(EmailState.NORMAL.getKey())); + List> beans = skyeyeBaseMapper.queryEmailListByEmailId(commonPageInfo); + return beans; + } + + private CommonPageInfo getPageObject(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + EmailUser emailUser = emailUserService.selectById(commonPageInfo.getObjectId()); + String userId = inputObject.getLogParams().get("id").toString(); + if (!userId.equals(emailUser.getCreateId())) { + throw new CustomException("该邮箱信息不存在或者该邮箱信息不属于当前账号。"); + } + commonPageInfo.setObjectId(emailUser.getEmailAddress()); + return commonPageInfo; + } + + @Override + public void validatorEntity(Email entity) { + if (StrUtil.isNotEmpty(entity.getEmailEnclosure())) { + entity.setIsContainAttach(WhetherEnum.ENABLE_USING.getKey()); + } else { + entity.setIsContainAttach(WhetherEnum.DISABLE_USING.getKey()); + } + } + + @Override + public void createPrepose(Email entity) { + entity.setSendDate(DateUtil.getTimeAndToString()); + entity.setReplaySign(WhetherEnum.ENABLE_USING.getKey()); + entity.setIsNew(WhetherEnum.DISABLE_USING.getKey()); + } + + @Override + public void writePostpose(Email entity, String userId) { + List emailEnclosures = new ArrayList<>(); + emailEnclosureService.deleteByObjectId(entity.getId()); + if (StrUtil.isNotEmpty(entity.getEmailEnclosure())) { + // 保存邮件附件 + List> enclosureList = iEnclosureService.queryEnclosureInfoByIds(entity.getEmailEnclosure()); + enclosureList.forEach(enclosure -> { + EmailEnclosure emailEnclosure = new EmailEnclosure(); + emailEnclosure.setFileName(enclosure.get("name").toString()); + emailEnclosure.setFilePath(enclosure.get("fileAddress").toString()); + emailEnclosure.setFileExtName(enclosure.get("type").toString()); + emailEnclosure.setFileSize(enclosure.get("size").toString()); + emailEnclosure.setParentId(entity.getId()); + emailEnclosures.add(emailEnclosure); + }); + emailEnclosureService.createEntity(emailEnclosures, userId); + } + + EmailUser emailUser = emailUserService.selectById(entity.getEmailUserId()); + // 消息队列参数对象 + Map emailNotice = new HashMap<>(); + emailNotice.put("type", entity.getMessageJobType());//消息队列任务类型 + emailNotice.put("userAddress", emailUser.getEmailAddress());//邮箱地址 + emailNotice.put("userPassword", emailUser.getEmailPassword());//邮箱密码 + emailNotice.put("title", entity.getTitle());//邮件标题 + emailNotice.put("content", entity.getContent());//邮件内容 + emailNotice.put("toPeople", entity.getToPeople());//邮件接收人 + emailNotice.put("toCc", entity.getToCc());//邮件抄送人 + emailNotice.put("toBcc", entity.getToBcc());//邮件暗送人 + emailNotice.put("emailId", entity.getId());//邮件id + emailNotice.put("emailEnclosure", JSONUtil.toJsonStr(emailEnclosures));//邮件附件 + this.sendMQProducer(JSONUtil.toJsonStr(emailNotice), userId); + } + + private void sendMQProducer(String jsonStr, String userId) { + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(jsonStr); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + @Override + public Email getDataFromDb(String id) { + Email email = super.getDataFromDb(id); + if (email.getIsContainAttach().equals(WhetherEnum.ENABLE_USING.getKey())) { + List emailEnclosureList = emailEnclosureService.queryByObjectId(id); + email.setEmailEnclosureList(emailEnclosureList); + } + SimpleDateFormat sdf1 = new SimpleDateFormat(DateUtil.YYYY_MM_DD); + email.setSendDay(sdf1.format(DateUtil.getPointTime(email.getSendDate(), DateUtil.YYYY_MM_DD))); + SimpleDateFormat sdf2 = new SimpleDateFormat(DateUtil.HH_MM); + email.setSendTime(sdf2.format(DateUtil.getPointTime(email.getSendDate(), DateUtil.YYYY_MM_DD_HH_MM_SS))); + return email; + } + + /** + * 获取我的已发送邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySendedEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = getPageObject(inputObject); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + commonPageInfo.setType(String.valueOf(CommonNumConstants.NUM_FOUR)); + commonPageInfo.setState(String.valueOf(EmailState.NORMAL.getKey())); + List> beans = skyeyeBaseMapper.queryEmailListByEmailId(commonPageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取我的已删除邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDeleteEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = getPageObject(inputObject); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + commonPageInfo.setType(String.valueOf(CommonNumConstants.NUM_FOUR)); + commonPageInfo.setState(String.valueOf(EmailState.DELETE.getKey())); + List> beans = skyeyeBaseMapper.queryEmailListByEmailId(commonPageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取我的草稿箱邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDraftsEmailListByEmailId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = getPageObject(inputObject); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + commonPageInfo.setType(String.valueOf(CommonNumConstants.NUM_FOUR)); + commonPageInfo.setState(String.valueOf(EmailState.DRAFT.getKey())); + List> beans = skyeyeBaseMapper.queryEmailListByEmailId(commonPageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void insertToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + EmailParams emailParams = inputObject.getParams(EmailParams.class); + createEmail(emailParams, EmailState.NORMAL.getKey(), inputObject.getLogParams().get("id").toString(), MqConstants.JobMateMationJobType.COMPLEX_MAIL_DELIVERY.getJobType(), null); + } + + private void createEmail(EmailParams emailParams, Integer state, String userId, Integer messageJobType, String id) { + Email email = new Email(); + email.setTitle(emailParams.getTitle()); + email.setContent(emailParams.getContent()); + setToEmail(emailParams, email); + email.setState(state); + email.setMessageJobType(messageJobType); + email.setEmailUserId(emailParams.getEmailUserId()); + email.setEmailEnclosure(emailParams.getEmailEnclosure()); + if (StrUtil.isNotEmpty(id)) { + updateEntity(email, userId); + } else { + createEntity(email, userId); + } + } + + private void setToEmail(EmailParams emailParams, Email email) { + // 接收人邮箱校验 + String[] toPeopleEmails = emailParams.getToPeople().split(","); + String toPeople = Joiner.on(CommonCharConstants.COMMA_MARK).join(Arrays.asList(toPeopleEmails).stream() + .filter(str -> ToolUtil.isEmail(str)).collect(Collectors.toList())); + if (ToolUtil.isBlank(toPeople)) { + throw new CustomException("请选择收件人"); + } + + // 抄送人邮箱校验 + String[] toCcEmails = emailParams.getToCc().split(","); + String toCc = Joiner.on(CommonCharConstants.COMMA_MARK).join(Arrays.asList(toCcEmails).stream() + .filter(str -> ToolUtil.isEmail(str)).collect(Collectors.toList())); + // 暗送人邮箱校验 + String[] toBccEmails = emailParams.getToBcc().split(","); + String toBcc = Joiner.on(CommonCharConstants.COMMA_MARK).join(Arrays.asList(toBccEmails).stream() + .filter(str -> ToolUtil.isEmail(str)).collect(Collectors.toList())); + email.setToPeople(toPeople); + email.setToCc(toCc); + email.setToBcc(toBcc); + } + + @Override + public void insertToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + EmailParams emailParams = inputObject.getParams(EmailParams.class); + createEmail(emailParams, EmailState.DRAFT.getKey(), inputObject.getLogParams().get("id").toString(), MqConstants.JobMateMationJobType.MAIL_DRAFTS_SAVE.getJobType(), null); + } + + @Override + public void editToDraftsEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + EmailParams emailParams = inputObject.getParams(EmailParams.class); + createEmail(emailParams, EmailState.DRAFT.getKey(), inputObject.getLogParams().get("id").toString(), MqConstants.JobMateMationJobType.MAIL_DRAFTS_EDIT.getJobType(), emailParams.getId()); + } + + @Override + public void insertToSendEmailMationByEmailId(InputObject inputObject, OutputObject outputObject) { + EmailParams emailParams = inputObject.getParams(EmailParams.class); + createEmail(emailParams, EmailState.NORMAL.getKey(), inputObject.getLogParams().get("id").toString(), MqConstants.JobMateMationJobType.MAIL_DRAFTS_SEND.getJobType(), emailParams.getId()); + } + + @Override + public void insertForwardToSendEmailMationByUserId(InputObject inputObject, OutputObject outputObject) { + EmailParams emailParams = inputObject.getParams(EmailParams.class); + createEmail(emailParams, EmailState.NORMAL.getKey(), inputObject.getLogParams().get("id").toString(), MqConstants.JobMateMationJobType.COMPLEX_MAIL_DELIVERY.getJobType(), null); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailUserServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailUserServiceImpl.java new file mode 100644 index 0000000..1f90f12 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/email/service/impl/EmailUserServiceImpl.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.email.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.email.dao.EmailUserDao; +import com.skyeye.eve.email.entity.EmailUser; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.email.service.EmailUserService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EmailUserServiceImpl + * @Description: 用户绑定的邮箱服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/8 10:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户绑定的邮箱", groupName = "用户绑定的邮箱") +public class EmailUserServiceImpl extends SkyeyeBusinessServiceImpl implements EmailUserService { + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Override + public void queryEmailListByUserId(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(EmailUser::getCreateId), userId); + queryWrapper.select(CommonConstants.ID, MybatisPlusUtil.toColumns(EmailUser::getEmailAddress), + MybatisPlusUtil.toColumns(EmailUser::getEmailCheck)); + List emailUserList = list(queryWrapper); + outputObject.setBeans(emailUserList); + outputObject.settotal(emailUserList.size()); + } + + @Override + public void validatorEntity(EmailUser entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + entity.setCreateId(userId); + super.validatorEntity(entity); + // 获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + boolean login = new MailUtil(entity.getEmailAddress(), entity.getEmailPassword(), + emailServer.get("emailSendServer").toString()).authLogin(); + if (!login) { + throw new CustomException("邮箱登录失败,请检查账号密码是否正确。"); + } + } + + @Override + public void createPrepose(EmailUser entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(EmailUser::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(EmailUser::getEmailCheck), WhetherEnum.ENABLE_USING.getKey()); + EmailUser checkItem = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(checkItem)) { + entity.setEmailCheck(WhetherEnum.ENABLE_USING.getKey()); + } else { + entity.setEmailCheck(WhetherEnum.DISABLE_USING.getKey()); + } + entity.setCreateId(userId); + entity.setCreateTime(DateUtil.getTimeAndToString()); + } + + /** + * 从服务器上获取收件箱里的邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + getDataFromServer(inputObject, MqConstants.JobMateMationJobType.MAIL_ACCESS_INBOX.getJobType()); + } + + private void getDataFromServer(InputObject inputObject, Integer type) { + Map map = inputObject.getParams(); + String emailUserId = map.get("emailUserId").toString(); + EmailUser emailUser = selectById(emailUserId); + + String userId = inputObject.getLogParams().get("id").toString(); + if (ObjectUtil.isNotEmpty(emailUser) && emailUser.getCreateId().equals(userId)) { + // 消息队列参数对象 + Map emailNotice = new HashMap<>(); + emailNotice.put("type", type);//消息队列任务类型 + emailNotice.put("userAddress", emailUser.getEmailAddress());//邮箱地址 + emailNotice.put("userPassword", emailUser.getEmailPassword());//邮箱密码 + emailNotice.put("userId", userId); + this.sendMQProducer(JSONUtil.toJsonStr(emailNotice), userId); + } else { + throw new CustomException("该邮箱信息不存在或者该邮箱信息不属于当前账号。"); + } + } + + /** + * 从服务器上获取已发送邮件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertSendedEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + getDataFromServer(inputObject, MqConstants.JobMateMationJobType.MAIL_ACCESS_SENDED.getJobType()); + } + + @Override + public void insertDelsteEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + getDataFromServer(inputObject, MqConstants.JobMateMationJobType.MAIL_ACCESS_DELETE.getJobType()); + } + + @Override + public void insertDraftsEmailListFromServiceByUserId(InputObject inputObject, OutputObject outputObject) { + getDataFromServer(inputObject, MqConstants.JobMateMationJobType.MAIL_ACCESS_DRAFTS.getJobType()); + } + + private void sendMQProducer(String jsonStr, String userId) { + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(jsonStr); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/controller/FolderController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/controller/FolderController.java new file mode 100644 index 0000000..050fec1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/controller/FolderController.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.folder.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.folder.entity.Folder; +import com.skyeye.eve.folder.service.FolderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FolderController + * @Description: 笔记文件夹管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "笔记文件夹管理", tags = "笔记文件夹管理", modelName = "笔记管理") +public class FolderController { + + @Autowired + private FolderService folderService; + + /** + * 新增/编辑文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeFolder", value = "新增/编辑文件夹", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Folder.class) + @RequestMapping("/post/FolderController/writeFolder") + public void writeFolder(InputObject inputObject, OutputObject outputObject) { + folderService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取当前用户的文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFolderByUserId", value = "获取当前用户的文件夹", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "parentId", name = "parentId", value = "父文件夹id,默认为0", required = "required"), + @ApiImplicitParam(id = "moveId", name = "moveId", value = "移动节点id")}) + @RequestMapping("/post/FolderController/queryFolderByUserId") + public void queryFolderByUserId(InputObject inputObject, OutputObject outputObject) { + folderService.queryFolderByUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/dao/FolderDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/dao/FolderDao.java new file mode 100644 index 0000000..d15f75f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/dao/FolderDao.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.folder.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.folder.entity.Folder; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FolderDao + * @Description: 笔记文件夹管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FolderDao extends SkyeyeBaseMapper { + + List> queryFolderByUserId(@Param("parentId") String parentId, + @Param("createId") String createId, + @Param("moveId") String moveId, + @Param("deleteFlag") Integer deleteFlag); + + List> queryFolderAndChildList(@Param("ids") List ids, @Param("deleteFlag") Integer deleteFlag); + + int insertFileFolderList(@Param("folderList") List> folderList); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/entity/Folder.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/entity/Folder.java new file mode 100644 index 0000000..965da27 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/entity/Folder.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.folder.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Folder + * @Description: 笔记文件夹实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 22:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("笔记文件夹实体类") +@TableName(value = "note_folder") +public class Folder extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "父文件夹id") + private String parentId; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/FolderService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/FolderService.java new file mode 100644 index 0000000..a59ebf8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/FolderService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.folder.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.folder.entity.Folder; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FolderService + * @Description: 笔记文件夹管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FolderService extends SkyeyeBusinessService { + + String setParentId(String id); + + void deleteByParentId(String parentId); + + void editNameById(String id, String name, String userId); + + void queryFolderByUserId(InputObject inputObject, OutputObject outputObject); + + List> queryFolderAndChildList(List ids); + + int insertFileFolderList(List> folderList); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/impl/FolderServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/impl/FolderServiceImpl.java new file mode 100644 index 0000000..40c4a15 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/folder/service/impl/FolderServiceImpl.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.folder.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.folder.dao.FolderDao; +import com.skyeye.eve.folder.entity.Folder; +import com.skyeye.eve.folder.service.FolderService; +import com.skyeye.exception.CustomException; +import com.skyeye.constans.NoteConstants; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FolderServiceImpl + * @Description: 笔记文件夹管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "笔记文件夹管理", groupName = "笔记管理") +public class FolderServiceImpl extends SkyeyeBusinessServiceImpl implements FolderService { + + @Override + public void createPrepose(Folder entity) { + String parentId = setParentId(entity.getParentId()); + entity.setParentId(parentId); + } + + /** + * 根据节点id设置ParentId + * + * @param id + * @return + */ + @Override + public String setParentId(String id) { + if ("2".equals(id)) { + return id + ","; + } else { + Folder folder = selectById(id); + if (ObjectUtil.isNotEmpty(folder)) { + return folder.getParentId() + id + ","; + } + throw new CustomException("错误的文件夹编码!"); + } + } + + @Override + public void deleteByParentId(String parentId) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(Folder::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getDeleteFlag), DeleteFlagEnum.DELETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + @Override + public void editNameById(String id, String name, String userId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getName), name); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Folder::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + @Override + public void queryFolderByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String parentId = map.get("parentId").toString(); + String moveId = map.get("moveId").toString(); + List> beans; + if (ToolUtil.isBlank(parentId) || "0".equals(parentId)) { + // 加载一级文件夹 + beans = NoteConstants.getFileMyNoteDefaultFolder(); + } else { + // 加载子文件夹 + String userId = InputObject.getLogParamsStatic().get("id").toString(); + beans = skyeyeBaseMapper.queryFolderByUserId(parentId, userId, moveId, DeleteFlagEnum.NOT_DELETE.getKey()); + } + outputObject.setBeans(beans); + } + + @Override + public List> queryFolderAndChildList(List ids) { + return skyeyeBaseMapper.queryFolderAndChildList(ids, DeleteFlagEnum.NOT_DELETE.getKey()); + } + + @Override + public int insertFileFolderList(List> folderList) { + return skyeyeBaseMapper.insertFileFolderList(folderList); + } + + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumContentController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumContentController.java new file mode 100644 index 0000000..697754e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumContentController.java @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.forum.service.ForumContentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ForumContentController { + + @Autowired + private ForumContentService forumContentService; + + /** + * 获取我的帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryMyForumContentList") + public void queryMyForumContentList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryMyForumContentList(inputObject, outputObject); + } + + /** + * 新增我的帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/insertForumContentMation") + public void insertForumContentMation(InputObject inputObject, OutputObject outputObject) { + forumContentService.insertForumContentMation(inputObject, outputObject); + } + + /** + * 删除帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/deleteForumContentById") + public void deleteForumContentById(InputObject inputObject, OutputObject outputObject) { + forumContentService.deleteForumContentById(inputObject, outputObject); + } + + /** + * 查询帖子信息用以编辑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumContentMationById") + public void queryForumContentMationById(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumContentMationById(inputObject, outputObject); + } + + /** + * 编辑帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/editForumContentMationById") + public void editForumContentMationById(InputObject inputObject, OutputObject outputObject) { + forumContentService.editForumContentMationById(inputObject, outputObject); + } + + /** + * 帖子详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumContentMationToDetails") + public void queryForumContentMationToDetails(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumContentMationToDetails(inputObject, outputObject); + } + + /** + * 获取最新帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryNewForumContentList") + public void queryNewForumContentList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryNewForumContentList(inputObject, outputObject); + } + + /** + * 新增帖子评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/insertForumCommentMation") + public void insertForumCommentMation(InputObject inputObject, OutputObject outputObject) { + forumContentService.insertForumCommentMation(inputObject, outputObject); + } + + /** + * 获取帖子评论信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumCommentList") + public void queryForumCommentList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumCommentList(inputObject, outputObject); + } + + /** + * 新增帖子评论回复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/insertForumReplyMation") + public void insertForumReplyMation(InputObject inputObject, OutputObject outputObject) { + forumContentService.insertForumReplyMation(inputObject, outputObject); + } + + /** + * 获取帖子评论回复信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumReplyList") + public void queryForumReplyList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumReplyList(inputObject, outputObject); + } + + /** + * 获取我的浏览信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumMyBrowerList") + public void queryForumMyBrowerList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumMyBrowerList(inputObject, outputObject); + } + + /** + * 获取最新评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryNewCommentList") + public void queryNewCommentList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryNewCommentList(inputObject, outputObject); + } + + /** + * 根据标签id获取帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryForumListByTagId") + public void queryForumListByTagId(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryForumListByTagId(inputObject, outputObject); + } + + /** + * 获取热门标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryHotTagList") + public void queryHotTagList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryHotTagList(inputObject, outputObject); + } + + /** + * 获取活跃用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryActiveUsersList") + public void queryActiveUsersList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryActiveUsersList(inputObject, outputObject); + } + + /** + * 获取热门贴 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryHotForumList") + public void queryHotForumList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryHotForumList(inputObject, outputObject); + } + + /** + * 获取用户搜索的帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/querySearchForumList") + public void querySearchForumList(InputObject inputObject, OutputObject outputObject) { + forumContentService.querySearchForumList(inputObject, outputObject); + } + + /** + * 获取solr上次同步数据的时间 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/querySolrSynchronousTime") + public void querySolrSynchronousTime(InputObject inputObject, OutputObject outputObject) { + forumContentService.querySolrSynchronousTime(inputObject, outputObject); + } + + /** + * solr同步数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/updateSolrSynchronousData") + public void updateSolrSynchronousData(InputObject inputObject, OutputObject outputObject) { + forumContentService.updateSolrSynchronousData(inputObject, outputObject); + } + + /** + * 获取我的帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryMyCommentList") + public void queryMyCommentList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryMyCommentList(inputObject, outputObject); + } + + /** + * 根据评论id删除评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/deleteCommentById") + public void deleteCommentById(InputObject inputObject, OutputObject outputObject) { + forumContentService.deleteCommentById(inputObject, outputObject); + } + + /** + * 获取我的通知列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/queryMyNoticeList") + public void queryMyNoticeList(InputObject inputObject, OutputObject outputObject) { + forumContentService.queryMyNoticeList(inputObject, outputObject); + } + + /** + * 根据通知id删除通知 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumContentController/deleteNoticeById") + public void deleteNoticeById(InputObject inputObject, OutputObject outputObject) { + forumContentService.deleteNoticeById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumReportController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumReportController.java new file mode 100644 index 0000000..cce0b1c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumReportController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.forum.service.ForumReportService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ForumReportController { + + @Autowired + private ForumReportService forumReportService; + + /** + * 添加举报信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumReportController/insertForumReportMation") + public void insertForumReportMation(InputObject inputObject, OutputObject outputObject) { + forumReportService.insertForumReportMation(inputObject, outputObject); + } + + /** + * 获取论坛举报未审核列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumReportController/queryReportNoCheckList") + public void queryReportNoCheckList(InputObject inputObject, OutputObject outputObject) { + forumReportService.queryReportNoCheckList(inputObject, outputObject); + } + + /** + * 举报信息审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumReportController/editReportCheckMationById") + public void editForumContentMationById(InputObject inputObject, OutputObject outputObject) { + forumReportService.editReportCheckMationById(inputObject, outputObject); + } + + /** + * 获取论坛举报已审核列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumReportController/queryReportCheckedList") + public void queryReportCheckedList(InputObject inputObject, OutputObject outputObject) { + forumReportService.queryReportCheckedList(inputObject, outputObject); + } + + /** + * 举报详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumReportController/queryForumReportMationToDetails") + public void queryForumReportMationToDetails(InputObject inputObject, OutputObject outputObject) { + forumReportService.queryForumReportMationToDetails(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumSensitiveWordsController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumSensitiveWordsController.java new file mode 100644 index 0000000..5b29e7a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumSensitiveWordsController.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.forum.service.ForumSensitiveWordsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ForumSensitiveWordsController { + + @Autowired + private ForumSensitiveWordsService forumSensitiveWordsService; + + /** + * 获取论坛敏感词列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumSensitiveWordsController/queryForumSensitiveWordsList") + public void queryForumSensitiveWordsList(InputObject inputObject, OutputObject outputObject) { + forumSensitiveWordsService.queryForumSensitiveWordsList(inputObject, outputObject); + } + + + /** + * 添加论坛敏感词 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumSensitiveWordsController/insertForumSensitiveWordsMation") + public void insertForumSensitiveWordsMation(InputObject inputObject, OutputObject outputObject) { + forumSensitiveWordsService.insertForumSensitiveWordsMation(inputObject, outputObject); + } + + /** + * 删除论坛敏感词 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumSensitiveWordsController/deleteForumSensitiveWordsById") + public void deleteForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject) { + forumSensitiveWordsService.deleteForumSensitiveWordsById(inputObject, outputObject); + } + + /** + * 通过id查找对应的论坛敏感词信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumSensitiveWordsController/selectForumSensitiveWordsById") + public void selectForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject) { + forumSensitiveWordsService.selectForumSensitiveWordsById(inputObject, outputObject); + } + + /** + * 通过id编辑对应的论坛敏感词信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumSensitiveWordsController/editForumSensitiveWordsMationById") + public void editForumSensitiveWordsMationById(InputObject inputObject, OutputObject outputObject) { + forumSensitiveWordsService.editForumSensitiveWordsMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumTagController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumTagController.java new file mode 100644 index 0000000..5a56664 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/controller/ForumTagController.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.forum.service.ForumTagService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ForumTagController { + + @Autowired + private ForumTagService forumTagService; + + /** + * 获取论坛标签列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/queryForumTagList") + public void queryForumTagList(InputObject inputObject, OutputObject outputObject) { + forumTagService.queryForumTagList(inputObject, outputObject); + } + + + /** + * 添加论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/insertForumTagMation") + public void insertForumTagMation(InputObject inputObject, OutputObject outputObject) { + forumTagService.insertForumTagMation(inputObject, outputObject); + } + + /** + * 删除论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/deleteForumTagById") + public void deleteForumTagById(InputObject inputObject, OutputObject outputObject) { + forumTagService.deleteForumTagById(inputObject, outputObject); + } + + /** + * 上线论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/updateUpForumTagById") + public void updateUpForumTagById(InputObject inputObject, OutputObject outputObject) { + forumTagService.updateUpForumTagById(inputObject, outputObject); + } + + /** + * 下线论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/updateDownForumTagById") + public void updateDownForumTagById(InputObject inputObject, OutputObject outputObject) { + forumTagService.updateDownForumTagById(inputObject, outputObject); + } + + /** + * 通过id查找对应的论坛标签信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/selectForumTagById") + public void selectForumTagById(InputObject inputObject, OutputObject outputObject) { + forumTagService.selectForumTagById(inputObject, outputObject); + } + + /** + * 通过id编辑对应的论坛标签信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/editForumTagMationById") + public void editForumTagMationById(InputObject inputObject, OutputObject outputObject) { + forumTagService.editForumTagMationById(inputObject, outputObject); + } + + /** + * 论坛标签上移 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/editForumTagMationOrderNumUpById") + public void editSysWinTypeMationOrderNumUpById(InputObject inputObject, OutputObject outputObject) { + forumTagService.editForumTagMationOrderNumUpById(inputObject, outputObject); + } + + /** + * 论坛标签下移 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/editForumTagMationOrderNumDownById") + public void editSysWinTypeMationOrderNumDownById(InputObject inputObject, OutputObject outputObject) { + forumTagService.editForumTagMationOrderNumDownById(inputObject, outputObject); + } + + /** + * 获取已经上线的论坛标签列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ForumTagController/queryForumTagUpStateList") + public void queryForumTagUpStateList(InputObject inputObject, OutputObject outputObject) { + forumTagService.queryForumTagUpStateList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumContentDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumContentDao.java new file mode 100644 index 0000000..ca45c84 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumContentDao.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.dao; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ForumContentDao + * @Description: 论坛管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ForumContentDao { + + List> queryMyForumContentList(Map map); + + int insertForumContentMation(Map map); + + int deleteForumContentById(Map map); + + Map queryForumContentMationById(Map map); + + int editForumContentMationById(Map map); + + Map queryForumContentMationToDetails(Map map); + + List> queryNewForumContentList(Map map); + + int insertForumCommentMation(Map map); + + List> queryForumCommentList(Map map); + + int insertForumReplyMation(Map map); + + List> queryForumReplyList(Map map); + + Map selectForumCommentNumById(Map map); + + List> queryNewCommentList(Map map); + + List> queryForumListByTagId(Map map); + + List> queryHotTagList(Map map); + + List> queryActiveUsersList(Map map); + + List> queryHotForumList(Map map); + + List> queryAllHotForumList(Map map); + + List> queryAllForumList(Map map); + + List> selectForumTagById(Map bean); + + List> queryMyCommentList(Map map); + + int deleteCommentById(Map map); + + List> queryMyNoticeList(Map map); + + int deleteNoticeById(Map map); + + int insertForumHotByList(List> list); + + int insertForumStatisticsDayByList(List> list); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumReportDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumReportDao.java new file mode 100644 index 0000000..ce096a1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumReportDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.dao; + +import java.util.List; +import java.util.Map; + +public interface ForumReportDao { + + int insertForumReportMation(Map map); + + List> queryReportNoCheckList(Map map); + + int editReportCheckMationById(Map map); + + List> queryReportCheckedList(Map map); + + Map queryForumReportMationToDetails(Map map); + + Map queryForumReportStateById(Map map); + + Map queryForumReportMationById(Map map); + + int insertForumNoticeMation(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumSensitiveWordsDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumSensitiveWordsDao.java new file mode 100644 index 0000000..dfd9589 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumSensitiveWordsDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.dao; + +import java.util.List; +import java.util.Map; + +public interface ForumSensitiveWordsDao { + + List> queryForumSensitiveWordsList(Map map); + + Map queryForumSensitiveWordsMationByName(Map map); + + int insertForumSensitiveWordsMation(Map map); + + int deleteForumSensitiveWordsById(Map map); + + Map selectForumSensitiveWordsById(Map map); + + int editForumSensitiveWordsMationById(Map map); + + List> queryForumSensitiveWordsListAll(); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumTagDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumTagDao.java new file mode 100644 index 0000000..e6e36e6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/dao/ForumTagDao.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.dao; + +import java.util.List; +import java.util.Map; + +public interface ForumTagDao { + + List> queryForumTagList(Map map); + + Map queryForumTagMationByName(Map map); + + int insertForumTagMation(Map map); + + Map queryForumTagBySimpleLevel(Map map); + + int deleteForumTagById(Map map); + + int updateUpForumTagById(Map map); + + int updateDownForumTagById(Map map); + + Map selectForumTagById(Map map); + + int editForumTagMationById(Map map); + + Map queryForumTagUpMationById(Map map); + + int editForumTagMationOrderNumUpById(Map map); + + Map queryForumTagDownMationById(Map map); + + Map queryForumTagStateById(Map map); + + List> queryForumTagUpStateList(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumContentService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumContentService.java new file mode 100644 index 0000000..f2beb47 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumContentService.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ForumContentService { + + void queryMyForumContentList(InputObject inputObject, OutputObject outputObject); + + void insertForumContentMation(InputObject inputObject, OutputObject outputObject); + + void deleteForumContentById(InputObject inputObject, OutputObject outputObject); + + void queryForumContentMationById(InputObject inputObject, OutputObject outputObject); + + void editForumContentMationById(InputObject inputObject, OutputObject outputObject); + + void queryForumContentMationToDetails(InputObject inputObject, OutputObject outputObject); + + void queryNewForumContentList(InputObject inputObject, OutputObject outputObject); + + void insertForumCommentMation(InputObject inputObject, OutputObject outputObject); + + void queryForumCommentList(InputObject inputObject, OutputObject outputObject); + + void insertForumReplyMation(InputObject inputObject, OutputObject outputObject); + + void queryForumReplyList(InputObject inputObject, OutputObject outputObject); + + void queryForumMyBrowerList(InputObject inputObject, OutputObject outputObject); + + void queryNewCommentList(InputObject inputObject, OutputObject outputObject); + + void queryForumListByTagId(InputObject inputObject, OutputObject outputObject); + + void queryHotTagList(InputObject inputObject, OutputObject outputObject); + + void queryActiveUsersList(InputObject inputObject, OutputObject outputObject); + + void queryHotForumList(InputObject inputObject, OutputObject outputObject); + + void querySearchForumList(InputObject inputObject, OutputObject outputObject); + + void querySolrSynchronousTime(InputObject inputObject, OutputObject outputObject); + + void updateSolrSynchronousData(InputObject inputObject, OutputObject outputObject); + + void queryMyCommentList(InputObject inputObject, OutputObject outputObject); + + void deleteCommentById(InputObject inputObject, OutputObject outputObject); + + void queryMyNoticeList(InputObject inputObject, OutputObject outputObject); + + void deleteNoticeById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumReportService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumReportService.java new file mode 100644 index 0000000..036413a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumReportService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ForumReportService { + + void insertForumReportMation(InputObject inputObject, OutputObject outputObject); + + void queryReportNoCheckList(InputObject inputObject, OutputObject outputObject); + + void editReportCheckMationById(InputObject inputObject, OutputObject outputObject); + + void queryReportCheckedList(InputObject inputObject, OutputObject outputObject); + + void queryForumReportMationToDetails(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumSensitiveWordsService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumSensitiveWordsService.java new file mode 100644 index 0000000..cc25c7b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumSensitiveWordsService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ForumSensitiveWordsService { + + void queryForumSensitiveWordsList(InputObject inputObject, OutputObject outputObject); + + void insertForumSensitiveWordsMation(InputObject inputObject, OutputObject outputObject); + + void deleteForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject); + + void selectForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject); + + void editForumSensitiveWordsMationById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumTagService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumTagService.java new file mode 100644 index 0000000..e832c6b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/ForumTagService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ForumTagService { + + void queryForumTagList(InputObject inputObject, OutputObject outputObject); + + void insertForumTagMation(InputObject inputObject, OutputObject outputObject); + + void deleteForumTagById(InputObject inputObject, OutputObject outputObject); + + void updateUpForumTagById(InputObject inputObject, OutputObject outputObject); + + void updateDownForumTagById(InputObject inputObject, OutputObject outputObject); + + void selectForumTagById(InputObject inputObject, OutputObject outputObject); + + void editForumTagMationById(InputObject inputObject, OutputObject outputObject); + + void editForumTagMationOrderNumUpById(InputObject inputObject, OutputObject outputObject); + + void editForumTagMationOrderNumDownById(InputObject inputObject, OutputObject outputObject); + + void queryForumTagUpStateList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumContentServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumContentServiceImpl.java new file mode 100644 index 0000000..7917b71 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumContentServiceImpl.java @@ -0,0 +1,836 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service.impl; + +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.*; +import com.skyeye.constans.ForumConstants; +import com.skyeye.eve.forum.dao.ForumContentDao; +import com.skyeye.eve.forum.dao.ForumSensitiveWordsDao; +import com.skyeye.eve.forum.service.ForumContentService; +import com.skyeye.eve.forum.solr.Forum; +import com.skyeye.jedis.JedisClientService; +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.beans.DocumentObjectBinder; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * @ClassName: ForumContentServiceImpl + * @Description: 论坛管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ForumContentServiceImpl implements ForumContentService { + + @Autowired + private ForumContentDao forumContentDao; + + @Autowired + private ForumSensitiveWordsDao forumSensitiveWordsDao; + + @Autowired + public JedisClientService jedisClient; + + @Autowired + private SolrClient solrClient; + + /** + * 获取我的帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyForumContentList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumContentDao.queryMyForumContentList(map); + for (Map bean : beans) { + String createTime = ToolUtil.timeFormat(bean.get("createTime").toString()); + bean.put("createTime", createTime); + String key = ForumConstants.forumBrowseNumsByForumId(bean.get("id").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + bean.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + bean.put("browseNum", browseNum); + } + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增我的帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumContentMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String str = querySensitiveWordsByMap(map); + if (str.length() > 0) { + outputObject.setreturnMessage("该帖子包含以下敏感词:" + str.substring(0, str.length() - 1) + "!"); + } else { + map.put("state", 1); + map.put("reportState", 1); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + // 贴子纯文本内容 + String content = map.get("textConent").toString(); + // 简介 + map.put("desc", content.length() > 400 ? content.substring(0, 400) : content); + // 贴子对应的solr对象 + Forum forum = new Forum(); + forum.setId(map.get("id").toString()); + forum.setForumTitle(map.get("title").toString()); + // 纯文本内容 + forum.setForumContent(content); + forum.setForumDesc(map.get("desc").toString()); + forum.setType(map.get("forumType").toString()); + forum.setCreateId(map.get("createId").toString()); + try { + UpdateResponse response = solrClient.addBean(forum, 1000); + int status = response.getStatus(); + if (status != 0) { + solrClient.rollback(); + outputObject.setreturnMessage("发布失败!"); + } else { + int insert = forumContentDao.insertForumContentMation(map); + if (insert != 1) { + solrClient.rollback(); + outputObject.setreturnMessage("发布失败!"); + } + } + } catch (Exception e) { + outputObject.setreturnMessage("发布失败!"); + } + } + } + + /** + * 删除我的帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteForumContentById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + try { + UpdateResponse response = solrClient.deleteById(map.get("id").toString(), 1000); + int status = response.getStatus(); + if (status != 0) { + solrClient.rollback(); + } else { + int delete = forumContentDao.deleteForumContentById(map); + if (delete != 1) { + solrClient.rollback(); + outputObject.setreturnMessage("删除失败!"); + } + } + } catch (Exception e) { + outputObject.setreturnMessage("删除失败!"); + } + } + + /** + * 查询帖子信息用以编辑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumContentMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumContentDao.queryForumContentMationById(map); + List> beans = forumContentDao.selectForumTagById(bean); + bean.put("tagName", beans); + outputObject.setBean(bean); + outputObject.settotal(1); + } + + /** + * 编辑帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editForumContentMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String str = querySensitiveWordsByMap(map); + if (str.length() > 0) { + outputObject.setreturnMessage("该帖子包含以下敏感词:" + str.substring(0, str.length() - 1) + "!"); + } else { + // 贴子纯文本内容 + String content = map.get("textConent").toString(); + // 简介 + map.put("desc", content.length() > 400 ? content.substring(0, 400) : content); + Map bean = forumContentDao.queryForumContentMationById(map); + Forum forum = new Forum(); + forum.setId(map.get("id").toString()); + forum.setForumTitle(map.get("title").toString()); + // 纯文本内容 + forum.setForumContent(content); + forum.setForumDesc(map.get("desc").toString()); + forum.setType(map.get("forumType").toString()); + forum.setCreateId(bean.get("createId").toString()); + try { + UpdateResponse response = solrClient.deleteById(map.get("id").toString(), 1000); + int delstatus = response.getStatus(); + if (delstatus != 0) { + solrClient.rollback(); + } else { + response = solrClient.addBean(forum, 1000); + int addstatus = response.getStatus(); + if (addstatus != 0) { + solrClient.rollback(); + outputObject.setreturnMessage("发布失败!"); + } else { + int edit = forumContentDao.editForumContentMationById(map); + if (edit != 1) { + solrClient.rollback(); + outputObject.setreturnMessage("发布失败!"); + } + } + } + } catch (Exception e) { + outputObject.setreturnMessage("发布失败!"); + } + } + } + + /** + * 帖子详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumContentMationToDetails(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumContentDao.queryForumContentMationToDetails(map); + outputObject.setBean(bean); + outputObject.settotal(1); + String userId = inputObject.getLogParams().get("id").toString(); + String forumId = map.get("id").toString(); + // 获取、设置浏览量 + String key = ForumConstants.forumBrowseNumsByForumId(forumId); + if (ToolUtil.isBlank(jedisClient.get(key))) { + jedisClient.set(key, "1"); + } else { + String oldnum = jedisClient.get(key); + jedisClient.set(key, String.valueOf(Integer.parseInt(oldnum) + 1)); + } + // 设置今日被浏览的帖子 + String browseKey = ForumConstants.forumEverydayBrowseIdsByTime(DateUtil.getYmdTimeAndToString()); + if (ToolUtil.isBlank(jedisClient.get(browseKey))) { + jedisClient.set(browseKey, forumId); + jedisClient.set(browseKey, forumId); + } else { + String str = jedisClient.get(browseKey); + if (str.indexOf(forumId) == -1) { + jedisClient.set(browseKey, str + "," + forumId); + } + } + //新增浏览信息 + String keys = ForumConstants.forumBrowseMationByUserid(userId); + List> beans = new ArrayList<>(); + if (ToolUtil.isBlank(jedisClient.get(keys))) { + // 用户之前是否浏览过帖子 + Map m = new HashMap<>(); + m.put("forumId", forumId); + m.put("tagName", bean.get("tagName")); + m.put("title", bean.get("title")); + m.put("desc", bean.get("desc")); + m.put("userPhoto", bean.get("userPhoto")); + m.put("userId", bean.get("userId")); + m.put("browseTime", DateUtil.getTimeAndToString()); + beans.add(m); + jedisClient.set(keys, JSONUtil.toJsonStr(beans)); + } else { + beans = JSONUtil.toList(jedisClient.get(keys), null); + // 用户之前是否浏览过当前帖子,浏览过则更改浏览时间为当前时间 + boolean ifexist = false; + for (Map m : beans) { + if (m.get("forumId").toString().equals(forumId)) { + m.put("tagName", bean.get("tagName")); + m.put("title", bean.get("title")); + m.put("desc", bean.get("desc")); + m.put("userPhoto", bean.get("userPhoto")); + m.put("userId", bean.get("userId")); + m.put("browseTime", DateUtil.getTimeAndToString()); + ifexist = true; + } + } + if (!ifexist) { + // 没有浏览过则新增 + Map m = new HashMap<>(); + m.put("forumId", forumId); + m.put("tagName", bean.get("tagName") == null ? "" : bean.get("tagName")); + m.put("title", bean.get("title")); + m.put("desc", bean.get("desc")); + m.put("userPhoto", bean.get("userPhoto")); + m.put("userId", bean.get("userId")); + m.put("browseTime", DateUtil.getTimeAndToString()); + beans.add(m); + } + jedisClient.set(keys, JSONUtil.toJsonStr(beans)); + } + } + + /** + * 获取最新帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryNewForumContentList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + List> beans = forumContentDao.queryNewForumContentList(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 新增帖子评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumCommentMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("id", ToolUtil.getSurFaceId()); + map.put("commentId", user.get("id")); + map.put("commentTime", DateUtil.getTimeAndToString()); + map.put("belongCommentId", "0"); + map.put("replyId", ""); + forumContentDao.insertForumCommentMation(map); + // 获取、设置评论量 + String key = ForumConstants.forumCommentNumsByForumId(map.get("forumId").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + jedisClient.set(key, "1"); + } else { + String oldnum = jedisClient.get(key); + jedisClient.set(key, String.valueOf(Integer.parseInt(oldnum) + 1)); + } + } + + /** + * 获取帖子评论信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumCommentList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryForumCommentList(map); + for (Map m : beans) { + String commentTime = ToolUtil.timeFormat(m.get("commentTime").toString()); + m.put("commentTime", commentTime); + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 新增帖子评论回复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumReplyMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("id", ToolUtil.getSurFaceId()); + map.put("commentId", user.get("id")); + map.put("commentTime", DateUtil.getTimeAndToString()); + forumContentDao.insertForumReplyMation(map); + // 获取、设置评论量 + String key = ForumConstants.forumCommentNumsByForumId(map.get("forumId").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + jedisClient.set(key, "1"); + } else { + String oldnum = jedisClient.get(key); + jedisClient.set(key, String.valueOf(Integer.parseInt(oldnum) + 1)); + } + } + + /** + * 获取帖子评论回复信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumReplyList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryForumReplyList(map); + for (Map m : beans) { + String commentTime = ToolUtil.timeFormat(m.get("commentTime").toString()); + m.put("commentTime", commentTime); + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取我的浏览信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumMyBrowerList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + String keys = ForumConstants.forumBrowseMationByUserid(userId); + List> beans = new ArrayList<>(); + if (!ToolUtil.isBlank(jedisClient.get(keys))) { + beans = JSONUtil.toList(jedisClient.get(keys), null); + // 按浏览时间给集合排序 + beans.sort(new Comparator>() { + @Override + public int compare(Map m1, Map m2) { + int flag = m1.get("browseTime").toString().compareTo(m2.get("browseTime").toString()); + return -flag; + } + }); + int count = beans.size(); + int pageMaxSize = Integer.parseInt(map.get("page").toString()) * Integer.parseInt(map.get("limit").toString()); + if (count < pageMaxSize) { + pageMaxSize = count; + } + beans = beans.subList((Integer.parseInt(map.get("page").toString()) - 1) * Integer.parseInt(map.get("limit").toString()), pageMaxSize); + for (Map m : beans) { + String key = ForumConstants.forumBrowseNumsByForumId(m.get("forumId").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + m.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + m.put("browseNum", browseNum); + } + Map ma = forumContentDao.selectForumCommentNumById(m); + if (!ToolUtil.isBlank(ma.get("commentNum").toString())) { + // 评论数 + m.put("commentNum", ma.get("commentNum")); + } else { + m.put("commentNum", 0); + } + // 浏览时间 + m.put("browseTime", ToolUtil.timeFormat(m.get("browseTime").toString())); + } + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取最新评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryNewCommentList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryNewCommentList(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 根据标签id获取帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumListByTagId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = new ArrayList<>(); + long total = 0; + if (!map.get("tagId").toString().equals("hot")) { + map.put("userId", inputObject.getLogParams().get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + beans = forumContentDao.queryForumListByTagId(map); + total = pages.getTotal(); + for (Map m : beans) { + String createTime = ToolUtil.timeFormat(m.get("createTime").toString()); + m.put("createTime", createTime); + String key = ForumConstants.forumBrowseNumsByForumId(m.get("id").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + m.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + m.put("browseNum", browseNum); + } + } + } else { + map.put("userId", inputObject.getLogParams().get("id")); + beans = forumContentDao.queryAllHotForumList(map); + for (Map m : beans) { + String createTime = ToolUtil.timeFormat(m.get("createTime").toString()); + m.put("createTime", createTime); + String key = ForumConstants.forumBrowseNumsByForumId(m.get("id").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + m.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + m.put("browseNum", browseNum); + } + } + // 按浏览量和评论数给集合排序 + beans.sort(new Comparator>() { + @Override + public int compare(Map m1, Map m2) { + Integer m1num = Integer.parseInt(m1.get("browseNum").toString()) + Integer.parseInt(m1.get("commentNum").toString()); + Integer m2num = Integer.parseInt(m2.get("browseNum").toString()) + Integer.parseInt(m2.get("commentNum").toString()); + int flag = m1num.compareTo(m2num); + return -flag; + } + }); + int count = beans.size(); + int pageMaxSize = Integer.parseInt(map.get("page").toString()) * Integer.parseInt(map.get("limit").toString()); + if (count < pageMaxSize) { + pageMaxSize = count; + } + beans = beans.subList((Integer.parseInt(map.get("page").toString()) - 1) * Integer.parseInt(map.get("limit").toString()), pageMaxSize); + total = count; + } + outputObject.setBeans(beans); + outputObject.settotal(total); + } + + /** + * 获取热门标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryHotTagList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryHotTagList(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取活跃用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryActiveUsersList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryActiveUsersList(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取热门贴 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryHotForumList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + List> beans = forumContentDao.queryHotForumList(map); + for (Map m : beans) { + String createTime = ToolUtil.timeFormat(m.get("createTime").toString()); + m.put("createTime", createTime); + String key = ForumConstants.forumBrowseNumsByForumId(m.get("id").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + m.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + m.put("browseNum", browseNum); + } + } + //按浏览量和评论数给集合排序 + beans.sort(new Comparator>() { + @Override + public int compare(Map m1, Map m2) { + Integer m1num = Integer.parseInt(m1.get("browseNum").toString()) + Integer.parseInt(m1.get("commentNum").toString()); + Integer m2num = Integer.parseInt(m2.get("browseNum").toString()) + Integer.parseInt(m2.get("commentNum").toString()); + int flag = m1num.compareTo(m2num); + return -flag; + } + }); + int count = beans.size(); + int pageMaxSize = 6; + if (count < pageMaxSize) { + pageMaxSize = count; + } + outputObject.setBeans(beans.subList(0, pageMaxSize)); + outputObject.settotal(beans.size()); + } + + /** + * 获取用户搜索的帖子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySearchForumList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String searchValue = map.get("searchValue").toString(); + List> beans = new ArrayList<>(); + List> rbeans = new ArrayList<>(); + // 关键字模糊查询 + SolrQuery query = new SolrQuery(); + String forumTitle = "forumTitle:" + searchValue; + String forumDesc = " OR forumDesc:" + searchValue; + String forumContent = " OR forumContent:" + searchValue; + query.set("q", forumTitle + forumDesc + forumContent); + query.setStart(0); + query.setRows(20); + query.setHighlight(true); //开启高亮 + query.addHighlightField("forumContent"); //高亮字段 + query.setHighlightSimplePre(""); //高亮单词的前缀 + query.setHighlightSimplePost(""); //高亮单词的后缀 + query.setHighlightFragsize(400); + int count = 0; + String createId = inputObject.getLogParams().get("id").toString(); + try { + QueryResponse response = solrClient.query(query); + SolrDocumentList documentList = response.getResults(); + for (SolrDocument document : documentList) { + beans.add(document); + } + Map>> maplist = response.getHighlighting(); + if (beans != null) { + for (Map m : beans) { + if (m.get("type").toString().replaceAll("\\[|\\]", "").substring(0, 1).equals("1")) { + for (String key : maplist.keySet()) { + if (key.equals(m.get("id").toString())) { + Map> fieldMap = maplist.get(key); + if (fieldMap.size() > 0) { + m.put("forumContent", "..." + fieldMap.get("forumContent").get(0)); + } + } + } + rbeans.add(m); + } else { + if (m.get("createId").toString().replaceAll("\\[|\\]", "").equals(createId)) { + for (String key : maplist.keySet()) { + if (key.equals(m.get("id").toString())) { + Map> fieldMap = maplist.get(key); + if (fieldMap.size() > 0) { + m.put("forumContent", "..." + fieldMap.get("forumContent").get(0)); + } + } + } + rbeans.add(m); + } + } + } + } + count = rbeans.size(); + } catch (SolrServerException e) { + outputObject.setreturnMessage("搜索失败!"); + } catch (Exception e) { + outputObject.setreturnMessage("搜索失败!"); + } + outputObject.setBeans(rbeans); + outputObject.settotal(count); + } + + /** + * 获取solr上次同步数据的时间 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySolrSynchronousTime(InputObject inputObject, OutputObject outputObject) { + Map map = new HashMap<>(); + String keys = ForumConstants.forumSolrSynchronoustime(); + if (!ToolUtil.isBlank(jedisClient.get(keys))) { + String synchronousTime = jedisClient.get(keys); + map.put("synchronousTime", synchronousTime); + } + outputObject.setBean(map); + outputObject.settotal(1); + } + + /** + * solr同步数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void updateSolrSynchronousData(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = forumContentDao.queryAllForumList(map); + DocumentObjectBinder binder = new DocumentObjectBinder(); + try { + for (Map t : beans) { + Forum forum = new Forum(); + forum.setId(t.get("id").toString()); + forum.setForumTitle(t.get("title").toString()); + forum.setForumContent(t.get("content").toString()); + forum.setForumDesc(t.get("desc").toString()); + forum.setType(t.get("forumType").toString()); + forum.setCreateId(t.get("createId").toString()); + SolrInputDocument doc = binder.toSolrInputDocument(forum); + solrClient.add(doc); + } + solrClient.commit(); + String keys = ForumConstants.forumSolrSynchronoustime(); + String nowTime = DateUtil.getTimeAndToString(); + if (!ToolUtil.isBlank(jedisClient.get(keys))) { + jedisClient.del(keys); + jedisClient.set(keys, nowTime); + } else { + jedisClient.set(keys, nowTime); + } + map.put("synchronousTime", nowTime); + } catch (SolrServerException e) { + outputObject.setreturnMessage("同步失败!"); + } catch (Exception e) { + outputObject.setreturnMessage("同步失败!"); + } + outputObject.setBean(map); + outputObject.settotal(1); + } + + /** + * 获取我的帖子列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyCommentList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumContentDao.queryMyCommentList(map); + for (Map m : beans) { + String commentTime = ToolUtil.timeFormat(m.get("commentTime").toString()); + m.put("commentTime", commentTime); + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 根据评论id删除评论 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteCommentById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + forumContentDao.deleteCommentById(map); + } + + /** + * 获取我的通知列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyNoticeList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumContentDao.queryMyNoticeList(map); + for (Map m : beans) { + String sendTime = ToolUtil.timeFormat(m.get("sendTime").toString()); + m.put("sendTime", sendTime); + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 根据通知id删除通知 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteNoticeById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + forumContentDao.deleteNoticeById(map); + } + + /** + * 查找内容中的包含的敏感词 + * + * @param map + * @return + */ + public String querySensitiveWordsByMap(Map map) { + String content = map.get("title").toString() + "," + map.get("textConent").toString(); + List> sensitiveWords; + if (ToolUtil.isBlank(jedisClient.get(ForumConstants.forumSensitiveWordsAll()))) { + sensitiveWords = forumSensitiveWordsDao.queryForumSensitiveWordsListAll(); + jedisClient.set(ForumConstants.forumSensitiveWordsAll(), JSONUtil.toJsonStr(sensitiveWords)); + } else { + sensitiveWords = JSONUtil.toList(jedisClient.get(ForumConstants.forumSensitiveWordsAll()), null); + } + SensitiveWordInit sensitiveWordInit = new SensitiveWordInit(); + Map sensitiveWordMap = sensitiveWordInit.initKeyWord(sensitiveWords); + SensitivewordEngine.sensitiveWordMap = sensitiveWordMap; + Set set = SensitivewordEngine.getSensitiveWord(content, 2); + String str = ""; + if (set.size() > 0) { + for (String s : set) { + str += s + "、"; + } + } + return str; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumReportServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumReportServiceImpl.java new file mode 100644 index 0000000..34c27eb --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumReportServiceImpl.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.forum.dao.ForumReportDao; +import com.skyeye.eve.forum.service.ForumReportService; +import com.skyeye.eve.service.ISysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ForumReportServiceImpl + * @Description: 论坛内容举报管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ForumReportServiceImpl implements ForumReportService { + + @Autowired + private ForumReportDao forumReportDao; + + @Autowired + private ISysDictDataService iSysDictDataService; + + /** + * 新增举报信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumReportMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("reportId", user.get("id")); + map.put("reportTime", DateUtil.getTimeAndToString()); + map.put("id", ToolUtil.getSurFaceId()); + map.put("examineState", "1"); + forumReportDao.insertForumReportMation(map); + } + + /** + * 获取论坛举报未审核列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryReportNoCheckList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumReportDao.queryReportNoCheckList(map); + iSysDictDataService.setNameForMap(beans, "reportTypeId", "reportType"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 举报信息审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editReportCheckMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map beans = forumReportDao.queryForumReportStateById(map); + if ("1".equals(beans.get("examineState").toString())) {//未审核的状态可以审核 + Map user = inputObject.getLogParams(); + map.put("examineId", user.get("id")); + map.put("examineTime", DateUtil.getTimeAndToString()); + int edit = forumReportDao.editReportCheckMationById(map); + if (edit == 1) { + if (map.get("examineState").toString().equals("2")) { + // 审核通过,通知举报人和发帖人 + Map m = forumReportDao.queryForumReportMationById(map); + Map bean = new HashMap<>(); + bean.put("id", ToolUtil.getSurFaceId()); + bean.put("noticeContent", map.get("examineState")); + bean.put("noticeTitle", "违规"); + bean.put("forumId", m.get("forumId")); + bean.put("receiveId", m.get("createId")); + bean.put("type", 1); + bean.put("state", 1); + bean.put("createTime", DateUtil.getTimeAndToString()); + // 通知发帖人 + forumReportDao.insertForumNoticeMation(bean); + bean.put("id", ToolUtil.getSurFaceId()); + bean.put("receiveId", m.get("reportId")); + bean.put("noticeTitle", "举报"); + // 通知举报人 + forumReportDao.insertForumNoticeMation(bean); + } else if (map.get("examineState").toString().equals("3")) { + // 审核不通过,通知举报人 + Map m = forumReportDao.queryForumReportMationById(map); + Map bean = new HashMap<>(); + bean.put("id", ToolUtil.getSurFaceId()); + bean.put("noticeContent", map.get("examineState")); + bean.put("noticeTitle", "举报"); + bean.put("forumId", m.get("forumId")); + bean.put("receiveId", m.get("reportId")); + bean.put("type", 1); + bean.put("state", 1); + bean.put("createTime", DateUtil.getTimeAndToString()); + forumReportDao.insertForumNoticeMation(bean); + } + } + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 获取论坛举报已审核列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryReportCheckedList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumReportDao.queryReportCheckedList(map); + iSysDictDataService.setNameForMap(beans, "reportTypeId", "reportType"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 举报详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumReportMationToDetails(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumReportDao.queryForumReportMationToDetails(map); + iSysDictDataService.setNameForMap(bean, "reportTypeId", "reportType"); + outputObject.setBean(bean); + outputObject.settotal(1); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumSensitiveWordsServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumSensitiveWordsServiceImpl.java new file mode 100644 index 0000000..e000864 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumSensitiveWordsServiceImpl.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.constans.ForumConstants; +import com.skyeye.eve.forum.dao.ForumSensitiveWordsDao; +import com.skyeye.eve.forum.service.ForumSensitiveWordsService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ForumSensitiveWordsServiceImpl + * @Description: 论坛敏感词管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ForumSensitiveWordsServiceImpl implements ForumSensitiveWordsService { + + @Autowired + private ForumSensitiveWordsDao forumSensitiveWordsDao; + + @Autowired + private JedisClientService jedisClient; + + /** + * 查出所有论坛敏感词列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumSensitiveWordsList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumSensitiveWordsDao.queryForumSensitiveWordsList(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增论坛敏感词 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumSensitiveWordsMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumSensitiveWordsDao.queryForumSensitiveWordsMationByName(map); + if (!CollectionUtils.isEmpty(bean)) { + outputObject.setreturnMessage("该论坛敏感词名称已存在,请更换"); + } else { + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + forumSensitiveWordsDao.insertForumSensitiveWordsMation(map); + jedisClient.del(ForumConstants.forumSensitiveWordsAll()); + } + } + + /** + * 删除论坛敏感词 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + forumSensitiveWordsDao.deleteForumSensitiveWordsById(map); + jedisClient.del(ForumConstants.forumSensitiveWordsAll()); + } + + /** + * 通过id查找对应的论坛敏感词信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void selectForumSensitiveWordsById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumSensitiveWordsDao.selectForumSensitiveWordsById(map); + outputObject.setBean(bean); + outputObject.settotal(1); + } + + /** + * 通过id编辑对应的论坛敏感词信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editForumSensitiveWordsMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumSensitiveWordsDao.queryForumSensitiveWordsMationByName(map); + if (!CollectionUtils.isEmpty(bean)) { + outputObject.setreturnMessage("该论坛敏感词名称已存在,请更换"); + } else { + forumSensitiveWordsDao.editForumSensitiveWordsMationById(map); + jedisClient.del(ForumConstants.forumSensitiveWordsAll()); + } + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumTagServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumTagServiceImpl.java new file mode 100644 index 0000000..3dd630b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/service/impl/ForumTagServiceImpl.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.service.impl; + +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.constans.ForumConstants; +import com.skyeye.eve.forum.dao.ForumTagDao; +import com.skyeye.eve.forum.service.ForumTagService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ForumTagServiceImpl + * @Description: 论坛标签管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ForumTagServiceImpl implements ForumTagService { + + @Autowired + private ForumTagDao forumTagDao; + + @Autowired + private JedisClientService jedisClient; + + /** + * 查出所有论坛标签列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumTagList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = forumTagDao.queryForumTagList(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertForumTagMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.queryForumTagMationByName(map); + if (!CollectionUtils.isEmpty(bean)) { + outputObject.setreturnMessage("该论坛标签名称已存在,请更换"); + } else { + Map itemCount = forumTagDao.queryForumTagBySimpleLevel(map); + int thisOrderBy = Integer.parseInt(itemCount.get("simpleNum").toString()) + 1; + map.put("orderBy", thisOrderBy); + // 默认新建 + map.put("state", "1"); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + forumTagDao.insertForumTagMation(map); + } + } + + /** + * 删除论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteForumTagById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.queryForumTagStateById(map); + if ("1".equals(bean.get("state").toString()) || "3".equals(bean.get("state").toString())) { + // 新建或者下线可以删除 + forumTagDao.deleteForumTagById(map); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 上线论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void updateUpForumTagById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.queryForumTagStateById(map); + if ("1".equals(bean.get("state").toString()) || "3".equals(bean.get("state").toString())) { + // 新建或者下线可以上线 + forumTagDao.updateUpForumTagById(map); + // 删除上线论坛标签的redis + jedisClient.del(ForumConstants.FORUM_TAG_UP_STATE_LIST); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 下线论坛标签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void updateDownForumTagById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.queryForumTagStateById(map); + if ("2".equals(bean.get("state").toString())) { + // 上线状态可以下线 + forumTagDao.updateDownForumTagById(map); + // 删除上线论坛标签的redis + jedisClient.del(ForumConstants.FORUM_TAG_UP_STATE_LIST); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 通过id查找对应的论坛标签信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void selectForumTagById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.selectForumTagById(map); + outputObject.setBean(bean); + outputObject.settotal(1); + } + + /** + * 通过id编辑对应的论坛标签信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editForumTagMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = forumTagDao.queryForumTagStateById(map); + if ("1".equals(bean.get("state").toString()) || "3".equals(bean.get("state").toString())) { + // 新建或者下线可以编辑 + Map b = forumTagDao.queryForumTagMationByName(map); + if (b != null && !b.isEmpty()) { + outputObject.setreturnMessage("该论坛标签名称已存在,请更换"); + } else { + forumTagDao.editForumTagMationById(map); + } + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 论坛标签上移 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editForumTagMationOrderNumUpById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 获取当前数据的同级分类下的上一条数据 + Map bean = forumTagDao.queryForumTagUpMationById(map); + if (CollectionUtils.isEmpty(bean)) { + outputObject.setreturnMessage("当前标签已经是首位,无须进行上移。"); + } else { + // 进行位置交换 + map.put("upOrderBy", bean.get("prevOrderBy")); + bean.put("upOrderBy", bean.get("thisOrderBy")); + forumTagDao.editForumTagMationOrderNumUpById(map); + forumTagDao.editForumTagMationOrderNumUpById(bean); + // 删除上线论坛标签的redis + jedisClient.del(ForumConstants.FORUM_TAG_UP_STATE_LIST); + } + } + + /** + * 论坛标签下移 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editForumTagMationOrderNumDownById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 获取当前数据的同级分类下的下一条数据 + Map bean = forumTagDao.queryForumTagDownMationById(map); + if (CollectionUtils.isEmpty(bean)) { + outputObject.setreturnMessage("当前标签已经是末位,无须进行下移。"); + } else { + // 进行位置交换 + map.put("upOrderBy", bean.get("prevOrderBy")); + bean.put("upOrderBy", bean.get("thisOrderBy")); + forumTagDao.editForumTagMationOrderNumUpById(map); + forumTagDao.editForumTagMationOrderNumUpById(bean); + // 删除上线论坛标签的redis + jedisClient.del(ForumConstants.FORUM_TAG_UP_STATE_LIST); + } + } + + /** + * 获取已经上线的论坛标签列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryForumTagUpStateList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans; + if (ToolUtil.isBlank(jedisClient.get(ForumConstants.FORUM_TAG_UP_STATE_LIST))) { + beans = forumTagDao.queryForumTagUpStateList(map); + jedisClient.set(ForumConstants.FORUM_TAG_UP_STATE_LIST, JSONUtil.toJsonStr(beans)); + } else { + beans = JSONUtil.toList(jedisClient.get(ForumConstants.FORUM_TAG_UP_STATE_LIST), null); + } + if (!beans.isEmpty()) { + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/solr/Forum.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/solr/Forum.java new file mode 100644 index 0000000..260aee7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/forum/solr/Forum.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.forum.solr; + +import lombok.Data; +import org.apache.solr.client.solrj.beans.Field; +import org.springframework.data.solr.core.mapping.SolrDocument; + +import java.io.Serializable; + +@Data +@SolrDocument(solrCoreName = "custom_core") +public class Forum implements Serializable { + + private static final long serialVersionUID = 1L; + + @Field + private String id; + @Field + private String forumContent; + @Field + private String type; + @Field + private String state; + @Field + private String reportState; + @Field + private String tagId; + @Field + private String forumTitle; + @Field + private String forumDesc; + @Field + private String anonymous; + @Field + private String createId; + @Field + private String createTime; + + public Forum() { + } + + public Forum(String id, String forumContent, String type, String state, String reportState, String tagId, + String forumTitle, String forumDesc, String anonymous, String createId, String createTime) { + this.id = id; + this.forumContent = forumContent; + this.type = type; + this.state = state; + this.reportState = reportState; + this.tagId = tagId; + this.forumTitle = forumTitle; + this.forumDesc = forumDesc; + this.anonymous = anonymous; + this.createId = createId; + this.createTime = createTime; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentOpenCategory.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentOpenCategory.java new file mode 100644 index 0000000..dc92d6c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentOpenCategory.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: GwDocumentOpenCategory + * @Description: 公开类别枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum GwDocumentOpenCategory implements SkyeyeEnumClass { + PROACTIVELY_DISCLOSE(1, "主动公开", true, true), + ACCORDING_TO_THE_APPLICATION(2, "依申请公开", true, false), + NOT_TO_DISCLOSED(3, "不予公开", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (GwDocumentOpenCategory value : GwDocumentOpenCategory.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentPeriod.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentPeriod.java new file mode 100644 index 0000000..872b879 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentPeriod.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: GwDocumentPeriod + * @Description: 保密期间枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum GwDocumentPeriod implements SkyeyeEnumClass { + SHORT_TERM(1, "短期", true, true), + LONG_TERM(2, "长期", true, false), + PERMANENT(3, "永久", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (GwDocumentPeriod value : GwDocumentPeriod.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentSecret.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentSecret.java new file mode 100644 index 0000000..c755eaf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentSecret.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: GwDocumentSecret + * @Description: 公文密级枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum GwDocumentSecret implements SkyeyeEnumClass { + INSIDE(1, "内部", true, true), + SECRET(2, "秘密", true, false), + CONFIDENTIAL(3, "机密", true, false), + TOP_SECRET(4, "绝密", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (GwDocumentSecret value : GwDocumentSecret.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentUrgency.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentUrgency.java new file mode 100644 index 0000000..e4f8020 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/classenum/GwDocumentUrgency.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: GwDocumentUrgency + * @Description: 紧急程度枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum GwDocumentUrgency implements SkyeyeEnumClass { + COMMONLY(1, "一般", true, true), + URGENT(2, "紧急", true, false), + EXTRA_GRADE(3, "特级", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (GwDocumentUrgency value : GwDocumentUrgency.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwModelController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwModelController.java new file mode 100644 index 0000000..1d39afd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwModelController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwModel; +import com.skyeye.eve.gw.service.GwModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: GwModelController + * @Description: 公文模版控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/29 9:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "公文模版", tags = "公文模版", modelName = "公文模版") +public class GwModelController { + + @Autowired + private GwModelService gwModelService; + + /** + * 查询公文模版列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryGwModelList", value = "查询公文模版列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/GwModelController/queryGwModelList") + public void queryGwModelList(InputObject inputObject, OutputObject outputObject) { + gwModelService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改公文模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeGwModel", value = "新增/修改公文模版信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = GwModel.class) + @RequestMapping("/post/GwModelController/writeGwModel") + public void writeGwModel(InputObject inputObject, OutputObject outputObject) { + gwModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除公文模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteGwModelById", value = "根据id删除公文模版信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/GwModelController/deleteGwModelById") + public void deleteGwModelById(InputObject inputObject, OutputObject outputObject) { + gwModelService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启用的公文模版列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledGwModelList", value = "获取所有启用的公文模版列表", method = "GET", allUse = "2") + @RequestMapping("/post/GwModelController/queryEnabledGwModelList") + public void queryAllGwModelList(InputObject inputObject, OutputObject outputObject) { + gwModelService.queryEnabledGwModelList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwReceiveDocumentController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwReceiveDocumentController.java new file mode 100644 index 0000000..f2107a6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwReceiveDocumentController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwReceiveDocument; +import com.skyeye.eve.gw.service.GwReceiveDocumentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: GwReceiveDocumentController + * @Description: 公文收文管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 22:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "公文收文管理", tags = "公文收文管理", modelName = "公文收文管理") +public class GwReceiveDocumentController { + + @Autowired + private GwReceiveDocumentService gwReceiveDocumentService; + + /** + * 获取公文收文列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryGwReceiveDocumentList", value = "获取公文收文列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/GwReceiveDocumentController/queryGwReceiveDocumentList") + public void queryGwReceiveDocumentList(InputObject inputObject, OutputObject outputObject) { + gwReceiveDocumentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑公文收文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeGwReceiveDocument", value = "新增/编辑公文收文", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = GwReceiveDocument.class) + @RequestMapping("/post/GwReceiveDocumentController/writeGwReceiveDocument") + public void writeGwReceiveDocument(InputObject inputObject, OutputObject outputObject) { + gwReceiveDocumentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 公文收文提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitGwReceiveDocumentToApproval", value = "公文收文提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/GwReceiveDocumentController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + gwReceiveDocumentService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废公文收文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidGwReceiveDocument", value = "作废公文收文", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/GwReceiveDocumentController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + gwReceiveDocumentService.invalid(inputObject, outputObject); + } + + /** + * 撤销公文收文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeGwReceiveDocument", value = "撤销公文收文", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/GwReceiveDocumentController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + gwReceiveDocumentService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwSendDocumentController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwSendDocumentController.java new file mode 100644 index 0000000..d886ba3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwSendDocumentController.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwSendDocument; +import com.skyeye.eve.gw.service.GwSendDocumentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: GwSendDocumentController + * @Description: 公文发文管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 15:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "公文发文管理", tags = "公文发文管理", modelName = "公文发文管理") +public class GwSendDocumentController { + + @Autowired + private GwSendDocumentService gwSendDocumentService; + + /** + * 获取公文发文列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryGwSendDocumentList", value = "获取公文发文列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/GwSendDocumentController/queryGwSendDocumentList") + public void queryGwSendDocumentList(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑公文发文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeGwSendDocument", value = "新增/编辑公文发文", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = GwSendDocument.class) + @RequestMapping("/post/GwSendDocumentController/writeGwSendDocument") + public void writeGwSendDocument(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 公文发文提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitGwSendDocumentToApproval", value = "公文发文提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/GwSendDocumentController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.submitToApproval(inputObject, outputObject); + } + + /** + * 公文发文详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryGwSendDocumentById", value = "公文发文详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/GwSendDocumentController/queryGwSendDocumentById") + public void queryGwSendDocumentById(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.selectById(inputObject, outputObject); + } + + /** + * 作废公文发文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidGwSendDocument", value = "作废公文发文", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/GwSendDocumentController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.invalid(inputObject, outputObject); + } + + /** + * 撤销公文发文 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeGwSendDocument", value = "撤销公文发文", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/GwSendDocumentController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + gwSendDocumentService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwTemplatesController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwTemplatesController.java new file mode 100644 index 0000000..ed23e1f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/controller/GwTemplatesController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwTemplates; +import com.skyeye.eve.gw.service.GwTemplatesService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: GwTemplatesController + * @Description: 套红模板控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 10:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "套红模板", tags = "套红模板", modelName = "套红模板") +public class GwTemplatesController { + + @Autowired + private GwTemplatesService gwTemplatesService; + + /** + * 查询套红模版列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryGwTemplatesList", value = "查询套红模版列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/GwTemplatesController/queryGwTemplatesList") + public void queryGwTemplatesList(InputObject inputObject, OutputObject outputObject) { + gwTemplatesService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改套红模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeGwTemplates", value = "新增/修改套红模版信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = GwTemplates.class) + @RequestMapping("/post/GwTemplatesController/writeGwTemplates") + public void writeGwTemplates(InputObject inputObject, OutputObject outputObject) { + gwTemplatesService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除套红模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteGwTemplatesById", value = "根据id删除套红模版信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/GwTemplatesController/deleteGwTemplatesById") + public void deleteGwTemplatesById(InputObject inputObject, OutputObject outputObject) { + gwTemplatesService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启用的套红模版列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledGwTemplatesList", value = "获取所有启用的套红模版列表", method = "GET", allUse = "2") + @RequestMapping("/post/GwTemplatesController/queryEnabledGwTemplatesList") + public void queryAllGwTemplatesList(InputObject inputObject, OutputObject outputObject) { + gwTemplatesService.queryEnabledGwTemplatesList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwModelDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwModelDao.java new file mode 100644 index 0000000..93745ba --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwModelDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.gw.entity.GwModel; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwModelDao + * @Description: 公文模版数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/29 9:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwModelDao extends SkyeyeBaseMapper { + + List> queryGwModelList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwReceiveDocumentDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwReceiveDocumentDao.java new file mode 100644 index 0000000..cfcfded --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwReceiveDocumentDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.gw.entity.GwReceiveDocument; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwReceiveDocumentDao + * @Description: 公文收文管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 22:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwReceiveDocumentDao extends SkyeyeBaseMapper { + + List> queryGwReceiveDocumentList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwSendDocumentDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwSendDocumentDao.java new file mode 100644 index 0000000..15d105c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwSendDocumentDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.gw.entity.GwSendDocument; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwSendDocumentDao + * @Description: 公文发文管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 15:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwSendDocumentDao extends SkyeyeBaseMapper { + + List> queryGwSendDocumentList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwTemplatesDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwTemplatesDao.java new file mode 100644 index 0000000..c49a05d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/dao/GwTemplatesDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.gw.entity.GwTemplates; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwTemplatesDao + * @Description: 套红模板数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 11:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwTemplatesDao extends SkyeyeBaseMapper { + + List> queryGwTemplatesList(CommonPageInfo pageInfo); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwModel.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwModel.java new file mode 100644 index 0000000..a17bf22 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwModel.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: GwModel + * @Description: 公文模版实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/29 9:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "gw:model", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "gw_model") +@ApiModel("公文模版实体类") +public class GwModel extends BaseGeneralInfo { + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "path") + @ApiModelProperty(value = "模版地址", required = "required") + private String path; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwReceiveDocument.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwReceiveDocument.java new file mode 100644 index 0000000..c6733d7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwReceiveDocument.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwReceiveDocument + * @Description: 公文收文管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "gw:receiveDocument", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "gw_receive_document", autoResultMap = true) +@ApiModel("公文收文管理实体类") +public class GwReceiveDocument extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("secret") + @ApiModelProperty(value = "密级级别,参考#GwDocumentSecret", required = "num") + private Integer secret; + + @TableField("period") + @ApiModelProperty(value = "保密期间,参考#GwDocumentPeriod", required = "num") + private Integer period; + + @TableField("urgency") + @ApiModelProperty(value = "紧急程度,参考#GwDocumentUrgency", required = "num") + private Integer urgency; + + @TableField("open_category") + @ApiModelProperty(value = "公开类别,参考#GwDocumentOpenCategory", required = "num") + private Integer openCategory; + + @TableField("year") + @ApiModelProperty(value = "年份", required = "required") + private String year; + + @TableField("number") + @ApiModelProperty(value = "第几号文", required = "required") + private String number; + + @TableField("enterprise") + @ApiModelProperty(value = "企字", required = "required") + private String enterprise; + + @TableField("receive_time") + @ApiModelProperty(value = "收文日期", required = "required") + private String receiveTime; + + @TableField("send_department_name") + @ApiModelProperty(value = "发文部门名称") + private String sendDepartmentName; + + @TableField(value = "receive_department_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "收文的部门id") + private List receiveDepartmentId; + + @TableField(exist = false) + @Property("收文的部门信息") + private List> receiveDepartmentMation; + + @TableField("content") + @ApiModelProperty(value = "内容") + private String content; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwSendDocument.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwSendDocument.java new file mode 100644 index 0000000..aa78acd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwSendDocument.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwSendDocument + * @Description: 公文发文管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 22:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "gw:sendDocument", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "gw_send_document", autoResultMap = true) +@ApiModel("公文发文管理实体类") +public class GwSendDocument extends SkyeyeFlowable { + + @TableField("template_id") + @ApiModelProperty(value = "套红模版id", required = "required") + private String templateId; + + @TableField(exist = false) + @Property("套红模版信息") + private GwTemplates templateMation; + + @TableField("model_id") + @ApiModelProperty(value = "公文模版id", required = "required") + private String modelId; + + @TableField(exist = false) + @Property("公文模版信息") + private GwModel modelMation; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("secret") + @ApiModelProperty(value = "密级级别,参考#GwDocumentSecret", required = "num") + private Integer secret; + + @TableField("period") + @ApiModelProperty(value = "保密期间,参考#GwDocumentPeriod", required = "num") + private Integer period; + + @TableField("urgency") + @ApiModelProperty(value = "紧急程度,参考#GwDocumentUrgency", required = "num") + private Integer urgency; + + @TableField("open_category") + @ApiModelProperty(value = "公开类别,参考#GwDocumentOpenCategory", required = "num") + private Integer openCategory; + + @TableField("year") + @ApiModelProperty(value = "年份", required = "required") + private String year; + + @TableField("number") + @ApiModelProperty(value = "第几号文", required = "required") + private String number; + + @TableField("enterprise") + @ApiModelProperty(value = "企字", required = "required") + private String enterprise; + + @TableField("send_time") + @ApiModelProperty(value = "发文日期", required = "required") + private String sendTime; + + @TableField("send_department_id") + @ApiModelProperty(value = "发文部门id") + private String sendDepartmentId; + + @TableField(exist = false) + @Property("发文部门信息") + private Map sendDepartmentMation; + + @TableField(value = "cc_department_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "抄送部门id") + private List ccDepartmentId; + + @TableField(exist = false) + @Property("抄送部门信息") + private List> ccDepartmentMation; + + @TableField(value = "receive_department_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "收文的部门id") + private List receiveDepartmentId; + + @TableField(exist = false) + @Property("收文的部门信息") + private List> receiveDepartmentMation; + + @TableField("content") + @ApiModelProperty(value = "内容") + private String content; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "path") + @Property(value = "公文文件地址") + private String path; + + @TableField(value = "pic_path") + @Property(value = "公文图片文件地址") + private String picPath; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwTemplates.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwTemplates.java new file mode 100644 index 0000000..09f82f0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/entity/GwTemplates.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.eve.seal.entity.Seal; +import lombok.Data; + +/** + * @ClassName: GwTemplates + * @Description: 套红模板实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "gw:templates", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "gw_templates") +@ApiModel("套红模板实体类") +public class GwTemplates extends BaseGeneralInfo { + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "seal_id") + @ApiModelProperty(value = "公章id", required = "required") + private String sealId; + + @TableField(exist = false) + @Property("公章信息") + private Seal sealMation; + + @TableField(value = "red_head") + @ApiModelProperty(value = "红头标题") + private String redHead; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwModelService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwModelService.java new file mode 100644 index 0000000..73ae6c2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwModelService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwModel; + +/** + * @ClassName: GwModelService + * @Description: 公文模版服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/29 9:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwModelService extends SkyeyeBusinessService { + + void queryEnabledGwModelList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwReceiveDocumentService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwReceiveDocumentService.java new file mode 100644 index 0000000..dc193dd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwReceiveDocumentService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.gw.entity.GwReceiveDocument; + +/** + * @ClassName: GwReceiveDocumentService + * @Description: 公文收文管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 22:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwReceiveDocumentService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwSendDocumentService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwSendDocumentService.java new file mode 100644 index 0000000..949e5cd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwSendDocumentService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.gw.entity.GwSendDocument; + +/** + * @ClassName: GwSendDocumentService + * @Description: 公文发文管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 15:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwSendDocumentService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwTemplatesService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwTemplatesService.java new file mode 100644 index 0000000..aa499d3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/GwTemplatesService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.gw.entity.GwTemplates; + +/** + * @ClassName: GwTemplatesService + * @Description: 套红模板服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 11:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface GwTemplatesService extends SkyeyeBusinessService { + + void queryEnabledGwTemplatesList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwModelServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwModelServiceImpl.java new file mode 100644 index 0000000..48b940a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwModelServiceImpl.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.gw.dao.GwModelDao; +import com.skyeye.eve.gw.entity.GwModel; +import com.skyeye.eve.gw.service.GwModelService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwModelServiceImpl + * @Description: 公文模版服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/29 9:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "公文模版", groupName = "公文模版") +public class GwModelServiceImpl extends SkyeyeBusinessServiceImpl implements GwModelService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryGwModelList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(GwModel entity) { + super.validatorEntity(entity); + if (!entity.getPath().endsWith(".docx")) { + throw new CustomException("目前仅支持docx类型的word文档"); + } + } + + @Override + public void updatePrepose(GwModel entity) { + GwModel oldModel = selectById(entity.getId()); + if (!StrUtil.equals(entity.getPath(), oldModel.getPath())) { + // 如果文件有修改,则需要删除之前的文件 + FileUtil.deleteFile(tPath.replace("images", StrUtil.EMPTY) + oldModel.getPath()); + } + } + + @Override + public void queryEnabledGwModelList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(GwModel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List gwModels = list(queryWrapper); + outputObject.setBeans(gwModels); + outputObject.settotal(gwModels.size()); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwReceiveDocumentServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwReceiveDocumentServiceImpl.java new file mode 100644 index 0000000..1b49fa7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwReceiveDocumentServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service.impl; + +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.gw.dao.GwReceiveDocumentDao; +import com.skyeye.eve.gw.entity.GwReceiveDocument; +import com.skyeye.eve.gw.service.GwReceiveDocumentService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwReceiveDocumentServiceImpl + * @Description: 公文收文管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 22:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "公文收文管理", groupName = "公文收文管理", flowable = true) +public class GwReceiveDocumentServiceImpl extends SkyeyeFlowableServiceImpl implements GwReceiveDocumentService { + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryGwReceiveDocumentList(pageInfo); + return beans; + } + + @Override + public GwReceiveDocument selectById(String id) { + GwReceiveDocument gwReceiveDocument = super.selectById(id); + String departmentIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(gwReceiveDocument.getReceiveDepartmentId()); + List> departmentList = iDepmentService.queryDataMationByIds(departmentIdStr); + gwReceiveDocument.setReceiveDepartmentMation(departmentList); + return gwReceiveDocument; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwSendDocumentServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwSendDocumentServiceImpl.java new file mode 100644 index 0000000..db64829 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwSendDocumentServiceImpl.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.data.Pictures; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.eve.gw.classenum.GwDocumentOpenCategory; +import com.skyeye.eve.gw.classenum.GwDocumentPeriod; +import com.skyeye.eve.gw.classenum.GwDocumentSecret; +import com.skyeye.eve.gw.classenum.GwDocumentUrgency; +import com.skyeye.eve.gw.dao.GwSendDocumentDao; +import com.skyeye.eve.gw.entity.GwModel; +import com.skyeye.eve.gw.entity.GwSendDocument; +import com.skyeye.eve.gw.entity.GwTemplates; +import com.skyeye.eve.gw.service.GwModelService; +import com.skyeye.eve.gw.service.GwSendDocumentService; +import com.skyeye.eve.gw.service.GwTemplatesService; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.util.OfficeUtils; +import org.ddr.poi.html.HtmlRenderPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwSendDocumentServiceImpl + * @Description: 公文发文管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/26 15:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "公文发文管理", groupName = "公文发文管理", flowable = true) +public class GwSendDocumentServiceImpl extends SkyeyeFlowableServiceImpl implements GwSendDocumentService { + + @Autowired + private GwTemplatesService gwTemplatesService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private GwModelService gwModelService; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setState(FlowableStateEnum.PASS.getKey()); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + pageInfo.setDepartmentId(inputObject.getLogParams().get("departmentId").toString()); + List> beans = skyeyeBaseMapper.queryGwSendDocumentList(pageInfo); + iDepmentService.setMationForMap(beans, "sendDepartmentId", "sendDepartmentMation"); + gwTemplatesService.setMationForMap(beans, "templateId", "templateMation"); + gwModelService.setMationForMap(beans, "modelId", "modelMation"); + return beans; + } + + @Override + public void createPrepose(GwSendDocument entity) { + super.createPrepose(entity); + saveGwFile(entity); + } + + @Override + protected void updatePrepose(GwSendDocument entity) { + GwSendDocument oldMation = selectById(entity.getId()); + FileUtil.deleteFile(tPath.replace("images", StrUtil.EMPTY) + oldMation.getPath()); + entity.setOddNumber(oldMation.getOddNumber()); + saveGwFile(entity); + } + + private void saveGwFile(GwSendDocument entity) { + GwModel gwModel = gwModelService.selectById(entity.getModelId()); + if (ObjectUtil.isEmpty(gwModel) || StrUtil.isEmpty(gwModel.getId())) { + throw new CustomException("公文模版不存在"); + } + Map params = resetGwParams(entity); + // 模版信息,参考:https://deepoove.com/poi-tl/#_maven + String basePath = tPath.replace("images", StrUtil.EMPTY) + gwModel.getPath(); + + // html渲染插件 + HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(); + Configure configure = Configure.builder() + // 注册html解析插件 + .bind("内容", htmlRenderPolicy) + .build(); + // 进行编译 + XWPFTemplate render = XWPFTemplate.compile(basePath, configure).render(params); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String path = tPath + FileConstants.FileUploadPath.getSavePath(FileConstants.FileUploadPath.GW_MODEL.getType()[0]) + "/" + userId; + FileUtil.createDirs(path); + + String saveBasePath = path + "/" + entity.getOddNumber() + ".docx"; + entity.setPath(FileConstants.FileUploadPath.getVisitPath(FileConstants.FileUploadPath.GW_MODEL.getType()[0]) + userId + "/" + entity.getOddNumber() + ".docx"); + File word = new File(saveBasePath); + try { + // 关键步骤, + render.writeToFile(word.getAbsolutePath()); + + // 转为图片 + // 转图片如果出现乱码, + // 1. 拷贝出 /docs/字体 下的所有的ttc和ttf格式的文件、或者拷贝常用的几个字体文件,如SIMSUN.TTC,根据需要拷贝即可。 + // 2. 将准备好的字体文件拷贝至linux系统中,路径:/usr/share/fonts/ + // 3. 放入上述路径后,执行命令:fc-cache -fv 说明:执行fc-cache命令,fc-cache扫描字体目录并生成字体信息的缓存,然后应用程序就可以立即使用这些新安装的字体 + // 4. 重启服务,否则不生效 + File file = new File(saveBasePath); + InputStream inStream = new FileInputStream(file); + List wordToImg = OfficeUtils.wordToImg(inStream); + BufferedImage mergeImage = OfficeUtils.mergeImage(false, wordToImg); + // 保存图片(长图) + ImageIO.write(mergeImage, "jpg", new File(saveBasePath.replace(".docx", ".png"))); + entity.setPicPath(FileConstants.FileUploadPath.getVisitPath(FileConstants.FileUploadPath.GW_MODEL.getType()[0]) + userId + "/" + entity.getOddNumber() + ".png"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Map resetGwParams(GwSendDocument entity) { + Map params = new HashMap<>(); + params.put("标题", entity.getTitle()); + params.put("企字", entity.getEnterprise()); + params.put("年份", entity.getYear()); + params.put("号文", entity.getNumber()); + params.put("密级", GwDocumentSecret.getShowName(entity.getSecret())); + params.put("保密期间", GwDocumentPeriod.getShowName(entity.getPeriod())); + params.put("紧急程度", GwDocumentUrgency.getShowName(entity.getUrgency())); + params.put("公开类别", GwDocumentOpenCategory.getShowName(entity.getOpenCategory())); + + SimpleDateFormat sdf1 = new SimpleDateFormat(DateUtil.YYYY_MM_DD_CHINESE); + params.put("发文日期", sdf1.format(DateUtil.getPointTime(entity.getSendTime(), DateUtil.YYYY_MM_DD))); + + if (StrUtil.isNotEmpty(entity.getSendDepartmentId())) { + Map sendDepartment = iDepmentService.queryDataMationById(entity.getSendDepartmentId()); + params.put("发文部门", CollectionUtil.isEmpty(sendDepartment) ? StrUtil.EMPTY : sendDepartment.get("name").toString()); + } + + if (CollectionUtil.isNotEmpty(entity.getReceiveDepartmentId())) { + List> departmentMations = iDepmentService.queryDataMationByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(entity.getReceiveDepartmentId())); + params.put("收文部门", departmentMations); + } + + if (CollectionUtil.isNotEmpty(entity.getCcDepartmentId())) { + List> departmentMations = iDepmentService.queryDataMationByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(entity.getCcDepartmentId())); + params.put("抄送部门", departmentMations); + } + + params.put("内容", entity.getContent()); + + List> enclosureList = new ArrayList<>(); + if (ObjectUtil.isNotEmpty(entity.getEnclosureInfo())) { + String enclosureInfo = entity.getEnclosureInfo().getEnclosureInfo(); + if (StrUtil.isNotEmpty(enclosureInfo)) { + enclosureList = iEnclosureService.queryEnclosureInfoByIds(enclosureInfo); + } + } + params.put("附件", enclosureList); + + // 本地图片 + GwTemplates gwTemplates = gwTemplatesService.selectById(entity.getTemplateId()); + if (ObjectUtil.isNotEmpty(gwTemplates) && StrUtil.isNotEmpty(gwTemplates.getId())) { + params.put("红头标题", gwTemplates.getRedHead()); + if (ObjectUtil.isNotEmpty(gwTemplates.getSealMation())) { + String logoPath = tPath.replace("images", StrUtil.EMPTY) + gwTemplates.getSealMation().getLogo(); + params.put("印章", Pictures.ofLocal(logoPath).size(120, 120).create()); + params.put("企业", gwTemplates.getSealMation().getCompanyName()); + } + } + + return params; + } + + @Override + public GwSendDocument selectById(String id) { + GwSendDocument gwSendDocument = super.selectById(id); + gwTemplatesService.setDataMation(gwSendDocument, GwSendDocument::getTemplateId); + gwModelService.setDataMation(gwSendDocument, GwSendDocument::getModelId); + + iDepmentService.setDataMation(gwSendDocument, GwSendDocument::getSendDepartmentId); + + // 接收部门 + if (CollectionUtil.isNotEmpty(gwSendDocument.getReceiveDepartmentId())) { + String departmentIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(gwSendDocument.getReceiveDepartmentId()); + List> departmentList = iDepmentService.queryDataMationByIds(departmentIdStr); + gwSendDocument.setReceiveDepartmentMation(departmentList); + } + + // 抄送部门 + if (CollectionUtil.isNotEmpty(gwSendDocument.getCcDepartmentId())) { + String ccDepartmentIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(gwSendDocument.getCcDepartmentId()); + List> ccDepartmentList = iDepmentService.queryDataMationByIds(ccDepartmentIdStr); + gwSendDocument.setCcDepartmentMation(ccDepartmentList); + } + return gwSendDocument; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwTemplatesServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwTemplatesServiceImpl.java new file mode 100644 index 0000000..8d57fb5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/gw/service/impl/GwTemplatesServiceImpl.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.gw.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.gw.dao.GwTemplatesDao; +import com.skyeye.eve.gw.entity.GwTemplates; +import com.skyeye.eve.gw.service.GwTemplatesService; +import com.skyeye.eve.seal.service.SealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: GwTemplatesServiceImpl + * @Description: 套红模板服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/25 11:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套红模板", groupName = "套红模板") +public class GwTemplatesServiceImpl extends SkyeyeBusinessServiceImpl implements GwTemplatesService { + + @Autowired + private SealService sealService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryGwTemplatesList(pageInfo); + sealService.setMationForMap(beans, "sealId", "sealMation"); + return beans; + } + + @Override + public GwTemplates selectById(String id) { + GwTemplates gwTemplates = super.selectById(id); + sealService.setDataMation(gwTemplates, GwTemplates::getSealId); + return gwTemplates; + } + + @Override + public List selectByIds(String... ids) { + List gwTemplates = super.selectByIds(ids); + sealService.setDataMation(gwTemplates, GwTemplates::getSealId); + return gwTemplates; + } + + @Override + public void queryEnabledGwTemplatesList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(GwTemplates::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List gwTemplatesList = list(queryWrapper); + outputObject.setBeans(gwTemplatesList); + outputObject.settotal(gwTemplatesList.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryState.java new file mode 100644 index 0000000..65614a1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryState.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: JobDiaryState + * @Description: 日志状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum JobDiaryState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, true), + REVOKE(2, "撤销", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (JobDiaryState bean : JobDiaryState.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryType.java new file mode 100644 index 0000000..b6ac2b9 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/JobDiaryType.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.util.DateUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Locale; + +/** + * @ClassName: JobDiaryType + * @Description: 日志类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum JobDiaryType implements SkyeyeEnumClass { + + DIARY_DAY(1, "日报", true, true), + DIARY_WEEK(2, "周报", true, false), + DIARY_MONTH(3, "月报", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getTitle(Integer type) { + if (type.equals(DIARY_DAY.getKey())) { + return String.format(Locale.ROOT, "%s日 %s", DateUtil.getYmdTimeAndToString(), DIARY_DAY.getValue()); + } else if (type.equals(DIARY_WEEK.getKey())) { + return String.format(Locale.ROOT, "%s年第%s周 %s", DateUtil.getYTimeAndToString(), DateUtil.getWeekOfYear(), DIARY_WEEK.getValue()); + } else if (type.equals(DIARY_MONTH.getKey())) { + return String.format(Locale.ROOT, "%s月 %s", DateUtil.getYmTimeAndToString(), DIARY_MONTH.getValue()); + } + return StringUtils.EMPTY; + } + + public static String getName(Integer state) { + for (JobDiaryType bean : JobDiaryType.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/ReadState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/ReadState.java new file mode 100644 index 0000000..2d4eba2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/classenum/ReadState.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ReadState + * @Description: 阅读状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ReadState implements SkyeyeEnumClass { + + READ(1, "已读", true, true), + NOT_READ(2, "未读", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ReadState bean : ReadState.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/controller/JobDiaryController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/controller/JobDiaryController.java new file mode 100644 index 0000000..2acd2cd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/controller/JobDiaryController.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.jobdiary.entity.JobDiary; +import com.skyeye.eve.jobdiary.service.JobDiaryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: JobDiaryController + * @Description: 工作日志管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "工作日志", tags = "工作日志", modelName = "工作日志") +public class JobDiaryController { + + @Autowired + private JobDiaryService jobDiaryService; + + /** + * 获取我发出日志列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "diary005", value = "获取我发出日志列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/JobDiaryController/queryMysendJobDiaryList") + public void queryMysendJobDiaryList(InputObject inputObject, OutputObject outputObject) { + jobDiaryService.queryPageList(inputObject, outputObject); + } + + /** + * 获取我收到的日志 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "diary001", value = "获取我收到的日志", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/JobDiaryController/queryMyReceivedJobDiaryList") + public void queryMyReceivedJobDiaryList(InputObject inputObject, OutputObject outputObject) { + jobDiaryService.queryMyReceivedJobDiaryList(inputObject, outputObject); + } + + /** + * 新增/编辑日志 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeJobDiary", value = "新增/编辑日志", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = JobDiary.class) + @RequestMapping("/post/JobDiaryController/writeJobDiary") + public void writeJobDiary(InputObject inputObject, OutputObject outputObject) { + jobDiaryService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 撤销日志 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeJobDiaryById", value = "撤销日志", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/JobDiaryController/revokeJobDiaryById") + public void revokeJobDiaryById(InputObject inputObject, OutputObject outputObject) { + jobDiaryService.revokeJobDiaryById(inputObject, outputObject); + } + + /** + * 删除日志 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteJobDiaryById", value = "删除日志", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/JobDiaryController/deleteJobDiaryById") + public void deleteJobDiaryById(InputObject inputObject, OutputObject outputObject) { + jobDiaryService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryDao.java new file mode 100644 index 0000000..60570fa --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.jobdiary.entity.JobDiary; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobDiaryDao + * @Description: 工作日志管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JobDiaryDao extends SkyeyeBaseMapper { + + List> queryMyReceivedJobDiaryList(CommonPageInfo commonPageInfo); + + List> queryMysendJobDiaryList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryReceivedDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryReceivedDao.java new file mode 100644 index 0000000..f693762 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/dao/JobDiaryReceivedDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.jobdiary.entity.JobDiaryReceived; + +/** + * @ClassName: JobDiaryReceivedDao + * @Description: 工作日志接收人数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 13:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface JobDiaryReceivedDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiary.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiary.java new file mode 100644 index 0000000..89a8435 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiary.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobDiary + * @Description: 工作日志实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField(value = {"name", "createId"}) +@RedisCacheField(name = "job:diary", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "job_diary") +@ApiModel("工作日志实体类") +public class JobDiary extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称") + private String name; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(value = "completed_job") + @ApiModelProperty(value = "已完成工作", required = "required") + private String completedJob; + + @TableField(value = "incomplete_job") + @ApiModelProperty(value = "未完成工作") + private String incompleteJob; + + @TableField(value = "coordina_job") + @ApiModelProperty(value = "需协调工作") + private String coordinaJob; + + @TableField(value = "work_summary") + @ApiModelProperty(value = "工作总结") + private String workSummary; + + @TableField(value = "state") + @Property(value = "状态,参考#JobDiaryState") + private Integer state; + + @TableField(value = "type") + @ApiModelProperty(value = "日志类型,参考#JobDiaryType", required = "required,num") + private Integer type; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @ApiModelProperty(value = "接收人id", required = "required,json") + private List receivedId; + + @TableField(exist = false) + @Property(value = "接收人信息") + private List> receivedMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiaryReceived.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiaryReceived.java new file mode 100644 index 0000000..b093f38 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/entity/JobDiaryReceived.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: JobDiaryReceived + * @Description: 工作日志接收人实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "job:diaryReceived", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "job_diary_received") +@ApiModel("工作日志接收人实体类") +public class JobDiaryReceived extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "state") + @Property(value = "状态,参考#ReadState") + private Integer state; + + @TableField(value = "diary_id") + @Property(value = "日志id") + private String diaryId; + + @TableField(value = "received_id") + @Property(value = "接收人id") + private String receivedId; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryReceivedService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryReceivedService.java new file mode 100644 index 0000000..bffdfb1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryReceivedService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.jobdiary.entity.JobDiaryReceived; + +import java.util.List; + +/** + * @ClassName: JobDiaryReceivedService + * @Description: 工作日志接收人服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 13:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface JobDiaryReceivedService extends SkyeyeBusinessService { + + void deleteByDiaryId(String diaryId); + + void save(String diaryId, List receivedIdList); + + List queryByDiaryId(String diaryId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryService.java new file mode 100644 index 0000000..b739981 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/JobDiaryService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.jobdiary.entity.JobDiary; + +/** + * @ClassName: JobDiaryService + * @Description: 工作日志管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 11:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface JobDiaryService extends SkyeyeBusinessService { + + void queryMyReceivedJobDiaryList(InputObject inputObject, OutputObject outputObject); + + void revokeJobDiaryById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryReceivedServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryReceivedServiceImpl.java new file mode 100644 index 0000000..299ccf3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryReceivedServiceImpl.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.jobdiary.classenum.ReadState; +import com.skyeye.eve.jobdiary.dao.JobDiaryReceivedDao; +import com.skyeye.eve.jobdiary.entity.JobDiaryReceived; +import com.skyeye.eve.jobdiary.service.JobDiaryReceivedService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: JobDiaryReceivedServiceImpl + * @Description: 工作日志接收人服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 13:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "工作日志接收人", groupName = "工作日志接收人", manageShow = false) +public class JobDiaryReceivedServiceImpl extends SkyeyeBusinessServiceImpl implements JobDiaryReceivedService { + + @Override + public void deleteByDiaryId(String diaryId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JobDiaryReceived::getDiaryId), diaryId); + remove(queryWrapper); + } + + @Override + public void save(String diaryId, List receivedIdList) { + deleteByDiaryId(diaryId); + receivedIdList = receivedIdList.stream() + .filter(receivedId -> StrUtil.isNotEmpty(receivedId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(receivedIdList)) { + List jobDiaryReceiveds = new ArrayList<>(); + for (String receivedId : receivedIdList) { + JobDiaryReceived jobDiaryReceived = new JobDiaryReceived(); + jobDiaryReceived.setReceivedId(receivedId); + jobDiaryReceived.setDiaryId(diaryId); + jobDiaryReceived.setState(ReadState.NOT_READ.getKey()); + jobDiaryReceiveds.add(jobDiaryReceived); + } + createEntity(jobDiaryReceiveds, StrUtil.EMPTY); + } + } + + @Override + public List queryByDiaryId(String diaryId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JobDiaryReceived::getDiaryId), diaryId); + List jobDiaryReceiveds = list(queryWrapper); + return jobDiaryReceiveds.stream().map(JobDiaryReceived::getReceivedId).collect(Collectors.toList()); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryServiceImpl.java new file mode 100644 index 0000000..263c717 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/jobdiary/service/impl/JobDiaryServiceImpl.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.jobdiary.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.jobdiary.classenum.JobDiaryState; +import com.skyeye.eve.jobdiary.classenum.JobDiaryType; +import com.skyeye.eve.jobdiary.classenum.ReadState; +import com.skyeye.eve.jobdiary.dao.JobDiaryDao; +import com.skyeye.eve.jobdiary.entity.JobDiary; +import com.skyeye.eve.jobdiary.service.JobDiaryReceivedService; +import com.skyeye.eve.jobdiary.service.JobDiaryService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobDiaryServiceImpl + * @Description: 工作日志管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工作日志", groupName = "工作日志") +public class JobDiaryServiceImpl extends SkyeyeBusinessServiceImpl implements JobDiaryService { + + @Autowired + private JobDiaryReceivedService jobDiaryReceivedService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + commonPageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryMysendJobDiaryList(commonPageInfo); + beans.forEach(bean -> { + bean.put("stateName", JobDiaryState.getName(Integer.parseInt(bean.get("state").toString()))); + bean.put("typeName", JobDiaryType.getName(Integer.parseInt(bean.get("type").toString()))); + }); + return beans; + } + + @Override + public void validatorEntity(JobDiary entity) { + entity.setName(JobDiaryType.getTitle(entity.getType())); + entity.setState(JobDiaryState.NORMAL.getKey()); + entity.setCreateId(InputObject.getLogParamsStatic().get("id").toString()); + super.validatorEntity(entity); + } + + @Override + public void writePostpose(JobDiary entity, String userId) { + super.writePostpose(entity, userId); + jobDiaryReceivedService.save(entity.getId(), entity.getReceivedId()); + } + + @Override + public void deletePostpose(String id) { + jobDiaryReceivedService.deleteByDiaryId(id); + } + + @Override + public JobDiary getDataFromDb(String id) { + JobDiary jobDiary = super.getDataFromDb(id); + jobDiary.setReceivedId(jobDiaryReceivedService.queryByDiaryId(id)); + return jobDiary; + } + + @Override + public JobDiary selectById(String id) { + JobDiary jobDiary = super.selectById(id); + jobDiary.setReceivedMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(jobDiary.getReceivedId()))); + return jobDiary; + } + + @Override + public void queryMyReceivedJobDiaryList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + commonPageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryMyReceivedJobDiaryList(commonPageInfo); + String serviceClassName = getServiceClassName(); + beans.forEach(bean -> { + bean.put("stateName", ReadState.getName(Integer.parseInt(bean.get("state").toString()))); + bean.put("typeName", JobDiaryType.getName(Integer.parseInt(bean.get("type").toString()))); + bean.put("serviceClassName", serviceClassName); + }); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void revokeJobDiaryById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + checkTime(id); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(JobDiary::getState), JobDiaryState.REVOKE.getKey()); + update(updateWrapper); + refreshCache(id); + } + + private void checkTime(String id) { + JobDiary jobDiary = selectById(id); + // 计算当前时间和创建时间的时间差,返回分钟 + long twoHour = DateUtil.getDistanceMinute(DateUtil.getTimeAndToString(), jobDiary.getCreateTime()); + if (twoHour > 120) { + throw new CustomException("已超出可操作时间,撤销失败!"); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/classenum/KnowlgContentState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/classenum/KnowlgContentState.java new file mode 100644 index 0000000..6d0436a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/classenum/KnowlgContentState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: KnowlgContentState + * @Description: 知识库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/14 11:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum KnowlgContentState implements SkyeyeEnumClass { + + IN_EXAMINE(1, "审核中", true, false), + PASS(2, "审核通过", true, true), + NO_PASS(3, "审核不通过", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/controller/KnowledgeContentController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/controller/KnowledgeContentController.java new file mode 100644 index 0000000..7231769 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/controller/KnowledgeContentController.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.knowlg.entity.KnowledgeContent; +import com.skyeye.eve.knowlg.service.KnowledgeContentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: KnowledgeContentController + * @Description: 知识库管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/21 15:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "知识库", tags = "知识库", modelName = "知识库管理") +public class KnowledgeContentController { + + @Autowired + private KnowledgeContentService knowledgeContentService; + + /** + * 获取我的知识库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "knowledgecontent001", value = "获取我的知识库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/KnowledgeContentController/queryKnowledgeContentList") + public void queryKnowledgeContentList(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.queryPageList(inputObject, outputObject); + } + + + /** + * 新增/编辑知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeKnowledgeContent", value = "新增/编辑知识库", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = KnowledgeContent.class) + @RequestMapping("/post/KnowledgeContentController/writeKnowledgeContent") + public void writeKnowledgeContent(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteKnowledgeContentById", value = "删除知识库", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "知识库id", required = "required")}) + @RequestMapping("/post/KnowledgeContentController/deleteKnowledgeContentById") + public void deleteKnowledgeContentById(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.deleteById(inputObject, outputObject); + } + + /** + * 知识库详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryKnowledgeContentById", value = "知识库详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "知识库id", required = "required")}) + @RequestMapping("/post/KnowledgeContentController/queryKnowledgeContentById") + public void queryKnowledgeContentById(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.selectById(inputObject, outputObject); + } + + /** + * 获取知识库列表用于审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "knowledgecontent010", value = "获取待审核的知识库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/KnowledgeContentController/queryAllKnowledgeContentList") + public void queryAllKnowledgeContentList(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.queryAllKnowledgeContentList(inputObject, outputObject); + } + + /** + * 审核知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "knowledgecontent012", value = "获取知识库信息用于回显审核", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "知识库id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "审核结果", required = "required,num"), + @ApiImplicitParam(id = "examineNopassReason", name = "examineNopassReason", value = "审核不通过原因")}) + @RequestMapping("/post/KnowledgeContentController/editKnowledgeContentToCheck") + public void editKnowledgeContentToCheck(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.editKnowledgeContentToCheck(inputObject, outputObject); + } + + /** + * 获取企业知识库列表(已审核通过) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "knowledgecontent016", value = "获取企业知识库列表(已审核通过)", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/KnowledgeContentController/queryAllPassKnowledgeContentList") + public void queryAllPassKnowledgeContentList(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.queryAllPassKnowledgeContentList(inputObject, outputObject); + } + + /** + * 获取近期八条已审核的知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEightPassKnowlgList", value = "获取近期八条已审核的知识库", method = "GET", allUse = "2") + @RequestMapping("/post/KnowledgeContentController/queryEightPassKnowlgList") + public void queryEightPassKnowlgList(InputObject inputObject, OutputObject outputObject) { + knowledgeContentService.queryEightPassKnowlgList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/dao/KnowledgeContentDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/dao/KnowledgeContentDao.java new file mode 100644 index 0000000..b51a00b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/dao/KnowledgeContentDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.knowlg.entity.KnowledgeContent; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: KnowledgeContentDao + * @Description: 企业知识库管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KnowledgeContentDao extends SkyeyeBaseMapper { + + List> queryKnowledgeContentList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/entity/KnowledgeContent.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/entity/KnowledgeContent.java new file mode 100644 index 0000000..418bb15 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/entity/KnowledgeContent.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: KnowledgeContent + * @Description: 知识库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/14 11:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "knowledge:content", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "knowlg_content") +@ApiModel("知识库实体类") +public class KnowledgeContent extends BaseGeneralInfo { + + @TableField(value = "content") + @ApiModelProperty(value = "内容") + private String content; + + @TableField(value = "type_id") + @ApiModelProperty(value = "分类id", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "分类信息") + private Map typeMation; + + @TableField(value = "state") + @ApiModelProperty(value = "状态,参考#KnowlgContentState") + private Integer state; + + @TableField(value = "examine_nopass_reason") + @ApiModelProperty(value = "审核不通过时的原因") + private String examineNopassReason; + + @TableField(value = "examine_id") + @Property("审核人id") + private String examineId; + + @TableField(exist = false) + @Property("审核人信息") + private Map examineMation; + + @TableField(value = "examine_time") + @Property("审核时间") + private String examineTime; + + @TableField(value = "read_num") + @Property("阅读量") + private String readNum; + + @TableField(value = "label") + @ApiModelProperty(value = "知识库标签") + private String label; + + @TableField(exist = false) + @ApiModelProperty(value = "上传文件创建知识库") + private String filePath; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/KnowledgeContentService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/KnowledgeContentService.java new file mode 100644 index 0000000..a9aa1e0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/KnowledgeContentService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.knowlg.entity.KnowledgeContent; + +/** + * @ClassName: KnowledgeContentService + * @Description: 知识库管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/21 15:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KnowledgeContentService extends SkyeyeBusinessService { + + void queryAllKnowledgeContentList(InputObject inputObject, OutputObject outputObject); + + void editKnowledgeContentToCheck(InputObject inputObject, OutputObject outputObject); + + void queryAllPassKnowledgeContentList(InputObject inputObject, OutputObject outputObject); + + void queryEightPassKnowlgList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/impl/KnowledgeContentServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/impl/KnowledgeContentServiceImpl.java new file mode 100644 index 0000000..ca3b8de --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/knowlg/service/impl/KnowledgeContentServiceImpl.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.knowlg.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.knowlg.classenum.KnowlgContentState; +import com.skyeye.eve.knowlg.dao.KnowledgeContentDao; +import com.skyeye.eve.knowlg.entity.KnowledgeContent; +import com.skyeye.eve.knowlg.service.KnowledgeContentService; +import com.skyeye.exception.CustomException; +import com.skyeye.knowlg.util.Word2Html; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: KnowledgeContentServiceImpl + * @Description: 知识库管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "知识库", groupName = "知识库管理") +public class KnowledgeContentServiceImpl extends SkyeyeBusinessServiceImpl implements KnowledgeContentService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryKnowledgeContentList(pageInfo); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public void createPrepose(KnowledgeContent entity) { + entity.setState(KnowlgContentState.IN_EXAMINE.getKey()); + entity.setReadNum(String.valueOf(CommonNumConstants.NUM_ZERO)); + if (StrUtil.isNotEmpty(entity.getFilePath())) { + // 文件路径 + String path = tPath + entity.getFilePath(); + File file = new File(path); + String imagesPath = tPath + FileConstants.FileUploadPath.getVisitPath(CommonNumConstants.NUM_THIRTEEN); + try { + Map word = Word2Html.word2007ToHtml(file, imagesPath); + if ("1".equals(word.get("code").toString())) { + String content = word.get("content").toString(); + entity.setContent(content); + } else { + word = Word2Html.wordToHtml(file, imagesPath); + if ("1".equals(word.get("code").toString())) { + String content = word.get("content").toString(); + entity.setContent(content); + } + } + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.deleteFile(path); + } + } + } + + @Override + protected void updatePrepose(KnowledgeContent entity) { + entity.setState(KnowlgContentState.IN_EXAMINE.getKey()); + } + + @Override + public KnowledgeContent selectById(String id) { + KnowledgeContent knowledgeContent = super.selectById(id); + iSysDictDataService.setDataMation(knowledgeContent, KnowledgeContent::getTypeId); + iAuthUserService.setDataMation(knowledgeContent, KnowledgeContent::getExamineId); + return knowledgeContent; + } + + /** + * 获取知识库列表用于审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllKnowledgeContentList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryKnowledgeContentList(pageInfo); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + iAuthUserService.setMationForMap(beans, "examineId", "examineMation"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 审核知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editKnowledgeContentToCheck(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + KnowledgeContent knowledgeContent = selectById(id); + if (knowledgeContent.getState().equals(KnowlgContentState.IN_EXAMINE.getKey())) { + String examineId = inputObject.getLogParams().get("id").toString(); + Integer state = Integer.parseInt(map.get("state").toString()); + String examineNopassReason = map.get("examineNopassReason").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(KnowledgeContent::getExamineId), examineId); + updateWrapper.set(MybatisPlusUtil.toColumns(KnowledgeContent::getExamineTime), DateUtil.getTimeAndToString()); + updateWrapper.set(MybatisPlusUtil.toColumns(KnowledgeContent::getState), state); + updateWrapper.set(MybatisPlusUtil.toColumns(KnowledgeContent::getExamineNopassReason), examineNopassReason); + update(updateWrapper); + refreshCache(id); + } else { + throw new CustomException("该数据状态已改变,请刷新页面。"); + } + } + + /** + * 获取企业知识库列表(已审核通过) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllPassKnowledgeContentList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setState(String.valueOf(KnowlgContentState.PASS.getKey())); + List> beans = skyeyeBaseMapper.queryKnowledgeContentList(pageInfo); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取近期八条已审核的知识库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEightPassKnowlgList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KnowledgeContent::getState), KnowlgContentState.PASS.getKey()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(KnowledgeContent::getCreateTime)); + queryWrapper.last(String.format(Locale.ROOT, "limit %s", CommonNumConstants.NUM_EIGHT)); + queryWrapper.select(CommonConstants.ID, + MybatisPlusUtil.toColumns(KnowledgeContent::getName), + MybatisPlusUtil.toColumns(KnowledgeContent::getTypeId), + MybatisPlusUtil.toColumns(KnowledgeContent::getCreateTime)); + List list = list(queryWrapper); + iSysDictDataService.setDataMation(list, KnowledgeContent::getTypeId); + // 获取我发表的审核通过的知识库数量 + String userId = inputObject.getLogParams().get("id").toString(); + Integer count = getKnowlgPassNumByUserId(userId); + outputObject.setBeans(list); + outputObject.settotal(count); + } + + private Integer getKnowlgPassNumByUserId(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KnowledgeContent::getState), KnowlgContentState.PASS.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(KnowledgeContent::getCreateId), userId); + return Math.toIntExact(count(queryWrapper)); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyBorrowController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyBorrowController.java new file mode 100644 index 0000000..ccc41a6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyBorrowController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.licence.entity.LicenceUse; +import com.skyeye.eve.licence.service.LicenceApplyBorrowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LicenceApplyBorrowController + * @Description: 证照借用控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 22:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "证照借用", tags = "证照借用", modelName = "证照模块") +public class LicenceApplyBorrowController { + + @Autowired + private LicenceApplyBorrowService licenceApplyBorrowService; + + /** + * 获取我发起的证照借用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licenceborrow001", value = "获取我发起的证照借用列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LicenceApplyBorrowController/queryLicenceBorrowList") + public void queryLicenceBorrowList(InputObject inputObject, OutputObject outputObject) { + licenceApplyBorrowService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑证照借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLicenceUse", value = "新增/编辑证照借用申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LicenceUse.class) + @RequestMapping("/post/LicenceApplyBorrowController/writeLicenceUse") + public void writeLicenceUse(InputObject inputObject, OutputObject outputObject) { + licenceApplyBorrowService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 证照借用申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licenceborrow006", value = "证照借用申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/LicenceApplyBorrowController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + licenceApplyBorrowService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废证照借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licenceborrow007", value = "作废证照借用申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LicenceApplyBorrowController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + licenceApplyBorrowService.invalid(inputObject, outputObject); + } + + /** + * 撤销证照借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licenceborrow010", value = "撤销证照借用申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/LicenceApplyBorrowController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + licenceApplyBorrowService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyRevertController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyRevertController.java new file mode 100644 index 0000000..332c325 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceApplyRevertController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.licence.entity.LicenceRevert; +import com.skyeye.eve.licence.service.LicenceApplyRevertService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LicenceApplyRevertController + * @Description: 证照归还申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 10:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "证照归还", tags = "证照归还", modelName = "证照模块") +public class LicenceApplyRevertController { + + @Autowired + private LicenceApplyRevertService licenceApplyRevertService; + + /** + * 获取我发起的的证照归还列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licencerevert001", value = "获取我发起的的证照归还列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LicenceApplyRevertController/queryLicenceRevertList") + public void queryLicenceRevertList(InputObject inputObject, OutputObject outputObject) { + licenceApplyRevertService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑证照归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLicenceRevert", value = "新增/编辑证照归还申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LicenceRevert.class) + @RequestMapping("/post/LicenceApplyRevertController/writeLicenceRevert") + public void writeLicenceRevert(InputObject inputObject, OutputObject outputObject) { + licenceApplyRevertService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 证照归还申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licencerevert006", value = "证照归还申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/LicenceApplyRevertController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + licenceApplyRevertService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废证照归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licencerevert007", value = "作废证照归还申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LicenceApplyRevertController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + licenceApplyRevertService.invalid(inputObject, outputObject); + } + + /** + * 撤销证照归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licencerevert010", value = "撤销证照归还申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/LicenceApplyRevertController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + licenceApplyRevertService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceController.java new file mode 100644 index 0000000..d874b8e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/controller/LicenceController.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.licence.entity.Licence; +import com.skyeye.eve.licence.service.LicenceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LicenceController + * @Description: 证照管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 22:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "证照管理", tags = "证照管理", modelName = "证照模块") +public class LicenceController { + + @Autowired + private LicenceService licenceService; + + /** + * 查询所有的证照 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licence001", value = "查询所有的证照", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LicenceController/queryLicenceList") + public void queryLicenceList(InputObject inputObject, OutputObject outputObject) { + licenceService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLicence", value = "新增/修改证照信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Licence.class) + @RequestMapping("/post/LicenceController/writeLicence") + public void writeLicence(InputObject inputObject, OutputObject outputObject) { + licenceService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licence003", value = "根据id删除证照信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LicenceController/deleteLicenceById") + public void deleteLicenceById(InputObject inputObject, OutputObject outputObject) { + licenceService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licenceborrow008", value = "获取所有证照信息", method = "GET", allUse = "2") + @RequestMapping("/post/LicenceController/queryAllLicenceList") + public void queryAllLicenceList(InputObject inputObject, OutputObject outputObject) { + licenceService.queryAllLicenceList(inputObject, outputObject); + } + + /** + * 获取我借用中的所有证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "licencerevert008", value = "获取我借用中的所有证照信息", method = "GET", allUse = "2") + @RequestMapping("/post/LicenceController/queryMyRevertLicenceList") + public void queryMyRevertLicenceList(InputObject inputObject, OutputObject outputObject) { + licenceService.queryMyRevertLicenceList(inputObject, outputObject); + } + + /** + * 获取我借用中的证照列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyRevertLicencePageList", value = "获取我借用中的证照列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LicenceController/queryMyRevertLicencePageList") + public void queryMyRevertLicencePageList(InputObject inputObject, OutputObject outputObject) { + licenceService.queryMyRevertLicencePageList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceDao.java new file mode 100644 index 0000000..64750d4 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.licence.entity.Licence; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LicenceDao + * @Description: 证照管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 23:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceDao extends SkyeyeBaseMapper { + + List> queryLicenceList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertDao.java new file mode 100644 index 0000000..38dbb9f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.licence.entity.LicenceRevert; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LicenceRevertDao + * @Description: 证照归还数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 10:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceRevertDao extends SkyeyeBaseMapper { + + List> queryLicenceRevertList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertLinkDao.java new file mode 100644 index 0000000..a4c36d6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceRevertLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.licence.entity.LicenceRevertLink; + +/** + * @ClassName: LicenceRevertLinkDao + * @Description: 证照归还申请关联的证照信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceRevertLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseDao.java new file mode 100644 index 0000000..b7c9750 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.licence.entity.LicenceUse; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LicenceUseDao + * @Description: 证照借用数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 22:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceUseDao extends SkyeyeBaseMapper { + + List> queryLicenceBorrowList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseLinkDao.java new file mode 100644 index 0000000..d324b6a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/dao/LicenceUseLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.licence.entity.LicenceUseLink; + +/** + * @ClassName: LicenceUseLinkDao + * @Description: 证照借用申请关联的证照信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceUseLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/Licence.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/Licence.java new file mode 100644 index 0000000..152d2a0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/Licence.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Licence + * @Description: 证照实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/6 9:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "assistant:licence", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "licence") +@ApiModel("证照实体类") +public class Licence extends BaseGeneralInfo { + + @TableField(value = "licence_num") + @ApiModelProperty(value = "证照编号", required = "required") + private String licenceNum; + + @TableField(value = "issuing_organization") + @ApiModelProperty(value = "签发机关", required = "required") + private String issuingOrganization; + + @TableField(value = "issue_time") + @ApiModelProperty(value = "签发时间", required = "required") + private String issueTime; + + @TableField(value = "annual_review") + @ApiModelProperty(value = "是否年审,参考#WhetherEnum", required = "required,num") + private Integer annualReview; + + @TableField(value = "next_annual_review") + @ApiModelProperty(value = "下次年审时间,当annualReview=1时") + private String nextAnnualReview; + + @TableField(value = "term_of_validity") + @ApiModelProperty(value = "有效期是否永久,参考#WhetherEnum", required = "required,num") + private Integer termOfValidity; + + @TableField(value = "term_of_validity_time") + @ApiModelProperty(value = "有效期,当termOfValidity为0时有值") + private String termOfValidityTime; + + @TableField(value = "licence_admin") + @ApiModelProperty(value = "管理人id") + private String licenceAdmin; + + @TableField(exist = false) + @Property(value = "管理人") + private Map licenceAdminMation; + + @TableField(value = "borrow_id") + @Property(value = "借用人id") + private String borrowId; + + @TableField(exist = false) + @Property(value = "借用人") + private Map borrowMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevert.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevert.java new file mode 100644 index 0000000..1f9a548 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevert.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: LicenceRevert + * @Description: 证照归还申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:licence:revert", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "licence_revert") +@ApiModel("证照归还申请实体类") +public class LicenceRevert extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "证照信息", required = "required,json") + private List revertLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevertLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevertLink.java new file mode 100644 index 0000000..870b397 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceRevertLink.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: LicenceRevertLink + * @Description: 证照归还申请关联的证照信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "licence_revert_goods") +@ApiModel("证照归还申请关联的证照信息实体类") +public class LicenceRevertLink extends SkyeyeLinkData { + + @TableField("licence_id") + @ApiModelProperty(value = "证照id", required = "required") + private String licenceId; + + @TableField(exist = false) + @Property("证照信息") + private Licence licenceMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUse.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUse.java new file mode 100644 index 0000000..115e98b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUse.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: LicenceUse + * @Description: 证照借用申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:licence:use", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "licence_use") +@ApiModel("证照借用申请实体类") +public class LicenceUse extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "证照信息", required = "required,json") + private List useLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUseLink.java new file mode 100644 index 0000000..66c8c48 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/entity/LicenceUseLink.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: LicenceUseLink + * @Description: 证照借用申请关联的证照信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "licence_use_goods") +@ApiModel("证照借用申请关联的证照信息实体类") +public class LicenceUseLink extends SkyeyeLinkData { + + @TableField("licence_id") + @ApiModelProperty(value = "证照id", required = "required") + private String licenceId; + + @TableField(exist = false) + @Property("证照信息") + private Licence licenceMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyBorrowService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyBorrowService.java new file mode 100644 index 0000000..e1f659f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyBorrowService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.licence.entity.LicenceUse; + +/** + * @ClassName: LicenceApplyBorrowService + * @Description: 证照借用服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 22:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceApplyBorrowService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyRevertService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyRevertService.java new file mode 100644 index 0000000..c4940c9 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceApplyRevertService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.licence.entity.LicenceRevert; + +/** + * @ClassName: LicenceApplyRevertService + * @Description: 证照归还申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 10:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceApplyRevertService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceRevertLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceRevertLinkService.java new file mode 100644 index 0000000..141d8be --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceRevertLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.licence.entity.LicenceRevertLink; + +/** + * @ClassName: LicenceRevertLinkService + * @Description: 证照归还申请关联的证照信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceRevertLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceService.java new file mode 100644 index 0000000..2b327bf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceService.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.licence.entity.Licence; + +/** + * @ClassName: LicenceService + * @Description: 证照管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 23:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceService extends SkyeyeBusinessService { + + void queryAllLicenceList(InputObject inputObject, OutputObject outputObject); + + void queryMyRevertLicenceList(InputObject inputObject, OutputObject outputObject); + + /** + * 设置证照领用信息 + * + * @param id 证照id + * @param useUserId 领用人id + */ + void setLicenceUse(String id, String useUserId); + + /** + * 设置证照归还信息 + * + * @param id 证照id + */ + void setLicenceRevert(String id); + + void queryMyRevertLicencePageList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceUseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceUseLinkService.java new file mode 100644 index 0000000..ae7c175 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/LicenceUseLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.licence.entity.LicenceUseLink; + +/** + * @ClassName: LicenceUseLinkService + * @Description: 证照借用申请关联的证照信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LicenceUseLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyBorrowServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyBorrowServiceImpl.java new file mode 100644 index 0000000..bdc58e6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyBorrowServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.licence.dao.LicenceUseDao; +import com.skyeye.eve.licence.entity.LicenceUse; +import com.skyeye.eve.licence.entity.LicenceUseLink; +import com.skyeye.eve.licence.service.LicenceApplyBorrowService; +import com.skyeye.eve.licence.service.LicenceService; +import com.skyeye.eve.licence.service.LicenceUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: LicenceApplyBorrowServiceImpl + * @Description: 证照借用服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 22:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "证照借用", groupName = "证照模块", flowable = true) +public class LicenceApplyBorrowServiceImpl extends SkyeyeFlowableServiceImpl implements LicenceApplyBorrowService { + + @Autowired + private LicenceUseLinkService licenceUseLinkService; + + @Autowired + private LicenceService licenceService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryLicenceBorrowList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(LicenceUse entity) { + chectOrderItem(entity.getUseLinks()); + } + + @Override + public void writeChild(LicenceUse entity, String userId) { + licenceUseLinkService.saveLinkList(entity.getId(), entity.getUseLinks()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List useLinks) { + if (CollectionUtil.isEmpty(useLinks)) { + throw new CustomException("请最少选择一条证照信息"); + } + List licenceIds = useLinks.stream().map(LicenceUseLink::getLicenceId).distinct() + .collect(Collectors.toList()); + if (useLinks.size() != licenceIds.size()) { + throw new CustomException("单据中不允许出现同一证照信息"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + licenceUseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public LicenceUse getDataFromDb(String id) { + LicenceUse licenceUse = super.getDataFromDb(id); + List licenceUseLinks = licenceUseLinkService.selectByPId(licenceUse.getId()); + licenceUse.setUseLinks(licenceUseLinks); + return licenceUse; + } + + @Override + public LicenceUse selectById(String id) { + LicenceUse licenceUse = super.selectById(id); + // 获取证照信息 + licenceService.setDataMation(licenceUse.getUseLinks(), LicenceUseLink::getLicenceId); + licenceUse.getUseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + licenceUse.setStateName(FlowableStateEnum.getStateName(licenceUse.getState())); + iAuthUserService.setName(licenceUse, "createId", "createName"); + return licenceUse; + } + + @Override + public void revokePostpose(LicenceUse entity) { + super.revokePostpose(entity); + licenceUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(LicenceUse entity) { + LicenceUse licenceUse = selectById(entity.getId()); + for (LicenceUseLink bean : licenceUse.getUseLinks()) { + if (StrUtil.isEmpty(bean.getLicenceMation().getBorrowId())) { + // 可以借用,给证照表中对应证照填上借用人 + licenceService.setLicenceUse(bean.getLicenceId(), licenceUse.getCreateId()); + licenceUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } else { + licenceUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + } + } + + @Override + public void approvalEndIsFailed(LicenceUse entity) { + licenceUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyRevertServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyRevertServiceImpl.java new file mode 100644 index 0000000..327ac47 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceApplyRevertServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.licence.dao.LicenceRevertDao; +import com.skyeye.eve.licence.entity.LicenceRevert; +import com.skyeye.eve.licence.entity.LicenceRevertLink; +import com.skyeye.eve.licence.service.LicenceApplyRevertService; +import com.skyeye.eve.licence.service.LicenceRevertLinkService; +import com.skyeye.eve.licence.service.LicenceService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: LicenceApplyRevertServiceImpl + * @Description: 证照归还申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 10:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "证照归还", groupName = "证照模块", flowable = true) +public class LicenceApplyRevertServiceImpl extends SkyeyeFlowableServiceImpl implements LicenceApplyRevertService { + + @Autowired + private LicenceRevertLinkService licenceRevertLinkService; + + @Autowired + private LicenceService licenceService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryLicenceRevertList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(LicenceRevert entity) { + chectOrderItem(entity.getRevertLinks()); + } + + @Override + public void writeChild(LicenceRevert entity, String userId) { + licenceRevertLinkService.saveLinkList(entity.getId(), entity.getRevertLinks()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List revertLinks) { + if (CollectionUtil.isEmpty(revertLinks)) { + throw new CustomException("请最少选择一条证照信息"); + } + List licenceIds = revertLinks.stream().map(LicenceRevertLink::getLicenceId).distinct() + .collect(Collectors.toList()); + if (revertLinks.size() != licenceIds.size()) { + throw new CustomException("单据中不允许出现同一证照信息"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + licenceRevertLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public LicenceRevert getDataFromDb(String id) { + LicenceRevert licenceRevert = super.getDataFromDb(id); + List licenceRevertLinks = licenceRevertLinkService.selectByPId(licenceRevert.getId()); + licenceRevert.setRevertLinks(licenceRevertLinks); + return licenceRevert; + } + + @Override + public LicenceRevert selectById(String id) { + LicenceRevert licenceRevert = super.selectById(id); + // 获取证照信息 + licenceService.setDataMation(licenceRevert.getRevertLinks(), LicenceRevertLink::getLicenceId); + licenceRevert.getRevertLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + licenceRevert.setStateName(FlowableStateEnum.getStateName(licenceRevert.getState())); + iAuthUserService.setName(licenceRevert, "createId", "createName"); + return licenceRevert; + } + + @Override + public void revokePostpose(LicenceRevert entity) { + super.revokePostpose(entity); + licenceRevertLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(LicenceRevert entity) { + LicenceRevert licenceRevert = selectById(entity.getId()); + for (LicenceRevertLink bean : licenceRevert.getRevertLinks()) { + if (StrUtil.equals(bean.getLicenceMation().getBorrowId(), licenceRevert.getCreateId())) { + // 如果当前借用人为归还单申请人可以归还 + licenceService.setLicenceRevert(bean.getLicenceId()); + licenceRevertLinkService.editStateById(bean.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } else { + licenceRevertLinkService.editStateById(bean.getId(), FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + } + } + + @Override + public void approvalEndIsFailed(LicenceRevert entity) { + licenceRevertLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceRevertLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceRevertLinkServiceImpl.java new file mode 100644 index 0000000..775f5e7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceRevertLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.licence.dao.LicenceRevertLinkDao; +import com.skyeye.eve.licence.entity.Licence; +import com.skyeye.eve.licence.entity.LicenceRevertLink; +import com.skyeye.eve.licence.service.LicenceRevertLinkService; +import com.skyeye.eve.licence.service.LicenceService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: LicenceRevertLinkServiceImpl + * @Description: 证照归还申请关联的证照信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "证照归还申请-证照Link", groupName = "证照模块", manageShow = false) +public class LicenceRevertLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements LicenceRevertLinkService { + + @Autowired + private LicenceService licenceService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("证照信息不能为空."); + } + List licenceIds = beans.stream().map(LicenceRevertLink::getLicenceId).distinct().collect(Collectors.toList()); + Map licenceMap = licenceService.selectMapByIds(licenceIds); + beans.forEach(licenceUseLink -> { + Licence licence = licenceMap.get(licenceUseLink.getLicenceId()); + if (licence == null) { + throw new CustomException("数据中包含不存在的证照信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceServiceImpl.java new file mode 100644 index 0000000..bfdb62c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceServiceImpl.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service.impl; + +import com.alibaba.csp.sentinel.util.StringUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.licence.dao.LicenceDao; +import com.skyeye.eve.licence.entity.Licence; +import com.skyeye.eve.licence.service.LicenceService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LicenceServiceImpl + * @Description: 证照管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "证照管理", groupName = "证照模块") +public class LicenceServiceImpl extends SkyeyeBusinessServiceImpl implements LicenceService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryLicenceList(pageInfo); + iAuthUserService.setMationForMap(beans, "licenceAdmin", "licenceAdminMation"); + iAuthUserService.setMationForMap(beans, "borrowId", "borrowMation"); + return beans; + } + + @Override + public Licence selectById(String id) { + Licence licence = super.selectById(id); + iAuthUserService.setDataMation(licence, Licence::getLicenceAdmin); + iAuthUserService.setDataMation(licence, Licence::getBorrowId); + return licence; + } + + /** + * 获取所有证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllLicenceList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Licence::getCreateTime)); + List licenceList = list(queryWrapper); + + outputObject.setBeans(licenceList); + outputObject.settotal(licenceList.size()); + } + + /** + * 获取我借用中的所有证照信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyRevertLicenceList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Licence::getBorrowId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Licence::getCreateTime)); + List licenceList = list(queryWrapper); + + outputObject.setBeans(licenceList); + outputObject.settotal(licenceList.size()); + } + + /** + * 设置证照领用信息 + * + * @param id 证照id + * @param useUserId 领用人id + */ + @Override + public void setLicenceUse(String id, String useUserId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + Licence licence = new Licence(); + licence.setBorrowId(useUserId); + update(licence, updateWrapper); + refreshCache(id); + } + + /** + * 设置证照归还信息 + * + * @param id 证照id + */ + @Override + public void setLicenceRevert(String id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + Licence licence = new Licence(); + licence.setBorrowId(StringUtil.EMPTY); + update(licence, updateWrapper); + refreshCache(id); + } + + /** + * 获取我借用中的证照列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyRevertLicencePageList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setChargePersonId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryLicenceList(pageInfo); + iAuthUserService.setMationForMap(beans, "licenceAdmin", "licenceAdminMation"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceUseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceUseLinkServiceImpl.java new file mode 100644 index 0000000..3504abf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/licence/service/impl/LicenceUseLinkServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.licence.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.licence.dao.LicenceUseLinkDao; +import com.skyeye.eve.licence.entity.Licence; +import com.skyeye.eve.licence.entity.LicenceUseLink; +import com.skyeye.eve.licence.service.LicenceService; +import com.skyeye.eve.licence.service.LicenceUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: LicenceUseLinkServiceImpl + * @Description: 证照借用申请关联的证照信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "证照借用申请-证照Link", groupName = "证照模块", manageShow = false) +public class LicenceUseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements LicenceUseLinkService { + + @Autowired + private LicenceService licenceService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("证照信息不能为空."); + } + List licenceIds = beans.stream().map(LicenceUseLink::getLicenceId).distinct().collect(Collectors.toList()); + Map licenceMap = licenceService.selectMapByIds(licenceIds); + beans.forEach(licenceUseLink -> { + Licence licence = licenceMap.get(licenceUseLink.getLicenceId()); + if (licence == null) { + throw new CustomException("数据中包含不存在的证照信息."); + } + if (StrUtil.isNotEmpty(licence.getBorrowId())) { + throw new CustomException("该证照正在被他人借用,无法申请."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppController.java new file mode 100644 index 0000000..7ff11db --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.lightapp.entity.LightApp; +import com.skyeye.eve.lightapp.service.LightAppService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LightAppController + * @Description: 轻应用管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/4 23:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "轻应用管理", tags = "轻应用管理", modelName = "轻应用管理") +public class LightAppController { + + @Autowired + private LightAppService lightAppService; + + /** + * 获取轻应用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLightAppList", value = "获取轻应用列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LightAppController/queryLightAppList") + public void queryLightAppList(InputObject inputObject, OutputObject outputObject) { + lightAppService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑轻应用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLightApp", value = "新增/编辑轻应用", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LightApp.class) + @RequestMapping("/post/LightAppController/writeLightApp") + public void writeLightApp(InputObject inputObject, OutputObject outputObject) { + lightAppService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除轻应用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLightAppById", value = "删除轻应用", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LightAppController/deleteLightAppById") + public void deleteLightAppById(InputObject inputObject, OutputObject outputObject) { + lightAppService.deleteById(inputObject, outputObject); + } + + /** + * 获取启用的轻应用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLightAppUpList", value = "获取启用的轻应用列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "typeId", name = "typeId", value = "类型id")}) + @RequestMapping("/post/LightAppController/queryLightAppUpList") + public void queryLightAppUpList(InputObject inputObject, OutputObject outputObject) { + lightAppService.queryLightAppUpList(inputObject, outputObject); + } + + /** + * 添加轻应用到桌面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertLightAppToWin", value = "添加轻应用到桌面", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LightAppController/insertLightAppToWin") + public void insertLightAppToWin(InputObject inputObject, OutputObject outputObject) { + lightAppService.insertLightAppToWin(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppTypeController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppTypeController.java new file mode 100644 index 0000000..1e5e145 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/controller/LightAppTypeController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.lightapp.entity.LightAppType; +import com.skyeye.eve.lightapp.service.LightAppTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LightAppTypeController + * @Description: 轻应用类型管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/4 23:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "轻应用类型管理", tags = "轻应用类型管理", modelName = "轻应用管理") +public class LightAppTypeController { + + @Autowired + private LightAppTypeService lightAppTypeService; + + /** + * 获取轻应用类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLightAppTypeList", value = "获取轻应用类型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LightAppTypeController/queryLightAppTypeList") + public void queryLightAppTypeList(InputObject inputObject, OutputObject outputObject) { + lightAppTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑轻应用类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLightAppType", value = "新增/编辑轻应用类型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LightAppType.class) + @RequestMapping("/post/LightAppTypeController/writeLightAppType") + public void writeLightAppType(InputObject inputObject, OutputObject outputObject) { + lightAppTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除轻应用类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLightAppTypeById", value = "删除轻应用类型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LightAppTypeController/deleteLightAppTypeById") + public void deleteLightAppTypeById(InputObject inputObject, OutputObject outputObject) { + lightAppTypeService.deleteById(inputObject, outputObject); + } + + /** + * 获取启用的轻应用类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLightAppTypeUpList", value = "获取启用的轻应用类型列表", method = "GET", allUse = "2") + @RequestMapping("/post/LightAppTypeController/queryLightAppTypeUpList") + public void queryLightAppTypeUpList(InputObject inputObject, OutputObject outputObject) { + lightAppTypeService.queryLightAppTypeUpList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppDao.java new file mode 100644 index 0000000..c750207 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.lightapp.entity.LightApp; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LightAppDao + * @Description: 轻应用管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/12 9:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface LightAppDao extends SkyeyeBaseMapper { + + List> queryLightAppList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppTypeDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppTypeDao.java new file mode 100644 index 0000000..ba33e19 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/dao/LightAppTypeDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.lightapp.entity.LightAppType; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LightAppTypeDao + * @Description: 轻应用类型管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/11 8:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface LightAppTypeDao extends SkyeyeBaseMapper { + + List> queryLightAppTypeList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightApp.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightApp.java new file mode 100644 index 0000000..c77ce94 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightApp.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: LightApp + * @Description: 轻应用实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/12 9:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "light:app") +@TableName(value = "light_app") +@ApiModel("轻应用实体类") +public class LightApp extends BaseGeneralInfo { + + @TableField(value = "logo") + @ApiModelProperty(value = "logo图片") + private String logo; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "所属分类信息") + private LightAppType typeMation; + + @TableField(value = "app_url") + @ApiModelProperty(value = "应用地址", required = "required") + private String appUrl; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightAppType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightAppType.java new file mode 100644 index 0000000..34aebf6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/entity/LightAppType.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.IconOrImgInfo; +import lombok.Data; + +/** + * @ClassName: LightAppType + * @Description: 轻应用类型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/11 8:33 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "light:appType") +@TableName(value = "light_app_type") +@ApiModel("轻应用类型实体类") +public class LightAppType extends IconOrImgInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppService.java new file mode 100644 index 0000000..8006cdc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.lightapp.entity.LightApp; + +/** + * @ClassName: LightAppService + * @Description: 轻应用管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/12 9:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface LightAppService extends SkyeyeBusinessService { + + void queryLightAppUpList(InputObject inputObject, OutputObject outputObject); + + void insertLightAppToWin(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppTypeService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppTypeService.java new file mode 100644 index 0000000..d46589d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/LightAppTypeService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.lightapp.entity.LightAppType; + +/** + * @ClassName: LightAppTypeService + * @Description: 轻应用类型管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/11 8:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface LightAppTypeService extends SkyeyeBusinessService { + + void queryLightAppTypeUpList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppServiceImpl.java new file mode 100644 index 0000000..a4b2339 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppServiceImpl.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.lightapp.dao.LightAppDao; +import com.skyeye.eve.lightapp.entity.LightApp; +import com.skyeye.eve.lightapp.service.LightAppService; +import com.skyeye.eve.lightapp.service.LightAppTypeService; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.pro.win.SysEveWinDragDropService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LightAppServiceImpl + * @Description: 轻应用管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "轻应用管理", groupName = "轻应用管理") +public class LightAppServiceImpl extends SkyeyeBusinessServiceImpl implements LightAppService { + + @Autowired + private SysEveWinDragDropService sysEveWinDragDropService; + + @Autowired + private LightAppTypeService lightAppTypeService; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryLightAppList(commonPageInfo); + lightAppTypeService.setMationForMap(beans, "typeId", "typeMation"); + return beans; + } + + /** + * 获取启用的轻应用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryLightAppUpList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String typeId = map.get("typeId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(LightApp::getEnabled), EnableEnum.ENABLE_USING.getKey()); + if (StrUtil.isNotEmpty(typeId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(LightApp::getTypeId), typeId); + } + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + @Override + public LightApp selectById(String id) { + LightApp lightApp = super.selectById(id); + lightAppTypeService.setDataMation(lightApp, LightApp::getTypeId); + return lightApp; + } + + /** + * 添加轻应用到桌面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertLightAppToWin(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + LightApp lightApp = selectById(id); + if (ObjectUtil.isEmpty(lightApp)) { + throw new CustomException("该应用不存在,无法进行添加!"); + } + + if (EnableEnum.ENABLE_USING.getKey().equals(lightApp.getEnabled())) { + // 启用状态可以添加 + map.put("menuName", lightApp.getName()); + map.put("menuNameEn", lightApp.getName()); + map.put("menuIconType", 2); + map.put("menuIconPic", lightApp.getLogo()); + map.put("menuUrl", lightApp.getName()); + map.put("deskTopId", "winfixedpage00000000"); + map.put("lightAppId", id); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + ExecuteFeignClient.get(() -> sysEveWinDragDropService.insertWinCustomMenu(map)); + outputObject.setBean(map); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppTypeServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppTypeServiceImpl.java new file mode 100644 index 0000000..f4f91c0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/lightapp/service/impl/LightAppTypeServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.lightapp.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.lightapp.dao.LightAppTypeDao; +import com.skyeye.eve.lightapp.entity.LightAppType; +import com.skyeye.eve.lightapp.service.LightAppTypeService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LightAppTypeServiceImpl + * @Description: 轻应用类型管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "轻应用类型管理", groupName = "轻应用管理") +public class LightAppTypeServiceImpl extends SkyeyeBusinessServiceImpl implements LightAppTypeService { + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryLightAppTypeList(commonPageInfo); + return beans; + } + + /** + * 获取启用的轻应用类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryLightAppTypeUpList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(LightAppType::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(LightAppType::getOrderBy)); + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/classenum/MailCategory.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/classenum/MailCategory.java new file mode 100644 index 0000000..393d556 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/classenum/MailCategory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MailCategory + * @Description: 通讯录类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MailCategory implements SkyeyeEnumClass { + + PERSON(1, "个人通讯录", true, true), + COMMON(2, "公共通讯录", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailController.java new file mode 100644 index 0000000..a8c6265 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.mail.entity.Mail; +import com.skyeye.eve.mail.service.MailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MailController + * @Description: 通讯录管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/23 12:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "通讯录管理", tags = "通讯录管理", modelName = "通讯录管理") +public class MailController { + + @Autowired + private MailService mailService; + + /** + * 获取通讯录列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMailList", value = "获取通讯录列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MailController/queryMailList") + public void queryMailList(InputObject inputObject, OutputObject outputObject) { + mailService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑通讯录信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMail", value = "新增/编辑通讯录信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Mail.class) + @RequestMapping("/post/MailController/writeMail") + public void writeMail(InputObject inputObject, OutputObject outputObject) { + mailService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除通讯录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMailById", value = "删除通讯录", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MailController/deleteMailById") + public void deleteMailById(InputObject inputObject, OutputObject outputObject) { + mailService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailTypeController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailTypeController.java new file mode 100644 index 0000000..4c9512d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/controller/MailTypeController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.mail.entity.MailType; +import com.skyeye.eve.mail.service.MailTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MailTypeController + * @Description: 通讯录分组管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/23 12:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "通讯录分组管理", tags = "通讯录分组管理", modelName = "通讯录分组管理") +public class MailTypeController { + + @Autowired + private MailTypeService mailTypeService; + + /** + * 获取通讯录类别列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMailTypeList", value = "获取通讯录类别列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MailTypeController/queryMailTypeList") + public void queryMailTypeList(InputObject inputObject, OutputObject outputObject) { + mailTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑通讯录类型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMailType", value = "新增/编辑通讯录类型信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = MailType.class) + @RequestMapping("/post/MailTypeController/writeMailType") + public void insertMailMationType(InputObject inputObject, OutputObject outputObject) { + mailTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除通讯录类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMailTypeById", value = "删除通讯录类型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MailTypeController/deleteMailTypeById") + public void deleteMailTypeById(InputObject inputObject, OutputObject outputObject) { + mailTypeService.deleteById(inputObject, outputObject); + } + + /** + * 获取我的通讯录类型用作下拉框展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllMailTypeList", value = "获取我的通讯录类型用作下拉框展示", method = "GET", allUse = "2") + @RequestMapping("/post/MailTypeController/queryAllMailTypeList") + public void queryAllMailTypeList(InputObject inputObject, OutputObject outputObject) { + mailTypeService.queryAllMailTypeList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailDao.java new file mode 100644 index 0000000..4b4cc1d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.mail.entity.Mail; + +/** + * @ClassName: MailDao + * @Description: 通讯录管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MailDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailTypeDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailTypeDao.java new file mode 100644 index 0000000..e7a3a9c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/dao/MailTypeDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.mail.entity.MailType; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MailTypeDao + * @Description: 通讯录分组管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/23 12:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MailTypeDao extends SkyeyeBaseMapper { + + List> queryMailTypeList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/Mail.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/Mail.java new file mode 100644 index 0000000..a0d6044 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/Mail.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Mail + * @Description: 通讯录实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/23 13:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField +@RedisCacheField(name = "mail:list") +@TableName(value = "sys_mail_list", autoResultMap = true) +@ApiModel("通讯录实体类") +public class Mail extends BaseGeneralInfo { + + @TableField(value = "category") + @ApiModelProperty(value = "通讯录类型,参考#MailCategory", required = "required,num") + private Integer category; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分组") + private String typeId; + + @TableField(exist = false) + @Property(value = "所属分组信息") + private MailType typeMation; + + @TableField(value = "company") + @ApiModelProperty(value = "公司") + private String company; + + @TableField(value = "department") + @ApiModelProperty(value = "部门") + private String department; + + @TableField(value = "personal_phone") + @ApiModelProperty(value = "个人电话") + private String personalPhone; + + @TableField(value = "work_phone") + @ApiModelProperty(value = "办公电话") + private String workPhone; + + @TableField(value = "fax") + @ApiModelProperty(value = "传真") + private String fax; + + @TableField(value = "email") + @ApiModelProperty(value = "邮箱") + private String email; + + @TableField(value = "other_phone") + @ApiModelProperty(value = "其他电话") + private String otherPhone; + + @TableField(value = "other_email") + @ApiModelProperty(value = "其他邮箱") + private String otherEmail; + + @TableField(value = "work_address") + @ApiModelProperty(value = "商务地址") + private String workAddress; + + @TableField(value = "work_code") + @ApiModelProperty(value = "商务邮编") + private String workCode; + + @TableField(value = "person_address") + @ApiModelProperty(value = "个人地址") + private String personAddress; + + @TableField(value = "person_code") + @ApiModelProperty(value = "个人邮编") + private String personCode; + + @TableField(value = "company_url") + @ApiModelProperty(value = "公司网址") + private String companyUrl; + + @TableField(value = "person_url") + @ApiModelProperty(value = "个人网址") + private String personUrl; + + @TableField(value = "birthday") + @ApiModelProperty(value = "生日 年月日") + private String birthday; + + @TableField(value = "wechat_num") + @ApiModelProperty(value = "微信号") + private String wechat_num; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/MailType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/MailType.java new file mode 100644 index 0000000..be9f7be --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/entity/MailType.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: MailType + * @Description: 通讯录分组实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/23 11:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField +@RedisCacheField(name = "mail:type") +@TableName(value = "sys_mail_type", autoResultMap = true) +@ApiModel("通讯录分组实体类") +public class MailType extends BaseGeneralInfo { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailService.java new file mode 100644 index 0000000..e8f1d59 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.mail.entity.Mail; + +/** + * @ClassName: MailService + * @Description: 通讯录管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/23 12:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface MailService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailTypeService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailTypeService.java new file mode 100644 index 0000000..c91d789 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/MailTypeService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.mail.entity.MailType; + +/** + * @ClassName: MailTypeService + * @Description: 通讯录分组管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/23 12:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MailTypeService extends SkyeyeBusinessService { + + void queryAllMailTypeList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailServiceImpl.java new file mode 100644 index 0000000..2157787 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailServiceImpl.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.mail.dao.MailDao; +import com.skyeye.eve.mail.entity.Mail; +import com.skyeye.eve.mail.service.MailService; +import com.skyeye.eve.mail.service.MailTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: MailServiceImpl + * @Description: 通讯录管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "通讯录管理", groupName = "通讯录管理") +public class MailServiceImpl extends SkyeyeBusinessServiceImpl implements MailService { + + @Autowired + private MailTypeService mailTypeService; + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Mail::getCategory), commonPageInfo.getType()); + if (StrUtil.equals(commonPageInfo.getType(), "1")) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Mail::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + } + return queryWrapper; + } + + @Override + public Mail selectById(String id) { + Mail mail = super.selectById(id); + mailTypeService.setDataMation(mail, Mail::getTypeId); + return mail; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailTypeServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailTypeServiceImpl.java new file mode 100644 index 0000000..3444b1b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mail/service/impl/MailTypeServiceImpl.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mail.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.mail.dao.MailTypeDao; +import com.skyeye.eve.mail.entity.MailType; +import com.skyeye.eve.mail.service.MailTypeService; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MailTypeServiceImpl + * @Description: 通讯录分组管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/23 12:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "通讯录分组管理", groupName = "通讯录分组管理") +public class MailTypeServiceImpl extends SkyeyeBusinessServiceImpl implements MailTypeService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setCreateId(InputObject.getLogParamsStatic().get("id").toString()); + List> beans = skyeyeBaseMapper.queryMailTypeList(commonPageInfo); + return beans; + } + + @Override + public void validatorEntity(MailType entity) { + super.validatorEntity(entity); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MailType::getName), entity.getName()); + queryWrapper.eq(MybatisPlusUtil.toColumns(MailType::getCreateId), userId); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + MailType checkMailType = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkMailType)) { + throw new CustomException("this data['name'] is exist."); + } + } + + /** + * 获取我的通讯录类型用作下拉框展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllMailTypeList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MailType::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(MailType::getCreateTime)); + List mailTypeList = list(queryWrapper); + outputObject.setBeans(mailTypeList); + outputObject.settotal(mailTypeList.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mq/job/impl/AssetGenerateBarcodeServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mq/job/impl/AssetGenerateBarcodeServiceImpl.java new file mode 100644 index 0000000..05e3688 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/mq/job/impl/AssetGenerateBarcodeServiceImpl.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.mq.job.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.util.FileUtil; +import com.skyeye.eve.assets.entity.Asset; +import com.skyeye.eve.assets.entity.AssetReport; +import com.skyeye.eve.assets.service.AssetReportService; +import com.skyeye.eve.assets.service.AssetService; +import com.skyeye.eve.assets.service.impl.AssetServiceImpl; +import com.skyeye.eve.coderule.service.ICodeRuleService; +import com.skyeye.eve.rest.barcode.BarCodeMation; +import com.skyeye.eve.rest.barcode.BarCodeMationBox; +import com.skyeye.eve.service.IBarCodeService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AssetGenerateBarcodeServiceImpl + * @Description: 资产生成条形码的处理类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/27 21:47 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.asset-generate-barcode}", + consumerGroup = "${topic.asset-generate-barcode}", + selectorExpression = "${spring.profiles.active}") +public class AssetGenerateBarcodeServiceImpl implements RocketMQListener { + + private static Logger LOGGER = LoggerFactory.getLogger(AssetGenerateBarcodeServiceImpl.class); + + @Autowired + private AssetReportService assetReportService; + + @Autowired + private AssetService assetService; + + @Value("${spring.application.name}") + private String springApplicationName; + + @Autowired + private IBarCodeService iBarCodeService; + + @Autowired + private ICodeRuleService iCodeRuleService; + + private static final Integer FILE_SAVE_PATH = FileConstants.FileUploadPath.ASSET_PURCHASE_GENERATE_BARCODE.getType()[0]; + + @Override + public void onMessage(String data) { + LOGGER.info("start get Bar Code, data is {}", data); + Map map = JSONUtil.toBean(data, null); + List> list = JSONUtil.toList(map.get("list").toString(), null); + String className = map.get("className").toString(); + String userId = map.get("userId").toString(); + + List assetIdList = list.stream().map(bean -> bean.get("assetId").toString()).distinct().collect(Collectors.toList()); + Map assetMap = assetService.selectMapByIds(assetIdList); + List barCodeMationList = new ArrayList<>(); + // 生成条形码 + for (Map bean : list) { + String assetId = bean.get("assetId").toString(); + Asset asset = assetMap.get(assetId); + if (ObjectUtil.isEmpty(asset) || StrUtil.isEmpty(asset.getId())) { + continue; + } + Integer number = Integer.parseInt(bean.get("operNumber").toString()); + List codeList = iCodeRuleService.getNextCodeByClassName(AssetServiceImpl.class.getName(), + BeanUtil.beanToMap(asset), number); + List assetReportList = new ArrayList<>(); + codeList.forEach(code -> { + AssetReport assetReport = new AssetReport(); + assetReport.setAssetId(assetId); + assetReport.setAssetNum(code); + assetReportList.add(assetReport); + }); + assetReportService.createEntity(assetReportList, userId); + + assetReportList.forEach(assetReport -> { + String barCodePath = FileUtil.getImageBarCodePath(assetReport.getAssetNum(), FILE_SAVE_PATH); + BarCodeMation barCodeMation = new BarCodeMation(); + barCodeMation.setCodeNum(assetReport.getAssetNum()); + barCodeMation.setObjectId(assetReport.getId()); + barCodeMation.setImagePath(barCodePath); + barCodeMationList.add(barCodeMation); + }); + } + + if (CollectionUtil.isEmpty(barCodeMationList)) { + LOGGER.warn("generate asset report is Empty."); + return; + } + BarCodeMationBox barCodeMationBox = new BarCodeMationBox(); + barCodeMationBox.setBarCodeList(barCodeMationList); + barCodeMationBox.setCodeImplClass(className); + barCodeMationBox.setSpringApplicationName(springApplicationName); + iBarCodeService.writeBarCode(barCodeMationBox); + + LOGGER.info("end get Bar Code, data is {}", data); + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/FileFolderType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/FileFolderType.java new file mode 100644 index 0000000..e99ce94 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/FileFolderType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FileFolderType + * @Description: 笔记和文件夹的类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FileFolderType implements SkyeyeEnumClass { + + FOLDER("folder", "文件夹", true, false), + NOTE("note", "笔记", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/NoteType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/NoteType.java new file mode 100644 index 0000000..6e2687f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/classenum/NoteType.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Locale; + +/** + * @ClassName: NoteType + * @Description: 笔记类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum NoteType implements SkyeyeEnumClass { + + EDITOR(1, "富文本编辑器", "note-1.png", true, false), + MD(2, "markdown笔记", "note-2.png", true, false), + WORD(3, "word笔记", "note-3.png", true, false), + EXCEL(4, "ecxel笔记", "note-4.png", true, false); + + private Integer key; + + private String value; + + private String iconLogo; + + private Boolean show; + + private Boolean isDefault; + + public static String getIconPathByType(Integer type) { + String iconLogo = "../../assets/images/%s"; + for (NoteType bean : NoteType.values()) { + if (type.equals(bean.getKey())) { + return String.format(Locale.ROOT, iconLogo, bean.getIconLogo()); + } + } + return StringUtils.EMPTY; + } + +} \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/controller/NoteController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/controller/NoteController.java new file mode 100644 index 0000000..a1aea53 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/controller/NoteController.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.note.entity.Note; +import com.skyeye.eve.note.service.NoteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: NoteController + * @Description: 笔记管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "笔记管理", tags = "笔记管理", modelName = "笔记管理") +public class NoteController { + + @Autowired + private NoteService noteService; + + /** + * 删除文件夹或笔记 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFileFolderById", value = "删除文件夹或笔记", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "文件夹/笔记id", required = "required"), + @ApiImplicitParam(id = "fileType", name = "fileType", value = "笔记或者文件夹类型", required = "required")}) + @RequestMapping("/post/NoteController/deleteFileFolderById") + public void deleteFileFolderById(InputObject inputObject, OutputObject outputObject) { + noteService.deleteFileFolderById(inputObject, outputObject); + } + + /** + * 编辑文件夹或者笔记的名称 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editFileFolderById", value = "编辑文件夹或者笔记的名称", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "文件夹/笔记id", required = "required"), + @ApiImplicitParam(id = "name", name = "name", value = "文件夹/笔记id的名称", required = "required"), + @ApiImplicitParam(id = "fileType", name = "fileType", value = "笔记或者文件夹类型", required = "required")}) + @RequestMapping("/post/NoteController/editFileFolderById") + public void editFileFolderById(InputObject inputObject, OutputObject outputObject) { + noteService.editFileFolderById(inputObject, outputObject); + } + + /** + * 获取当前用户最新的笔记列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNewNoteListByUserId", value = "获取当前用户最新的笔记列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/NoteController/queryNewNoteListByUserId") + public void queryNewNoteListByUserId(InputObject inputObject, OutputObject outputObject) { + noteService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑笔记 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeNote", value = "新增/编辑笔记", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Note.class) + @RequestMapping("/post/NoteController/writeNote") + public void writeNote(InputObject inputObject, OutputObject outputObject) { + noteService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据文件夹id获取文件夹下的文件夹和笔记列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mynote006", value = "根据文件夹id获取文件夹下的文件夹和笔记列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "parentId", name = "parentId", value = "文件夹id", required = "required"), + @ApiImplicitParam(id = "search", name = "search", value = "搜索框的值")}) + @RequestMapping("/post/MyNoteController/queryFileAndContentListByFolderId") + public void queryFileAndContentListByFolderId(InputObject inputObject, OutputObject outputObject) { + noteService.queryFileAndContentListByFolderId(inputObject, outputObject); + } + + /** + * 根据id获取笔记信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNoteById", value = "根据id获取笔记信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "笔记id", required = "required")}) + @RequestMapping("/post/NoteController/queryNoteById") + public void queryNoteById(InputObject inputObject, OutputObject outputObject) { + noteService.selectById(inputObject, outputObject); + } + + /** + * 保存文件夹拖拽后的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mynote010", value = "保存文件夹拖拽后的信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "targetId", name = "targetId", value = "拖拽目标节点id", required = "required"), + @ApiImplicitParam(id = "arrId", name = "arrId", value = "拖拽节点id数组", required = "required")}) + @RequestMapping("/post/NoteController/editFileToDragById") + public void editFileToDragById(InputObject inputObject, OutputObject outputObject) { + noteService.editFileToDragById(inputObject, outputObject); + } + + /** + * 保存笔记移动后的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mynote011", value = "保存笔记移动后的信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "toId", name = "toId", value = "移动目标节点id", required = "required"), + @ApiImplicitParam(id = "moveId", name = "moveId", value = "移动笔记id", required = "required")}) + @RequestMapping("/post/NoteController/editNoteToMoveById") + public void editNoteToMoveById(InputObject inputObject, OutputObject outputObject) { + noteService.editNoteToMoveById(inputObject, outputObject); + } + + /** + * 根据id(文件夹或者笔记id)将笔记输出为压缩包 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "outputNoteIsZipJob", value = "根据id(文件夹或者笔记id)将笔记输出为压缩包", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "文件夹/文件id", required = "required"), + @ApiImplicitParam(id = "type", name = "type", value = "类型", required = "required")}) + @RequestMapping("/post/NoteController/outputNoteIsZipJob") + public void outputNoteIsZipJob(InputObject inputObject, OutputObject outputObject) { + noteService.outputNoteIsZipJob(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/dao/NoteDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/dao/NoteDao.java new file mode 100644 index 0000000..0ea1fa7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/dao/NoteDao.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.note.entity.Note; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: NoteDao + * @Description: 笔记管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface NoteDao extends SkyeyeBaseMapper { + + List> queryNewNoteListByUserId(CommonPageInfo pageInfo); + + List> queryFileAndContentListByFolderId(Map map); + + List> queryFileList(@Param("folderList") List> folderList, + @Param("deleteFlag") Integer deleteFlag); + + int insertFileListByList(@Param("fileList") List> fileList); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/entity/Note.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/entity/Note.java new file mode 100644 index 0000000..c8c01a1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/entity/Note.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Note + * @Description: 笔记实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/26 22:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("笔记实体类") +@TableName(value = "note_content") +public class Note extends BaseGeneralInfo { + + @TableField(value = "icon_logo", updateStrategy = FieldStrategy.NEVER) + @Property(value = "icon的图标") + private String iconLogo; + + @TableField(value = "content") + @ApiModelProperty(value = "笔记内容") + private String content; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "父文件夹id") + private String parentId; + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "笔记类型,参考#NoteType") + private Integer type; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/NoteService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/NoteService.java new file mode 100644 index 0000000..977acc2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/NoteService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.note.entity.Note; + +/** + * @ClassName: NoteService + * @Description: 笔记管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/25 19:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface NoteService extends SkyeyeBusinessService { + + void deleteFileFolderById(InputObject inputObject, OutputObject outputObject); + + void editFileFolderById(InputObject inputObject, OutputObject outputObject); + + void queryFileAndContentListByFolderId(InputObject inputObject, OutputObject outputObject); + + void editFileToDragById(InputObject inputObject, OutputObject outputObject); + + void editNoteToMoveById(InputObject inputObject, OutputObject outputObject); + + void outputNoteIsZipJob(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/impl/NoteServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/impl/NoteServiceImpl.java new file mode 100644 index 0000000..e5a0178 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/note/service/impl/NoteServiceImpl.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.note.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.folder.entity.Folder; +import com.skyeye.eve.folder.service.FolderService; +import com.skyeye.eve.note.classenum.FileFolderType; +import com.skyeye.eve.note.classenum.NoteType; +import com.skyeye.eve.note.dao.NoteDao; +import com.skyeye.eve.note.entity.Note; +import com.skyeye.eve.note.service.NoteService; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MyNoteServiceImpl + * @Description: 笔记管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "笔记管理", groupName = "笔记管理") +public class NoteServiceImpl extends SkyeyeBusinessServiceImpl implements NoteService { + + @Autowired + private FolderService folderService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + /** + * 删除文件夹或文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteFileFolderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + if (FileFolderType.FOLDER.getKey().equals(map.get("fileType").toString())) { + // 操作文件夹表 删除自身文件夹 + folderService.deleteById(id); + // 删除子文件夹 + folderService.deleteByParentId(id); + // 删除子文件 + deleteByParentId(id); + } else { + // 操作笔记内容表 删除自身文件 + deleteById(id); + } + } + + private void deleteByParentId(String parentId) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.apply("INSTR(CONCAT(',', " + MybatisPlusUtil.toColumns(Note::getParentId) + ", ','), CONCAT(',', {0}, ','))", parentId); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getDeleteFlag), DeleteFlagEnum.DELETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + /** + * 编辑文件夹或者文件的名称 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editFileFolderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + String name = map.get("name").toString(); + String fileType = map.get("fileType").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (FileFolderType.FOLDER.getKey().equals(fileType)) { + // 操作文件夹表 + folderService.editNameById(id, name, userId); + } else { + // 操作笔记表 + editNameById(id, name, userId); + } + } + + private void editNameById(String id, String name, String userId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getName), name); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryNewNoteListByUserId(pageInfo); + return beans; + } + + @Override + public void createPrepose(Note entity) { + String parentId = folderService.setParentId(entity.getParentId()); + entity.setParentId(parentId); + entity.setIconLogo(NoteType.getIconPathByType(entity.getType())); + if (StrUtil.isNotEmpty(entity.getRemark()) && entity.getRemark().length() > 100) { + entity.setRemark(entity.getRemark().substring(0, 99)); + } + } + + @Override + public void updatePrepose(Note entity) { + Note note = selectById(entity.getId()); + entity.setParentId(note.getParentId()); + if (entity.getRemark().length() > 100) { + entity.setRemark(entity.getRemark().substring(0, 99)); + } + } + + @Override + public Note selectById(String id) { + Note note = super.selectById(id); + iAuthUserService.setName(note, "createId", "createName"); + return note; + } + + /** + * 根据文件夹id获取文件夹下的文件夹和笔记列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFileAndContentListByFolderId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + map.put("deleteFlag", DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryFileAndContentListByFolderId(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 保存文件夹拖拽后的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editFileToDragById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String newParentId; + String targetId = map.get("targetId").toString(); + // 拖拽文件夹新的父id + if (targetId.equals("2")) { + newParentId = "2" + ","; + } else { + Folder folder = folderService.selectById(targetId); + newParentId = folder.getParentId() + targetId + ","; + } + String arrId = map.get("arrId").toString(); + // 拖拽文件夹的id数组 + List arr = Arrays.asList(arrId.split(",")); + if (CollectionUtil.isNotEmpty(arr)) { + // 选择保存的文件夹不为空 + List> folderList = folderService.queryFolderAndChildList(arr); + if (CollectionUtil.isNotEmpty(folderList)) { + // 删除之前的信息 + List ids = folderList.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + folderService.deleteById(ids); + } + List> fileList = skyeyeBaseMapper.queryFileList(folderList, DeleteFlagEnum.NOT_DELETE.getKey()); + if (CollectionUtil.isNotEmpty(fileList)) { + // 删除之前的信息 + List ids = fileList.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + deleteById(ids); + } + for (Map folder : folderList) {//重置父id + String[] str = folder.get("parentId").toString().split(","); + folder.put("directParentId", str[str.length - 1]); + folder.put("newId", ToolUtil.getSurFaceId()); + } + // 将数据转化为树的形式,方便进行父id重新赋值 + folderList = ToolUtil.listToTree(folderList, "id", "directParentId", "children"); + ToolUtil.FileListParentISEdit(folderList, newParentId);// 替换父id + folderList = ToolUtil.FileTreeTransList(folderList);// 将树转为list + // 为文件重置新parentId参数 + for (Map folder : folderList) { + String parentId = folder.get("parentId").toString() + folder.get("id").toString() + ","; + String nParentId = folder.get("newParentId").toString() + folder.get("newId").toString() + ","; + // 重置文件的参数 + for (Map file : fileList) { + if (file.get("parentId").toString().equals(parentId)) { + file.put("newParentId", nParentId); + file.put("newId", ToolUtil.getSurFaceId()); + } + } + } + if (CollectionUtil.isNotEmpty(folderList)) { + folderService.insertFileFolderList(folderList); + } + if (CollectionUtil.isNotEmpty(fileList)) { + skyeyeBaseMapper.insertFileListByList(fileList); + } + } + } + + /** + * 保存笔记移动后的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editNoteToMoveById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 要移动的笔记id + String rowId = map.get("moveId").toString(); + // 移动后的目录id + String toId = map.get("toId").toString(); + String parentId = folderService.setParentId(toId); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, rowId); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getParentId), parentId); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateId), inputObject.getLogParams().get("id").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Note::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + /** + * 根据id(文件夹或者笔记id)将笔记输出为压缩包 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void outputNoteIsZipJob(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + String type = map.get("type").toString(); + Map mation; + if (FileFolderType.FOLDER.getKey().equals(type)) { + // 获取文件夹信息 + mation = folderService.selectMapById(id); + } else { + // 获取文件信息 + mation = selectMapById(id); + } + if (CollectionUtil.isEmpty(mation)) { + throw new CustomException("该信息不存在"); + } + String userId = inputObject.getLogParams().get("id").toString(); + Map json = new HashMap<>(); + json.put("title", mation.get("name").toString()); + json.put("noteType", type); + json.put("rowId", id); + json.put("userId", userId); + json.put("type", MqConstants.JobMateMationJobType.OUTPUT_NOTES_IS_ZIP.getJobType()); + // 启动任务 + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(json)); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeRealLinesType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeRealLinesType.java new file mode 100644 index 0000000..a45a52d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeRealLinesType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: NoticeRealLinesType + * @Description: 公告上线类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 20:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum NoticeRealLinesType implements SkyeyeEnumClass { + + HAND_MOVEMENT(1, "手动上线", false, false), + AT_REGULAR_TIME(2, "定时上线", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeState.java new file mode 100644 index 0000000..946ebfa --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: NoticeState + * @Description: 公告状态 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum NoticeState implements SkyeyeEnumClass { + + NEW(1, "新建", true, true), + UP(2, "上线", true, false), + DOWN(3, "下线", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeTimeSend.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeTimeSend.java new file mode 100644 index 0000000..f5134f2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/classenum/NoticeTimeSend.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: NoticeTimeSend + * @Description: 是否设置定时发送 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 20:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum NoticeTimeSend implements SkyeyeEnumClass { + + DO_NOT_SET(1, "不设置", true, true), + SET_UP(2, "设置", true, false), + EXPIRED(3, "已失效", false, false), + IMPLEMENTED(4, "已实行", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/NoticeController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/NoticeController.java new file mode 100644 index 0000000..091e9d1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/NoticeController.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.notice.entity.Notice; +import com.skyeye.eve.notice.service.NoticeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: NoticeController + * @Description: 公告管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 20:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "公告管理", tags = "公告管理", modelName = "公告管理") +public class NoticeController { + + @Autowired + private NoticeService noticeService; + + /** + * 获取公告列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNoticeList", value = "获取公告列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/NoticeController/queryNoticeList") + public void queryNoticeList(InputObject inputObject, OutputObject outputObject) { + noticeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑公告信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeNotice", value = "新增/编辑公告信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Notice.class) + @RequestMapping("/post/NoticeController/writeNotice") + public void writeNotice(InputObject inputObject, OutputObject outputObject) { + noticeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID删除公告 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteNoticeById", value = "根据ID删除公告", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/NoticeController/deleteNoticeById") + public void deleteNoticeById(InputObject inputObject, OutputObject outputObject) { + noticeService.deleteById(inputObject, outputObject); + } + + /** + * 获取用户收到的公告 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserReceivedNotice", value = "获取用户收到的公告", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/NoticeController/queryUserReceivedNotice") + public void queryUserReceivedNotice(InputObject inputObject, OutputObject outputObject) { + noticeService.queryUserReceivedNotice(inputObject, outputObject); + } + + /** + * 获取用户收到的前8条公告 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserReceivedTopNotice", value = "获取用户收到的前8条公告", method = "GET", allUse = "2") + @RequestMapping("/post/NoticeController/queryUserReceivedTopNotice") + public void queryUserReceivedTopNotice(InputObject inputObject, OutputObject outputObject) { + noticeService.queryUserReceivedTopNotice(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/UserMessageController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/UserMessageController.java new file mode 100644 index 0000000..0c7c5c7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/controller/UserMessageController.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.notice.entity.UserMessageBox; +import com.skyeye.eve.notice.service.UserMessageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: UserMessageController + * @Description: 用户消息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/31 21:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "用户消息管理", tags = "用户消息管理", modelName = "内部消息模块") +public class UserMessageController { + + @Autowired + private UserMessageService userMessageService; + + /** + * 获取当前用户前8条未读的消息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getTopEightMessageList", value = "获取当前用户前8条未读的消息列表", method = "POST", allUse = "2") + @RequestMapping("/post/UserMessageController/getTopEightMessageList") + public void getTopEightMessageList(InputObject inputObject, OutputObject outputObject) { + userMessageService.getTopEightMessageList(inputObject, outputObject); + } + + /** + * 分页查询当前用户的消息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserMessageList", value = "分页查询当前用户的消息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/UserMessageController/queryUserMessageList") + public void getAllNoticeListByUserId(InputObject inputObject, OutputObject outputObject) { + userMessageService.queryPageList(inputObject, outputObject); + } + + /** + * 用户阅读消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editMessageById", value = "用户阅读消息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/UserMessageController/editMessageById") + public void editMessageById(InputObject inputObject, OutputObject outputObject) { + userMessageService.editMessageById(inputObject, outputObject); + } + + /** + * 删除消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMessageById", value = "删除消息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/UserMessageController/deleteMessageById") + public void deleteMessageById(InputObject inputObject, OutputObject outputObject) { + userMessageService.deleteById(inputObject, outputObject); + } + + /** + * 用户删除全部消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAllMessage", value = "用户删除全部消息", method = "DELETE", allUse = "2") + @RequestMapping("/post/UserMessageController/deleteAllMessage") + public void deleteAllMessage(InputObject inputObject, OutputObject outputObject) { + userMessageService.deleteAllMessage(inputObject, outputObject); + } + + /** + * 新增用户消息数据---给其他微服务调用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertUserMessage", value = "新增用户消息数据---给其他微服务调用", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = UserMessageBox.class) + @RequestMapping("/post/UserMessageController/insertUserMessage") + public void insertUserMessage(InputObject inputObject, OutputObject outputObject) { + userMessageService.insertUserMessage(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeDao.java new file mode 100644 index 0000000..fff4558 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeDao.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.notice.entity.Notice; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: NoticeDao + * @Description: 公告管理数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 21:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface NoticeDao extends SkyeyeBaseMapper { + + List> queryNoticeList(CommonPageInfo pageInfo); + + List> queryAllUserList(@Param("userIds") List userIds, @Param("stateList") List stateList); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeUserDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeUserDao.java new file mode 100644 index 0000000..d733450 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/NoticeUserDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.notice.entity.NoticeUser; + +/** + * @ClassName: NoticeUserDao + * @Description: 公告群发对象管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/31 10:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface NoticeUserDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/UserMessageDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/UserMessageDao.java new file mode 100644 index 0000000..47574a3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/dao/UserMessageDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.notice.entity.UserMessage; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: UserMessageDao + * @Description: 用户消息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 19:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UserMessageDao extends SkyeyeBaseMapper { + + List> queryUserMessageList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/Notice.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/Notice.java new file mode 100644 index 0000000..85c5021 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/Notice.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Notice + * @Description: 公告实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 19:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField +@RedisCacheField(name = "sys:notice") +@TableName(value = "sys_notice", autoResultMap = true) +@ApiModel("公告实体类") +public class Notice extends BaseGeneralInfo { + + @TableField(value = "content") + @ApiModelProperty(value = "内容", required = "required") + private String content; + + @TableField(value = "state") + @ApiModelProperty(value = "状态,参考#NoticeState", required = "required,num") + private Integer state; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序,值越大越往前", required = "required,num") + private Integer orderBy; + + @TableField(value = "whether_email") + @ApiModelProperty(value = "是否发送邮件通知,参考#WhetherEnum", required = "required,num") + private Integer whetherEmail; + + @TableField(value = "time_send") + @ApiModelProperty(value = "是否设置定时发送,参考#NoticeTimeSend", required = "required,num") + private Integer timeSend; + + @TableField(value = "delayed_time") + @ApiModelProperty(value = "当time_send为2时的定时任务时间") + private String delayedTime; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类,参考数据字典", required = "required") + private String typeId; + + @TableField(value = "real_lines_type") + @Property(value = "上线类型,参考#NoticeRealLinesType") + private Integer realLinesType; + + @TableField(value = "real_lines_time") + @Property(value = "真正的上线时间") + private String realLinesTime; + + @TableField(value = "send_type") + @ApiModelProperty(value = "是否群发所有人,参考#WhetherEnum", required = "required,num") + private Integer sendType; + + @TableField(exist = false) + @ApiModelProperty(value = "公告不是群发时,指定的人", required = "json") + private List receiver; + + @TableField(exist = false) + @Property(value = "公告不是群发时,指定的人") + private List> receiverMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/NoticeUser.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/NoticeUser.java new file mode 100644 index 0000000..c4763b6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/NoticeUser.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: NoticeUser + * @Description: 公告群发对象表 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 23:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "sys_notice_user", autoResultMap = true) +@ApiModel("公告群发对象表") +public class NoticeUser extends CommonInfo { + + @TableField(value = "user_id") + @Property(value = "用户id") + private String userId; + + @TableField(value = "notice_id") + @Property(value = "公告id") + private String noticeId; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessage.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessage.java new file mode 100644 index 0000000..d66628c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessage.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: UserNotice + * @Description: 用户内部消息的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 14:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_eve_user_notice") +@ApiModel("用户内部消息的实体类") +public class UserMessage extends BaseGeneralInfo { + + @TableField("content") + @ApiModelProperty(value = "通知内容", required = "required") + private String content; + + @TableField("state") + @Property("是否已读,参考#WhetherEnum") + private Integer state; + + @TableField("read_time") + @Property("消息阅读时间") + private String readTime; + + @TableField("receive_id") + @ApiModelProperty(value = "消息接收人", required = "required") + private String receiveId; + + @TableField("type") + @ApiModelProperty(value = "消息类型,参考#NoticeUserMessageTypeEnum", required = "required,num") + private Integer type; + + @TableField(exist = false) + @ApiModelProperty(value = "传递过来的创建id,用来设置创建人", required = "required") + private String createUserId; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessageBox.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessageBox.java new file mode 100644 index 0000000..3acda8d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/entity/UserMessageBox.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: UserNoticeMationBox + * @Description: 用户内部消息的实体类的盒子,支持集合使用 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 14:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("用户内部消息的实体类的盒子,支持集合使用") +public class UserMessageBox implements Serializable { + + @ApiModelProperty(value = "用户内部消息", required = "required") + private List userNoticeMationList; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeService.java new file mode 100644 index 0000000..244f1c0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.notice.entity.Notice; + +/** + * @ClassName: NoticeService + * @Description: 公告管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/30 20:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface NoticeService extends SkyeyeBusinessService { + + void queryUserReceivedNotice(InputObject inputObject, OutputObject outputObject); + + void editNoticeStateToUp(String id); + + void queryUserReceivedTopNotice(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeUserService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeUserService.java new file mode 100644 index 0000000..3ccc3dc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/NoticeUserService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.notice.entity.NoticeUser; + +import java.util.List; + +/** + * @ClassName: NoticeUserService + * @Description: 公告群发对象管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/31 10:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface NoticeUserService extends SkyeyeBusinessService { + + void deleteNoticeUserByNoticeId(String noticeId); + + void saveNoticeUser(String noticeId, List userIdList); + + List queryNoticeUserByNoticeId(String noticeId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/UserMessageService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/UserMessageService.java new file mode 100644 index 0000000..afbc9c6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/UserMessageService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.notice.entity.UserMessage; + +/** + * @ClassName: UserMessageService + * @Description: 用户消息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/31 21:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface UserMessageService extends SkyeyeBusinessService { + + void getTopEightMessageList(InputObject inputObject, OutputObject outputObject); + + void editMessageById(InputObject inputObject, OutputObject outputObject); + + void deleteAllMessage(InputObject inputObject, OutputObject outputObject); + + void insertUserMessage(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeServiceImpl.java new file mode 100644 index 0000000..995c7e1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeServiceImpl.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.*; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.UserStaffState; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.notice.classenum.NoticeRealLinesType; +import com.skyeye.eve.notice.classenum.NoticeState; +import com.skyeye.eve.notice.classenum.NoticeTimeSend; +import com.skyeye.eve.notice.dao.NoticeDao; +import com.skyeye.eve.notice.entity.Notice; +import com.skyeye.eve.notice.service.NoticeService; +import com.skyeye.eve.notice.service.NoticeUserService; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: NoticeServiceImpl + * @Description: 公告管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 21:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "公告管理", groupName = "公告管理") +public class NoticeServiceImpl extends SkyeyeBusinessServiceImpl implements NoticeService { + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private NoticeUserService noticeUserService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryNoticeList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(Notice entity) { + super.validatorEntity(entity); + if (entity.getSendType().equals(WhetherEnum.DISABLE_USING.getKey())) { + // 群发指定人 + if (CollectionUtil.isEmpty(entity.getReceiver())) { + throw new CustomException("请选择公告接收人."); + } + } + + if (entity.getTimeSend().equals(NoticeTimeSend.SET_UP.getKey())) { + // 定时发送 + entity.setRealLinesType(NoticeRealLinesType.AT_REGULAR_TIME.getKey()); + if (StrUtil.isEmpty(entity.getDelayedTime())) { + throw new CustomException("请选择定时发送的时间."); + } + if (DateUtil.compare(entity.getDelayedTime(), DateUtil.getTimeAndToString())) { + // 定时通知时间早于当前时间 + throw new CustomException("公告定时发送的时间不能早于当前时间,请重新设定发送时间."); + } + } else { + // 手动发送 + entity.setRealLinesType(NoticeRealLinesType.HAND_MOVEMENT.getKey()); + if (entity.getState().equals(NoticeState.UP.getKey())) { + entity.setRealLinesTime(DateUtil.getTimeAndToString()); + } + } + } + + @Override + public void updatePrepose(Notice entity) { + if (entity.getTimeSend().equals(NoticeTimeSend.DO_NOT_SET.getKey())) { + // 手动发送 + Notice oldNotice = selectById(entity.getId()); + if (oldNotice.getTimeSend().equals(NoticeTimeSend.SET_UP.getKey())) { + // 如果老的数据时定时发送,则删除定时任务 + iQuartzService.stopAndDeleteTaskQuartz(entity.getId()); + } + } + } + + @Override + public void writePostpose(Notice entity, String userId) { + super.writePostpose(entity, userId); + List stateList = Arrays.asList(new String[]{UserStaffState.ON_THE_JOB.getKey().toString(), UserStaffState.PROBATION.getKey().toString(), UserStaffState.PROBATION_PERIOD.getKey().toString()}); + if (entity.getSendType().equals(WhetherEnum.ENABLE_USING.getKey())) { + // 群发所有人 + List> userInfoList = skyeyeBaseMapper.queryAllUserList(null, stateList); + List userIds = userInfoList.stream().map(bean -> bean.get("userId").toString()) + .collect(Collectors.toList()); + noticeUserService.saveNoticeUser(entity.getId(), userIds); + } else { + // 群发指定人 + noticeUserService.saveNoticeUser(entity.getId(), entity.getReceiver()); + } + + if (entity.getTimeSend().equals(NoticeTimeSend.SET_UP.getKey())) { + // 定时发送 启动定时任务,要求定时通知时间晚于当前时间 + this.startUpTaskQuartz(entity.getId(), entity.getName(), entity.getDelayedTime()); + } else { + // 手动发送 + if (entity.getWhetherEmail().equals(WhetherEnum.ENABLE_USING.getKey()) + && entity.getState().equals(NoticeState.UP.getKey())) { + // 开启了邮件通知并且是上线状态 + List> userEmail; + if (entity.getSendType().equals(WhetherEnum.ENABLE_USING.getKey())) { + // 群发所有人 + userEmail = skyeyeBaseMapper.queryAllUserList(null, stateList); + } else { + // 群发指定人 + userEmail = skyeyeBaseMapper.queryAllUserList(entity.getReceiver(), stateList); + } + // 启动mq消息任务 + Map notice = new HashMap<>(); + notice.put("title", "公告提醒"); + notice.put("content", "内部公告 -【" + entity.getName() + "】"); + notice.put("email", userEmail); + // 消息队列任务类型 + notice.put("type", MqConstants.JobMateMationJobType.NOTICE_SEND.getJobType()); + sendMQProducer(JSONUtil.toJsonStr(notice), userId); + } + } + } + + @Override + public Notice getFromCache(String key) { + Notice notice = super.getFromCache(key); + if (notice.getSendType().equals(WhetherEnum.DISABLE_USING.getKey())) { + // 群发指定人 + notice.setReceiver(noticeUserService.queryNoticeUserByNoticeId(notice.getId())); + } + return notice; + } + + @Override + public Notice selectById(String id) { + Notice notice = super.selectById(id); + if (notice.getSendType().equals(WhetherEnum.DISABLE_USING.getKey())) { + // 群发指定人 + List> users = iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(notice.getReceiver())); + notice.setReceiverMation(users); + } + return notice; + } + + /** + * 定时发送公告 + * + * @param name + * @param title + * @param delayedTime + */ + private void startUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.QUARTZ_NOTICE_GROUP_STR.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + private void sendMQProducer(String jsonStr, String userId) { + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(jsonStr); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + @Override + public void deletePostpose(String id) { + // 删除定时任务 + iQuartzService.stopAndDeleteTaskQuartz(id); + } + + /** + * 用户收到的公告 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserReceivedNotice(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + pageInfo.setObjectId(inputObject.getLogParams().get("id").toString()); + pageInfo.setState(NoticeState.UP.getKey().toString()); + List> beans = skyeyeBaseMapper.queryNoticeList(pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void editNoticeStateToUp(String id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Notice::getState), NoticeState.UP.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Notice::getRealLinesTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void queryUserReceivedTopNotice(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(CommonNumConstants.NUM_ONE, CommonNumConstants.NUM_EIGHT); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + pageInfo.setObjectId(inputObject.getLogParams().get("id").toString()); + pageInfo.setState(NoticeState.UP.getKey().toString()); + List> beans = skyeyeBaseMapper.queryNoticeList(pageInfo); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + String serviceClassName = getServiceClassName(); + beans.forEach(bean -> { + bean.put("serviceClassName", serviceClassName); + }); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeUserServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeUserServiceImpl.java new file mode 100644 index 0000000..22f01b2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/NoticeUserServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.notice.dao.NoticeUserDao; +import com.skyeye.eve.notice.entity.NoticeUser; +import com.skyeye.eve.notice.service.NoticeUserService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: NoticeUserServiceImpl + * @Description: 公告群发对象管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/31 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "公告群发对象管理", groupName = "公告管理", manageShow = false) +public class NoticeUserServiceImpl extends SkyeyeBusinessServiceImpl implements NoticeUserService { + + @Override + public void deleteNoticeUserByNoticeId(String noticeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(NoticeUser::getNoticeId), noticeId); + remove(queryWrapper); + } + + @Override + public void saveNoticeUser(String noticeId, List userIdList) { + deleteNoticeUserByNoticeId(noticeId); + userIdList = userIdList.stream() + .filter(userId -> StrUtil.isNotEmpty(userId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(userIdList)) { + List noticeUserList = new ArrayList<>(); + for (String userId : userIdList) { + NoticeUser noticeUser = new NoticeUser(); + noticeUser.setUserId(userId); + noticeUser.setNoticeId(noticeId); + noticeUserList.add(noticeUser); + } + createEntity(noticeUserList, StrUtil.EMPTY); + } + } + + @Override + public List queryNoticeUserByNoticeId(String noticeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(NoticeUser::getNoticeId), noticeId); + List noticeUserList = list(queryWrapper); + return noticeUserList.stream().map(NoticeUser::getUserId).collect(Collectors.toList()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/UserMessageServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/UserMessageServiceImpl.java new file mode 100644 index 0000000..c9d24e2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/notice/service/impl/UserMessageServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.notice.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.notice.dao.UserMessageDao; +import com.skyeye.eve.notice.entity.UserMessage; +import com.skyeye.eve.notice.entity.UserMessageBox; +import com.skyeye.eve.notice.service.UserMessageService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: UserMessageServiceImpl + * @Description: 用户消息管理务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 19:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户消息管理", groupName = "内部消息模块") +public class UserMessageServiceImpl extends SkyeyeBusinessServiceImpl implements UserMessageService { + + /** + * 获取当前用户前8条未读的消息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getTopEightMessageList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(UserMessage::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(UserMessage::getState), WhetherEnum.DISABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(UserMessage::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(UserMessage::getCreateTime)); + queryWrapper.last("LIMIT 8"); + List userMessages = list(queryWrapper); + outputObject.setBeans(userMessages); + outputObject.settotal(userMessages.size()); + } + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + commonPageInfo.setObjectId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryUserMessageList(commonPageInfo); + return beans; + } + + /** + * 用户阅读消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editMessageById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + UserMessage userMessage = selectById(id); + if (ObjectUtil.isNotEmpty(userMessage)) { + if (userMessage.getState().equals(WhetherEnum.DISABLE_USING.getKey())) { + // 未读状态下的消息 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(UserMessage::getState), WhetherEnum.ENABLE_USING.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(UserMessage::getReadTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + } else { + outputObject.setreturnMessage("该消息不存在."); + } + } + + /** + * 用户删除全部消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteAllMessage(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(UserMessage::getReceiveId), userId); + updateWrapper.eq(MybatisPlusUtil.toColumns(UserMessage::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(UserMessage::getDeleteFlag), DeleteFlagEnum.DELETED.getKey()); + update(updateWrapper); + } + + /** + * 新增用户消息数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertUserMessage(InputObject inputObject, OutputObject outputObject) { + UserMessageBox userMessageBox = inputObject.getParams(UserMessageBox.class); + List userMessageList = userMessageBox.getUserNoticeMationList(); + String userId = null; + for (UserMessage userMessage : userMessageList) { + userId = userMessage.getCreateUserId(); + userMessage.setState(WhetherEnum.DISABLE_USING.getKey()); + } + createEntity(userMessageList, userId); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleImported.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleImported.java new file mode 100644 index 0000000..f28b2d0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleImported.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ScheduleImported + * @Description: 日程重要性 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 17:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ScheduleImported implements SkyeyeEnumClass { + + ORDINARY(1, "普通", true, false), + IMPORTANT(2, "重要", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ScheduleImported bean : ScheduleImported.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleRemindType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleRemindType.java new file mode 100644 index 0000000..d8100ec --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleRemindType.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ScheduleRemindType + * @Description: 日程提醒时间所属类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 17:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ScheduleRemindType implements SkyeyeEnumClass { + + NO_REMINDER(0, "无需提醒", false, false), + START(1, "日程开始时", true, true), + FIVE_MINUTE(2, "5分钟前", true, false), + FIFTEEN_MINUTE(3, "15分钟前", true, false), + THIRTY_MINUTE(4, "30分钟前", true, false), + ONE_HOUR(5, "1小时前", true, false), + TWO_HOUR(6, "2小时前", true, false), + ONE_DAY(7, "1天前", true, false), + TWO_DAY(8, "2天前", true, false), + ONE_WEEK(9, "一周前", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ScheduleRemindType bean : ScheduleRemindType.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleState.java new file mode 100644 index 0000000..8284d05 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/classenum/ScheduleState.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ScheduleState + * @Description: 日程状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 18:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ScheduleState implements SkyeyeEnumClass { + + NEW_SCHEDULE(0, "新建日程", true, false), + REMINDED_SCHEDULE(1, "已提醒结束的日程", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ScheduleState bean : ScheduleState.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/controller/ScheduleDayController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/controller/ScheduleDayController.java new file mode 100644 index 0000000..5a43f59 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/controller/ScheduleDayController.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.schedule.entity.ScheduleDay; +import com.skyeye.eve.rest.schedule.OtherModuleScheduleMation; +import com.skyeye.eve.schedule.service.ScheduleDayService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ScheduleDayController + * @Description: 日程管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 17:42 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "日程管理", tags = "日程管理", modelName = "日程管理") +public class ScheduleDayController { + + @Autowired + private ScheduleDayService scheduleDayService; + + /** + * 添加日程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertScheduleDay", value = "添加日程信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ScheduleDay.class) + @RequestMapping("/post/ScheduleDayController/insertScheduleDay") + public void insertScheduleDay(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.createEntity(inputObject, outputObject); + } + + /** + * 新增节假日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule017", value = "新增节假日", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "name", name = "name", value = "节假日标题", required = "required"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "开始时间", required = "required"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "结束时间", required = "required")}) + @RequestMapping("/post/ScheduleDayController/addSchedule") + public void addSchedule(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.addSchedule(inputObject, outputObject); + } + + /** + * 获取当前用户的日程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule002", value = "获取当前用户的日程信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "yearMonth", name = "yearMonth", value = "指定年月:YYYY-MM", required = "required"), + @ApiImplicitParam(id = "checkWorkId", name = "checkWorkId", value = "班次id", required = "required")}) + @RequestMapping("/post/ScheduleDayController/queryScheduleDayByUserId") + public void queryScheduleDayByUserId(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryList(inputObject, outputObject); + } + + /** + * 根据用户获取今日日程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule003", value = "根据用户获取今日日程信息", method = "GET", allUse = "2") + @RequestMapping("/post/ScheduleDayController/queryTodayScheduleDayByUserId") + public void queryTodayScheduleDayByUserId(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryTodayScheduleDayByUserId(inputObject, outputObject); + } + + /** + * 获取当前用户指定日期的日程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryScheduleDayByPointHms", value = "获取当前用户指定日期的日程信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "pointHms", name = "pointHms", value = "指定日期", required = "required")}) + @RequestMapping("/post/ScheduleDayController/queryScheduleDayByPointHms") + public void queryScheduleDayByPointHms(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryScheduleDayByPointHms(inputObject, outputObject); + } + + /** + * 修改日程日期信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule005", value = "修改日程日期信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "name", name = "name", value = "标题", required = "required"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "开始时间", required = "required"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "结束时间", required = "required")}) + @RequestMapping("/post/ScheduleDayController/editScheduleDayById") + public void editScheduleDayById(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.editScheduleDayById(inputObject, outputObject); + } + + /** + * 获取日程详细信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule006", value = "获取日程详细信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ScheduleDayController/queryScheduleDayById") + public void queryScheduleDayById(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.selectById(inputObject, outputObject); + } + + /** + * 删除日程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule007", value = "删除日程信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ScheduleDayController/deleteScheduleDayById") + public void deleteScheduleDayById(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.deleteById(inputObject, outputObject); + } + + /** + * 获取我的日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule019", value = "获取我的日程", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ScheduleDayController/queryMyScheduleList") + public void queryMyScheduleList(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryPageList(inputObject, outputObject); + } + + /** + * 其他模块同步到日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertScheduleMationByOtherModule", value = "其他模块同步到日程", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = OtherModuleScheduleMation.class) + @RequestMapping("/post/ScheduleDayController/insertScheduleByOtherModule") + public void insertScheduleByOtherModule(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.insertScheduleByOtherModule(inputObject, outputObject); + } + + /** + * 根据ObjectId删除日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteScheduleMationByObjectId", value = "根据ObjectId删除日程", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "日程关联ID", required = "required")}) + @RequestMapping("/post/ScheduleDayController/deleteScheduleMationByObjectId") + public void deleteScheduleMationByObjectId(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.deleteScheduleMationByObjectId(inputObject, outputObject); + } + + /** + * 判断指定日期是否是节假日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "judgeISHoliday", value = "判断指定日期是否是节假日", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "day", name = "day", value = "日期,格式为yyyy-mm-dd", required = "required")}) + @RequestMapping("/post/ScheduleDayController/judgeISHoliday") + public void judgeISHoliday(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.judgeISHoliday(inputObject, outputObject); + } + + /** + * 删除本年度节假日日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule012", value = "删除本年度节假日日程", method = "POST", allUse = "1") + @RequestMapping("/post/ScheduleDayController/deleteHolidayScheduleByThisYear") + public void deleteHolidayScheduleByThisYear(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.deleteHolidayScheduleByThisYear(inputObject, outputObject); + } + + /** + * 下载节假日导入模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule009", value = "下载节假日导入模板", method = "POST", allUse = "1") + @RequestMapping("/post/ScheduleDayController/downloadScheduleTemplate") + public void downloadScheduleTemplate(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.downloadScheduleTemplate(inputObject, outputObject); + } + + /** + * 导入节假日日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule010", value = "导入节假日日程", method = "POST", allUse = "1") + @RequestMapping("/post/ScheduleDayController/exploreScheduleTemplate") + public void exploreScheduleTemplate(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.exploreScheduleTemplate(inputObject, outputObject); + } + + /** + * 添加节假日日程提醒 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule013", value = "添加节假日日程提醒", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "节假日ID", required = "required"), + @ApiImplicitParam(id = "remindType", name = "remindType", value = "提醒时间所属类型", required = "required,num")}) + @RequestMapping("/post/ScheduleDayController/addHolidayScheduleRemind") + public void addHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.addHolidayScheduleRemind(inputObject, outputObject); + } + + /** + * 取消节假日日程提醒 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule014", value = "取消节假日日程提醒", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "节假日ID", required = "required")}) + @RequestMapping("/post/ScheduleDayController/deleteHolidayScheduleRemind") + public void deleteHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.deleteHolidayScheduleRemind(inputObject, outputObject); + } + + /** + * 获取所有节假日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "syseveschedule018", value = "获取所有节假日", method = "POST", allUse = "2") + @RequestMapping("/post/ScheduleDayController/queryHolidayScheduleListBySys") + public void queryHolidayScheduleListBySys(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryHolidayScheduleListBySys(inputObject, outputObject); + } + + /** + * 获取我的代办列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "myagency001", value = "获取我的代办列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ScheduleDayController/queryMyAgencyList") + public void queryMyAgencyList(InputObject inputObject, OutputObject outputObject) { + scheduleDayService.queryMyAgencyList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/MyAgencyDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/MyAgencyDao.java new file mode 100644 index 0000000..cdc249c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/MyAgencyDao.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.dao; + +import java.util.List; +import java.util.Map; + +public interface MyAgencyDao { + + List> queryMyAgencyList(Map map); + + int deleteMyAgencyList(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/ScheduleDayDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/ScheduleDayDao.java new file mode 100644 index 0000000..89156fa --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/dao/ScheduleDayDao.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.schedule.entity.ScheduleDay; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ScheduleDayDao + * @Description: 日程管理数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/1 11:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ScheduleDayDao extends SkyeyeBaseMapper { + + List> queryScheduleDayMationByUserId(@Param("userId") String userId, @Param("list") List months); + + Map queryIsnullThistime(@Param("startTime") String startTime, @Param("endTime") String endTime); + + List> queryScheduleList(CommonPageInfo commonPageInfo); + + List> queryAllUserAndEmailISNotNull(); + + List> queryMyAgencyList(CommonPageInfo pageInfo); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/entity/ScheduleDay.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/entity/ScheduleDay.java new file mode 100644 index 0000000..f785edb --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/entity/ScheduleDay.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ScheduleDay + * @Description: 日程实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 18:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "schedule_day") +@ApiModel("日程实体类") +public class ScheduleDay extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField(value = "remark") + @ApiModelProperty(value = "日程内容/备注") + private String remark; + + @TableField(value = "all_day", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "是否全天,参考#WhetherEnum", required = "required,num") + private Integer allDay; + + @TableField("start_time") + @ApiModelProperty(value = "开始时间,格式为:yyyy-MM-dd HH:mm:ss", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间,格式为:yyyy-MM-dd HH:mm:ss", required = "required") + private String endTime; + + @TableField(value = "remind_type") + @ApiModelProperty(value = "提醒时间所属类型,参考#ScheduleRemindType", required = "required,num") + private Integer remindType; + + @TableField("remind_time") + @Property("提醒时间,系统计算") + private String remindTime; + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "日程类型,参考#CheckDayType", required = "required,num") + private Integer type; + + @TableField(exist = false) + @Property("日程类型名称") + private String typeName; + + @TableField("state") + @Property("日程状态 0.新建日程 1.已提醒结束") + private Integer state = 0; + + @TableField(exist = false) + @Property("日程状态名称") + private String stateName; + + @TableField(value = "imported") + @ApiModelProperty(value = "日程重要性,参考#ScheduleImported", required = "required,num") + private Integer imported; + + @TableField(exist = false) + @Property("日程重要性名称") + private String importedName; + + @TableField(exist = false) + @Property("日程背景色") + private String backgroundColor; + + @TableField(value = "is_remind") + @Property("是否需要提醒,参考#WhetherEnum") + private Integer isRemind = 1; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "关联id") + private String objectId; + + @TableField(value = "object_type", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "object类型:1.任务计划id,2.项目任务id", required = "num") + private Integer objectType; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/ScheduleDayService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/ScheduleDayService.java new file mode 100644 index 0000000..b45ff4c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/ScheduleDayService.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.schedule.entity.ScheduleDay; + +/** + * @ClassName: ScheduleDayService + * @Description: 日程管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/24 17:42 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ScheduleDayService extends SkyeyeBusinessService { + + void queryTodayScheduleDayByUserId(InputObject inputObject, OutputObject outputObject); + + void editScheduleDayById(InputObject inputObject, OutputObject outputObject); + + void insertScheduleByOtherModule(InputObject inputObject, OutputObject outputObject); + + void deleteScheduleMationByObjectId(InputObject inputObject, OutputObject outputObject); + + void judgeISHoliday(InputObject inputObject, OutputObject outputObject); + + void deleteHolidayScheduleByThisYear(InputObject inputObject, OutputObject outputObject); + + void addSchedule(InputObject inputObject, OutputObject outputObject); + + /** + * 根据日程id修改日程状态 + * + * @param id 日程id + * @param state 日程状态 + * @return + */ + void editScheduleStateById(String id, Integer state); + + void downloadScheduleTemplate(InputObject inputObject, OutputObject outputObject); + + void exploreScheduleTemplate(InputObject inputObject, OutputObject outputObject); + + void addHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject); + + void deleteHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject); + + void queryHolidayScheduleListBySys(InputObject inputObject, OutputObject outputObject); + + void queryMyAgencyList(InputObject inputObject, OutputObject outputObject); + + void queryScheduleDayByPointHms(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/impl/ScheduleDayServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/impl/ScheduleDayServiceImpl.java new file mode 100644 index 0000000..58acef3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/schedule/service/impl/ScheduleDayServiceImpl.java @@ -0,0 +1,552 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.schedule.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DateAfterSpacePointTime; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ExcelUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.schedule.classenum.ScheduleImported; +import com.skyeye.eve.schedule.classenum.ScheduleRemindType; +import com.skyeye.eve.schedule.classenum.ScheduleState; +import com.skyeye.eve.schedule.dao.ScheduleDayDao; +import com.skyeye.eve.schedule.entity.ScheduleDay; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.rest.schedule.OtherModuleScheduleMation; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.eve.schedule.service.ScheduleDayService; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.checkwork.CheckWorkService; +import com.skyeye.rest.checkwork.entity.DayWorkMationRest; +import com.skyeye.rest.checkwork.entity.UserOtherDayMationRest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import java.io.IOException; +import java.util.*; + +/** + * @ClassName: ScheduleDayServiceImpl + * @Description: 日程管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/24 11:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "日程管理", groupName = "日程管理") +public class ScheduleDayServiceImpl extends SkyeyeBusinessServiceImpl implements ScheduleDayService { + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private CheckWorkService checkWorkService; + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void addSchedule(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String startTime = map.get("startTime").toString(); + String name = map.get("name").toString(); + String endTime = map.get("endTime").toString(); + + Map m = skyeyeBaseMapper.queryIsnullThistime(startTime, endTime); + if (CollectionUtil.isNotEmpty(m)) { + outputObject.setreturnMessage("该节假日时间段与已有的节假日时间段有冲突,请重新设置节假日"); + } else { + ScheduleDay scheduleDay = new ScheduleDay(); + scheduleDay.setName(name); + scheduleDay.setStartTime(startTime); + scheduleDay.setEndTime(endTime); + scheduleDay.setIsRemind(WhetherEnum.DISABLE_USING.getKey()); + // 是否全天 + scheduleDay.setAllDay(WhetherEnum.ENABLE_USING.getKey()); + // 日程类型 + scheduleDay.setType(CheckDayType.DAY_IS_HOLIDAY.getKey()); + // 提醒时间所属类型 + scheduleDay.setRemindType(ScheduleRemindType.NO_REMINDER.getKey()); + scheduleDay.setState(ScheduleState.NEW_SCHEDULE.getKey()); + scheduleDay.setImported(ScheduleImported.ORDINARY.getKey()); + createEntity(scheduleDay, inputObject.getLogParams().get("id").toString()); + } + } + + @Override + public void createPrepose(ScheduleDay entity) { + String scheduleStartTime = entity.getStartTime(); + String remindTime = DateAfterSpacePointTime.getSpecifiedTime(entity.getRemindType(), scheduleStartTime, + DateUtil.YYYY_MM_DD_HH_MM_SS, DateAfterSpacePointTime.AroundType.BEFORE); + if (StrUtil.isNotBlank(remindTime)) { + if (DateUtil.compare(remindTime, DateUtil.getTimeAndToString())) { + // 日程提醒时间早于当前时间 + throw new CustomException("日程提醒时间不能早于当前时间"); + } else { + if (DateUtil.compare(entity.getEndTime(), scheduleStartTime)) { + // 结束时间早于开始时间 + throw new CustomException("日程结束时间不能早于开始时间"); + } else { + entity.setRemindTime(remindTime); + } + } + } + } + + @Override + public void createPostpose(ScheduleDay entity, String userId) { + if (StrUtil.isNotEmpty(entity.getRemindTime())) { + // 定时任务 + startUpTaskQuartz(entity.getId(), entity.getName(), entity.getRemindTime()); + } + } + + private void startUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.MY_SCHEDULEDAY_MATION.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + @Override + public List> queryDataList(InputObject inputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + String yearMonth = map.get("yearMonth").toString(); + String timeId = map.get("checkWorkId").toString(); + List months = DateUtil.getPointMonthAfterMonthList(yearMonth, 2); + // 1.获取当前登录人指定月份的日程信息 + List> beans = skyeyeBaseMapper.queryScheduleDayMationByUserId(userId, months); + beans.forEach(bean -> { + bean.put("backgroundColor", CheckDayType.getColor(Integer.parseInt(bean.get("type").toString()))); + }); + DayWorkMationRest dayWorkMationParams = new DayWorkMationRest(); + dayWorkMationParams.setBeans(beans); + dayWorkMationParams.setMonths(months); + dayWorkMationParams.setTimeId(timeId); + beans = ExecuteFeignClient.get(() -> checkWorkService.queryDayWorkMation(dayWorkMationParams)).getRows(); + // 2.获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + UserOtherDayMationRest userOtherDayMationParams = new UserOtherDayMationRest(); + userOtherDayMationParams.setTimeId(timeId); + userOtherDayMationParams.setUserId(userId); + userOtherDayMationParams.setMonths(months); + beans.addAll(ExecuteFeignClient.get(() -> checkWorkService.getUserOtherDayMation(userOtherDayMationParams)).getRows()); + return beans; + } + + @Override + public void queryTodayScheduleDayByUserId(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + List scheduleDayList = getScheduleDayList(userId, DateUtil.getTimeIsYMD()); + outputObject.setBeans(scheduleDayList); + outputObject.settotal(scheduleDayList.size()); + } + + private List getScheduleDayList(String userId, String timeHms) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("date_format(" + MybatisPlusUtil.toColumns(ScheduleDay::getStartTime) + ", '%Y-%m-%d') <= date_format({0}, '%Y-%m-%d')", timeHms) + .apply("date_format(" + MybatisPlusUtil.toColumns(ScheduleDay::getEndTime) + ", '%Y-%m-%d') >= date_format({0}, '%Y-%m-%d')", timeHms); + queryWrapper.ne(MybatisPlusUtil.toColumns(ScheduleDay::getType), CheckDayType.DAY_IS_HOLIDAY.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ScheduleDay::getCreateId), userId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(ScheduleDay::getStartTime)); + List list = list(queryWrapper); + list.forEach(bean -> { + bean.setImportedName(ScheduleImported.getName(bean.getImported())); + bean.setBackgroundColor(CheckDayType.getColor(bean.getType())); + }); + return list; + } + + @Override + public void queryScheduleDayByPointHms(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + String pointHms = inputObject.getParams().get("pointHms").toString(); + List scheduleDayList = getScheduleDayList(userId, pointHms); + outputObject.setBeans(scheduleDayList); + outputObject.settotal(scheduleDayList.size()); + } + + /** + * 修改日程日期信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editScheduleDayById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + ScheduleDay scheduleDay = selectById(id); + int remindTimeType = scheduleDay.getRemindType(); + String startTime = map.get("startTime").toString(); + String endTime = map.get("endTime").toString(); + String remindTime = DateAfterSpacePointTime.getSpecifiedTime(remindTimeType, startTime, DateUtil.YYYY_MM_DD_HH_MM_SS, DateAfterSpacePointTime.AroundType.BEFORE); + if (StrUtil.isNotBlank(remindTime)) { + if (DateUtil.compare(remindTime, DateUtil.getTimeAndToString())) { + // 日程提醒时间早于当前时间,提醒时间则变为当前时间+2分钟;获取当前时间和开始时间相差几分钟 + long minute = DateUtil.getDistanceMinute(remindTime, startTime); + if (minute >= 2) { + // 两分钟后 + remindTime = DateAfterSpacePointTime.getSpecifiedTime(remindTimeType, DateUtil.getTimeAndToString(), + DateUtil.YYYY_MM_DD_HH_MM_SS, DateAfterSpacePointTime.AroundType.AFTER, 2); + } else if (minute < 2 && minute > 0) { + // minute分钟后 + remindTime = DateAfterSpacePointTime.getSpecifiedTime(remindTimeType, DateUtil.getTimeAndToString(), + DateUtil.YYYY_MM_DD_HH_MM_SS, DateAfterSpacePointTime.AroundType.AFTER, (int) minute); + } else { + // 日程开始时 + remindTime = startTime; + } + } else if (DateUtil.compare(endTime, startTime)) { + // 结束时间早于开始时间 + outputObject.setreturnMessage("日程结束时间不能早于开始时间"); + return; + } + // 修改定时任务 + startUpTaskQuartz(id, map.get("name").toString(), remindTime); + } + String userId = inputObject.getLogParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getStartTime), startTime); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getEndTime), endTime); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getRemindTime), remindTime); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + @Override + public ScheduleDay selectById(String id) { + ScheduleDay scheduleDay = super.selectById(id); + scheduleDay.setImportedName(ScheduleImported.getName(scheduleDay.getImported())); + scheduleDay.setStateName(ScheduleState.getName(scheduleDay.getState())); + scheduleDay.setTypeName(CheckDayType.getName(scheduleDay.getType())); + return scheduleDay; + } + + @Override + public void deletePostpose(String id) { + // 删除定时任务 + iQuartzService.stopAndDeleteTaskQuartz(id); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (StrUtil.isNotEmpty(commonPageInfo.getType()) && commonPageInfo.getType().equals(CheckDayType.DAY_IS_HOLIDAY.getKey().toString())) { + } else { + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + } + List> beans = skyeyeBaseMapper.queryScheduleList(commonPageInfo); + for (Map str : beans) { //遍历数组 + boolean before = DateUtil.compare(DateUtil.getTimeAndToString(), str.get("startTime").toString()); + if (before) { //当前时间 在 节假日开始时间 之前 + str.put("before", "1"); + } else { + str.put("before", "2"); + } + } + return beans; + } + + /** + * 其他模块同步到日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertScheduleByOtherModule(InputObject inputObject, OutputObject outputObject) { + OtherModuleScheduleMation scheduleMationParams = inputObject.getParams(OtherModuleScheduleMation.class); + ScheduleDay scheduleDay = new ScheduleDay(); + scheduleDay.setName(scheduleMationParams.getTitle()); + int length = scheduleMationParams.getContent().length(); + scheduleDay.setRemark(length > 1000 ? scheduleMationParams.getContent().substring(0, 1000) : scheduleMationParams.getContent()); + scheduleDay.setStartTime(scheduleMationParams.getStartTime()); + scheduleDay.setEndTime(scheduleMationParams.getEndTime()); + scheduleDay.setIsRemind(WhetherEnum.ENABLE_USING.getKey()); + // 是否全天 + scheduleDay.setAllDay(WhetherEnum.ENABLE_USING.getKey()); + // 日程类型 + scheduleDay.setType(CheckDayType.DAY_IS_WORK.getKey()); + // 提醒时间所属类型 + scheduleDay.setRemindType(ScheduleRemindType.NO_REMINDER.getKey()); + scheduleDay.setImported(ScheduleImported.ORDINARY.getKey()); + scheduleDay.setObjectId(scheduleMationParams.getObjectId()); + scheduleDay.setObjectType(scheduleMationParams.getObjectType()); + createEntity(scheduleDay, scheduleMationParams.getUserId()); + } + + /** + * 根据ObjectId删除日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteScheduleMationByObjectId(InputObject inputObject, OutputObject outputObject) { + String objectId = inputObject.getParams().get("objectId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ScheduleDay::getObjectId), objectId); + remove(queryWrapper); + } + + /** + * 判断指定日期是否是节假日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void judgeISHoliday(InputObject inputObject, OutputObject outputObject) { + String day = inputObject.getParams().get("day").toString(); + Map result = new HashMap<>(); + result.put("result", this.judgeISHoliday(day)); + outputObject.setBean(result); + outputObject.settotal(1); + } + + /** + * 判断指定日期是否是节假日 + * + * @param day 日期,格式为yyyy-mm-dd + * @return true:是节假日;false:不是节假日 + */ + private boolean judgeISHoliday(String day) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("date_format(" + MybatisPlusUtil.toColumns(ScheduleDay::getStartTime) + ", '%Y-%m-%d') <= date_format({0}, '%Y-%m-%d')", day) + .apply("date_format(" + MybatisPlusUtil.toColumns(ScheduleDay::getEndTime) + ", '%Y-%m-%d') >= date_format({0}, '%Y-%m-%d')", day); + queryWrapper.eq(MybatisPlusUtil.toColumns(ScheduleDay::getType), CheckDayType.DAY_IS_HOLIDAY.getKey()); + List scheduleDays = list(queryWrapper); + if (CollectionUtil.isEmpty(scheduleDays)) { + return false; + } + return true; + } + + @Override + public void deleteHolidayScheduleByThisYear(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("YEAR(" + MybatisPlusUtil.toColumns(ScheduleDay::getStartTime) + ") = YEAR(NOW())"); + queryWrapper.eq(MybatisPlusUtil.toColumns(ScheduleDay::getType), CheckDayType.DAY_IS_HOLIDAY.getKey()); + List scheduleDays = list(queryWrapper); + scheduleDays.forEach(scheduleDay -> { + // 删除定时任务 + iQuartzService.stopAndDeleteTaskQuartz(scheduleDay.getId()); + }); + remove(queryWrapper); + } + + @Override + public void editScheduleStateById(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getState), state); + update(updateWrapper); + } + + /** + * 下载节假日导入模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void downloadScheduleTemplate(InputObject inputObject, OutputObject outputObject) { + String[] key = new String[9]; + String[] column = new String[]{"标题", "开始日期", "结束日期"}; + String[] dataType = new String[]{"", "data", "data"}; + ExcelUtil.createWorkBook("节假日模板", "节假日", null, key, column, dataType, PutObject.getResponse()); + } + + /** + * 导入节假日日程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void exploreScheduleTemplate(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器) + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(PutObject.getRequest().getSession().getServletContext()); + // 检查form中是否有enctype="multipart/form-data" + if (multipartResolver.isMultipart(PutObject.getRequest())) { + // 将request变成多部分request + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) PutObject.getRequest(); + // 获取multiRequest 中所有的文件名 + Iterator iter = multiRequest.getFileNames(); + //循环内使用参数 + MultipartFile file;//获取到文件 + List> list;//excel读取到的数据 + String nowTime = DateUtil.getTimeAndToString();//当前时间 + List row;//获取每一行的数据 + while (iter.hasNext()) { + // 一次遍历所有文件 + file = multiRequest.getFile(iter.next().toString()); + try { + list = ExcelUtil.readExcelContent(file.getInputStream()); + } catch (IOException e) { + throw new CustomException(e); + } + List beans = new ArrayList<>(); + for (int i = 0, j = list.size(); i < j; i++) { + row = list.get(i); + if (!ToolUtil.isBlank(row.get(1).toString()) && !ToolUtil.isBlank(row.get(1).toString())) { + String startTime = row.get(1).toString() + " 00:00:00";//日程开始时间 + String endTime = row.get(2).toString() + " 23:59:59";//日程结束时间 + ScheduleDay scheduleDay = new ScheduleDay(); + scheduleDay.setStartTime(startTime); + scheduleDay.setEndTime(endTime); + scheduleDay.setIsRemind(WhetherEnum.DISABLE_USING.getKey()); + // 是否全天 + scheduleDay.setAllDay(WhetherEnum.ENABLE_USING.getKey()); + // 日程类型 + scheduleDay.setType(CheckDayType.DAY_IS_HOLIDAY.getKey()); + // 提醒时间所属类型 + scheduleDay.setRemindType(ScheduleRemindType.NO_REMINDER.getKey()); + scheduleDay.setImported(ScheduleImported.ORDINARY.getKey()); + if (DateUtil.compare(startTime, nowTime)) {//日程开始时间早于当前时间 + scheduleDay.setState(ScheduleState.REMINDED_SCHEDULE.getKey());//已结束 + } else { + scheduleDay.setState(ScheduleState.NEW_SCHEDULE.getKey());//新日程 + } + if (ToolUtil.isBlank(row.get(0).toString())) { + scheduleDay.setName("休息日"); + } else { + scheduleDay.setName(row.get(0)); + } + beans.add(scheduleDay); + } + } + createEntity(beans, user.get("id").toString()); + map.put("uploadNum", beans.size()); + outputObject.setBean(map); + } + } + } + + /** + * 添加节假日日程提醒 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void addHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + ScheduleDay scheduleDay = selectById(id); + int remindType = Integer.parseInt(map.get("remindType").toString()); + String scheduleStartTime = map.get("scheduleStartTime").toString(); + String remindTime = DateAfterSpacePointTime.getSpecifiedTime(remindType, scheduleStartTime, DateUtil.YYYY_MM_DD_HH_MM_SS, DateAfterSpacePointTime.AroundType.BEFORE); + if (StrUtil.isNotEmpty(remindTime)) { + if (DateUtil.compare(remindTime, DateUtil.getTimeAndToString())) { + // 日程提醒时间早于当前时间 + outputObject.setreturnMessage("日程提醒时间不能早于当前时间"); + } else { + if (DateUtil.compare(scheduleDay.getEndTime(), scheduleStartTime)) { + // 结束时间早于开始时间 + outputObject.setreturnMessage("日程结束时间不能早于开始时间"); + } else { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getRemindType), remindType); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getIsRemind), WhetherEnum.ENABLE_USING.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getRemindTime), remindTime); + update(updateWrapper); + // 定时任务 + startAllUpTaskQuartz(map.get("id").toString(), scheduleDay.getName(), remindTime); + } + } + } else { + outputObject.setreturnMessage("参数错误"); + } + } + + private void startAllUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.ALL_SCHEDULE_MATION.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + /** + * 取消节假日日程提醒 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteHolidayScheduleRemind(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 修改节假日信息 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getRemindType), ScheduleRemindType.NO_REMINDER.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(ScheduleDay::getIsRemind), WhetherEnum.DISABLE_USING.getKey()); + update(updateWrapper); + // 删除定时任务 + iQuartzService.stopAndDeleteTaskQuartz(id); + } + + /** + * 获取所有节假日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryHolidayScheduleListBySys(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ScheduleDay::getType), CheckDayType.DAY_IS_HOLIDAY.getKey()); + List scheduleDays = list(queryWrapper); + outputObject.setBeans(scheduleDays); + outputObject.settotal(scheduleDays.size()); + } + + @Override + public void queryMyAgencyList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryMyAgencyList(pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/classenum/SealBgColorType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/classenum/SealBgColorType.java new file mode 100644 index 0000000..aa09852 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/classenum/SealBgColorType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SealBgColorType + * @Description: 印章背景类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/23 22:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SealBgColorType implements SkyeyeEnumClass { + + WHITE_BACKGROUND(1, "白色背景", true, true), + TRANSPARENT_BACKGROUND(2, "透明背景", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyBorrowController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyBorrowController.java new file mode 100644 index 0000000..1de8bef --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyBorrowController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.seal.entity.SealUse; +import com.skyeye.eve.seal.service.SealApplyBorrowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealApplyBorrowController + * @Description: 印章借用申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "印章借用", tags = "印章借用", modelName = "印章模块") +public class SealApplyBorrowController { + + @Autowired + private SealApplyBorrowService sealApplyBorrowService; + + /** + * 获取我发起的印章借用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealborrow001", value = "获取我发起的印章借用列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealApplyBorrowController/querySealUseList") + public void querySealUseList(InputObject inputObject, OutputObject outputObject) { + sealApplyBorrowService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑印章借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealUse", value = "新增/编辑印章借用申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SealUse.class) + @RequestMapping("/post/SealApplyBorrowController/writeSealUse") + public void writeSealUse(InputObject inputObject, OutputObject outputObject) { + sealApplyBorrowService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 印章借用申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealborrow006", value = "印章借用申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/SealApplyBorrowController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + sealApplyBorrowService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废印章借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealborrow007", value = "作废印章借用申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealApplyBorrowController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + sealApplyBorrowService.invalid(inputObject, outputObject); + } + + /** + * 撤销印章借用申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealborrow010", value = "撤销印章借用申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/SealApplyBorrowController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + sealApplyBorrowService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyRevertController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyRevertController.java new file mode 100644 index 0000000..f6f1982 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealApplyRevertController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.seal.entity.SealRevert; +import com.skyeye.eve.seal.service.SealApplyRevertService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealApplyRevertController + * @Description: 印章归还申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 17:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "印章归还", tags = "印章归还", modelName = "印章模块") +public class SealApplyRevertController { + + @Autowired + private SealApplyRevertService sealApplyRevertService; + + /** + * 获取我发起的印章归还列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealrevert001", value = "获取我发起的印章归还列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealApplyRevertController/querySealRevertList") + public void querySealRevertList(InputObject inputObject, OutputObject outputObject) { + sealApplyRevertService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑印章归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealRevert", value = "新增/编辑印章归还申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SealRevert.class) + @RequestMapping("/post/SealApplyRevertController/writeSealRevert") + public void writeSealRevert(InputObject inputObject, OutputObject outputObject) { + sealApplyRevertService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 印章归还申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealrevert006", value = "印章归还申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/SealApplyRevertController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + sealApplyRevertService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废印章归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealrevert007", value = "作废印章归还申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealApplyRevertController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + sealApplyRevertService.invalid(inputObject, outputObject); + } + + /** + * 撤销印章归还申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealrevert010", value = "撤销印章归还申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/SealApplyRevertController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + sealApplyRevertService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealController.java new file mode 100644 index 0000000..4e774d4 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/controller/SealController.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.seal.entity.Seal; +import com.skyeye.eve.seal.service.SealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealController + * @Description: 印章管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 19:33 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "印章管理", tags = "印章管理", modelName = "印章模块") +public class SealController { + + @Autowired + private SealService sealService; + + /** + * 查询所有的印章 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "seal001", value = "查询所有的印章", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealController/querySealList") + public void querySealList(InputObject inputObject, OutputObject outputObject) { + sealService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSeal", value = "新增/修改印章信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Seal.class) + @RequestMapping("/post/SealController/writeSeal") + public void writeSeal(InputObject inputObject, OutputObject outputObject) { + sealService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "seal003", value = "根据id删除印章信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealController/deleteSealById") + public void deleteSealById(InputObject inputObject, OutputObject outputObject) { + sealService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启用的印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "seal007", value = "获取所有启用的印章信息", method = "GET", allUse = "2") + @RequestMapping("/post/SealController/queryAllEnabledSealList") + public void queryAllEnabledSealList(InputObject inputObject, OutputObject outputObject) { + sealService.queryAllEnabledSealList(inputObject, outputObject); + } + + /** + * 获取我借用中的所有印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealrevert008", value = "获取我借用中的所有印章信息", method = "GET", allUse = "2") + @RequestMapping("/post/SealController/queryMyRevertSealList") + public void queryMyRevertSealList(InputObject inputObject, OutputObject outputObject) { + sealService.queryMyRevertSealList(inputObject, outputObject); + } + + /** + * 获取我借用中的印章列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyRevertSealPageList", value = "获取我借用中的印章列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealController/queryMyRevertSealPageList") + public void queryMyRevertSealPageList(InputObject inputObject, OutputObject outputObject) { + sealService.queryMyRevertSealPageList(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyBorrowDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyBorrowDao.java new file mode 100644 index 0000000..6bd679d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyBorrowDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.seal.entity.SealUse; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealApplyBorrowDao + * @Description: 印章借用数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyBorrowDao extends SkyeyeBaseMapper { + + List> querySealUseList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyRevertDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyRevertDao.java new file mode 100644 index 0000000..a35bdfd --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealApplyRevertDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.seal.entity.SealRevert; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealApplyRevertDao + * @Description: 印章归还申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 17:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyRevertDao extends SkyeyeBaseMapper { + + List> querySealRevertList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealDao.java new file mode 100644 index 0000000..13ae7f1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.seal.entity.Seal; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealDao + * @Description: 印章管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 16:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealDao extends SkyeyeBaseMapper { + + List> querySealList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealRevertLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealRevertLinkDao.java new file mode 100644 index 0000000..ba06834 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealRevertLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.seal.entity.SealRevertLink; + +/** + * @ClassName: SealRevertLinkDao + * @Description: 印章归还申请关联的印章信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealRevertLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealUseLinkDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealUseLinkDao.java new file mode 100644 index 0000000..e855701 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/dao/SealUseLinkDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.seal.entity.SealUseLink; + +/** + * @ClassName: SealUseLinkDao + * @Description: 印章借用申请关联的印章信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealUseLinkDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/Seal.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/Seal.java new file mode 100644 index 0000000..2217258 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/Seal.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Seal + * @Description: 印章实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/6 9:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "assistant:seal", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "seal") +@ApiModel("印章实体类") +public class Seal extends BaseGeneralInfo { + + @TableField(value = "company_name") + @ApiModelProperty(value = "公司名称", required = "required") + private String companyName; + + @TableField(value = "enable_time") + @ApiModelProperty(value = "启用日期", required = "required") + private String enableTime; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "num", defaultValue = "1") + private Integer enabled; + + @TableField(value = "bg_color_type") + @ApiModelProperty(value = "背景类型,参考#SealBgColorType", required = "required,num") + private Integer bgColorType; + + @TableField(value = "logo") + @ApiModelProperty(value = "logo图片") + private String logo; + + @TableField(value = "seal_admin") + @ApiModelProperty(value = "管理人id") + private String sealAdmin; + + @TableField(exist = false) + @Property(value = "管理人") + private Map sealAdminMation; + + @TableField(value = "borrow_id") + @Property(value = "借用人id") + private String borrowId; + + @TableField(exist = false) + @Property(value = "借用人") + private Map borrowMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevert.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevert.java new file mode 100644 index 0000000..6a148c9 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevert.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SealRevert + * @Description: 印章归还申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:seal:revert", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "seal_revert") +@ApiModel("印章归还申请实体类") +public class SealRevert extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "印章信息", required = "required,json") + private List revertLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevertLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevertLink.java new file mode 100644 index 0000000..f0c6e76 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealRevertLink.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: SealRevertLink + * @Description: 印章归还申请关联的印章信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "seal_revert_goods") +@ApiModel("印章归还申请关联的印章信息实体类") +public class SealRevertLink extends SkyeyeLinkData { + + @TableField("seal_id") + @ApiModelProperty(value = "印章id", required = "required") + private String sealId; + + @TableField(exist = false) + @Property("印章信息") + private Seal sealMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUse.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUse.java new file mode 100644 index 0000000..4c0c0c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUse.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SealUse + * @Description: 印章借用申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:seal:use", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "seal_use") +@ApiModel("印章借用申请实体类") +public class SealUse extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "印章信息", required = "required,json") + private List useLinks; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUseLink.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUseLink.java new file mode 100644 index 0000000..18231c8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/entity/SealUseLink.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: SealUseLink + * @Description: 印章借用申请关联的印章信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "seal_use_goods") +@ApiModel("印章借用申请关联的印章信息实体类") +public class SealUseLink extends SkyeyeLinkData { + + @TableField("seal_id") + @ApiModelProperty(value = "印章id", required = "required") + private String sealId; + + @TableField(exist = false) + @Property("印章信息") + private Seal sealMation; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyBorrowService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyBorrowService.java new file mode 100644 index 0000000..70dccef --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyBorrowService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.seal.entity.SealUse; + +/** + * @ClassName: SealApplyBorrowService + * @Description: 印章借用服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyBorrowService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyRevertService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyRevertService.java new file mode 100644 index 0000000..2feb1c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealApplyRevertService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.seal.entity.SealRevert; + +/** + * @ClassName: SealApplyRevertService + * @Description: 印章归还申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 17:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyRevertService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealRevertLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealRevertLinkService.java new file mode 100644 index 0000000..9a05c54 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealRevertLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.seal.entity.SealRevertLink; + +/** + * @ClassName: SealRevertLinkService + * @Description: 印章归还申请关联的印章信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealRevertLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealService.java new file mode 100644 index 0000000..d7a7eb1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealService.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.seal.entity.Seal; + +/** + * @ClassName: SealService + * @Description: 印章管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 16:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealService extends SkyeyeBusinessService { + + void queryAllEnabledSealList(InputObject inputObject, OutputObject outputObject); + + void queryMyRevertSealList(InputObject inputObject, OutputObject outputObject); + + /** + * 设置印章领用信息 + * + * @param id 印章id + * @param useUserId 领用人id + */ + void setSealUse(String id, String useUserId); + + /** + * 设置印章归还信息 + * + * @param id 印章id + */ + void setSealRevert(String id); + + void queryMyRevertSealPageList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealUseLinkService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealUseLinkService.java new file mode 100644 index 0000000..cfd13c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/SealUseLinkService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.eve.seal.entity.SealUseLink; + +/** + * @ClassName: SealUseLinkService + * @Description: 印章借用申请关联的印章信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealUseLinkService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyBorrowServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyBorrowServiceImpl.java new file mode 100644 index 0000000..1d1dd4d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyBorrowServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.seal.dao.SealApplyBorrowDao; +import com.skyeye.eve.seal.entity.SealUse; +import com.skyeye.eve.seal.entity.SealUseLink; +import com.skyeye.eve.seal.service.SealApplyBorrowService; +import com.skyeye.eve.seal.service.SealService; +import com.skyeye.eve.seal.service.SealUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealApplyBorrowServiceImpl + * @Description: 印章借用服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "印章借用", groupName = "印章模块", flowable = true) +public class SealApplyBorrowServiceImpl extends SkyeyeFlowableServiceImpl implements SealApplyBorrowService { + + @Autowired + private SealService sealService; + + @Autowired + private SealUseLinkService sealUseLinkService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.querySealUseList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(SealUse entity) { + chectOrderItem(entity.getUseLinks()); + } + + @Override + public void writeChild(SealUse entity, String userId) { + sealUseLinkService.saveLinkList(entity.getId(), entity.getUseLinks()); + super.writeChild(entity, userId); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + sealUseLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + private void chectOrderItem(List useLinks) { + if (CollectionUtil.isEmpty(useLinks)) { + throw new CustomException("请最少选择一条印章信息"); + } + List sealIds = useLinks.stream().map(SealUseLink::getSealId).distinct() + .collect(Collectors.toList()); + if (useLinks.size() != sealIds.size()) { + throw new CustomException("单据中不允许出现同一印章信息"); + } + } + + @Override + public SealUse getDataFromDb(String id) { + SealUse sealUse = super.getDataFromDb(id); + List sealUseLinks = sealUseLinkService.selectByPId(sealUse.getId()); + sealUse.setUseLinks(sealUseLinks); + return sealUse; + } + + @Override + public SealUse selectById(String id) { + SealUse sealUse = super.selectById(id); + // 获取印章信息 + sealService.setDataMation(sealUse.getUseLinks(), SealUseLink::getSealId); + sealUse.getUseLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + sealUse.setStateName(FlowableStateEnum.getStateName(sealUse.getState())); + iAuthUserService.setName(sealUse, "createId", "createName"); + return sealUse; + } + + @Override + public void revokePostpose(SealUse entity) { + super.revokePostpose(entity); + sealUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(SealUse entity) { + SealUse sealUse = selectById(entity.getId()); + for (SealUseLink bean : sealUse.getUseLinks()) { + if (StrUtil.isEmpty(bean.getSealMation().getBorrowId())) { + // 可以借用,给印章表中对应印章填上借用人 + sealService.setSealUse(bean.getSealId(), sealUse.getCreateId()); + sealUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } else { + sealUseLinkService.editStateById(bean.getId(), FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + } + } + + @Override + public void approvalEndIsFailed(SealUse entity) { + sealUseLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyRevertServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyRevertServiceImpl.java new file mode 100644 index 0000000..70c6f1f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealApplyRevertServiceImpl.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.seal.dao.SealApplyRevertDao; +import com.skyeye.eve.seal.entity.SealRevert; +import com.skyeye.eve.seal.entity.SealRevertLink; +import com.skyeye.eve.seal.service.SealApplyRevertService; +import com.skyeye.eve.seal.service.SealRevertLinkService; +import com.skyeye.eve.seal.service.SealService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealApplyRevertServiceImpl + * @Description: 印章归还申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 17:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "印章归还", groupName = "印章模块", flowable = true) +public class SealApplyRevertServiceImpl extends SkyeyeFlowableServiceImpl implements SealApplyRevertService { + + @Autowired + private SealService sealService; + + @Autowired + private SealRevertLinkService sealRevertLinkService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.querySealRevertList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(SealRevert entity) { + chectOrderItem(entity.getRevertLinks()); + } + + @Override + public void writeChild(SealRevert entity, String userId) { + sealRevertLinkService.saveLinkList(entity.getId(), entity.getRevertLinks()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List revertLinks) { + if (CollectionUtil.isEmpty(revertLinks)) { + throw new CustomException("请最少选择一条印章信息"); + } + List sealIds = revertLinks.stream().map(SealRevertLink::getSealId).distinct() + .collect(Collectors.toList()); + if (revertLinks.size() != sealIds.size()) { + throw new CustomException("单据中不允许出现同一印章信息"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + sealRevertLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public SealRevert getDataFromDb(String id) { + SealRevert sealRevert = super.getDataFromDb(id); + List sealRevertLinks = sealRevertLinkService.selectByPId(sealRevert.getId()); + sealRevert.setRevertLinks(sealRevertLinks); + return sealRevert; + } + + @Override + public SealRevert selectById(String id) { + SealRevert sealRevert = super.selectById(id); + // 获取印章信息 + sealService.setDataMation(sealRevert.getRevertLinks(), SealRevertLink::getSealId); + sealRevert.getRevertLinks().forEach(bean -> { + bean.setStateName(FlowableChildStateEnum.getStateName(bean.getState())); + }); + sealRevert.setStateName(FlowableStateEnum.getStateName(sealRevert.getState())); + iAuthUserService.setName(sealRevert, "createId", "createName"); + return sealRevert; + } + + @Override + public void revokePostpose(SealRevert entity) { + super.revokePostpose(entity); + sealRevertLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(SealRevert entity) { + SealRevert sealRevert = selectById(entity.getId()); + for (SealRevertLink bean : sealRevert.getRevertLinks()) { + sealService.setSealRevert(bean.getSealId()); + } + sealRevertLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + public void approvalEndIsFailed(SealRevert entity) { + sealRevertLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealRevertLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealRevertLinkServiceImpl.java new file mode 100644 index 0000000..1e83684 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealRevertLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.seal.dao.SealRevertLinkDao; +import com.skyeye.eve.seal.entity.Seal; +import com.skyeye.eve.seal.entity.SealRevertLink; +import com.skyeye.eve.seal.service.SealRevertLinkService; +import com.skyeye.eve.seal.service.SealService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealRevertLinkServiceImpl + * @Description: 印章归还申请关联的印章信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "印章归还申请-印章Link", groupName = "印章模块", manageShow = false) +public class SealRevertLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements SealRevertLinkService { + + @Autowired + private SealService sealService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("印章信息不能为空."); + } + List sealIds = beans.stream().map(SealRevertLink::getSealId).distinct().collect(Collectors.toList()); + Map sealMap = sealService.selectMapByIds(sealIds); + beans.forEach(sealRevertLink -> { + Seal seal = sealMap.get(sealRevertLink.getSealId()); + if (seal == null) { + throw new CustomException("数据中包含不存在的印章信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealServiceImpl.java new file mode 100644 index 0000000..fc87390 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealServiceImpl.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service.impl; + +import com.alibaba.csp.sentinel.util.StringUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.seal.dao.SealDao; +import com.skyeye.eve.seal.entity.Seal; +import com.skyeye.eve.seal.service.SealService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealServiceImpl + * @Description: 印章管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "印章管理", groupName = "印章模块") +public class SealServiceImpl extends SkyeyeBusinessServiceImpl implements SealService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySealList(pageInfo); + iAuthUserService.setMationForMap(beans, "sealAdmin", "sealAdminMation"); + iAuthUserService.setMationForMap(beans, "borrowId", "borrowMation"); + return beans; + } + + @Override + public Seal selectById(String id) { + Seal seal = super.selectById(id); + seal.setSealAdminMation(iAuthUserService.queryDataMationById(seal.getSealAdmin())); + seal.setBorrowMation(iAuthUserService.queryDataMationById(seal.getBorrowId())); + return seal; + } + + @Override + public List selectByIds(String... ids) { + List sealList = super.selectByIds(ids); + iAuthUserService.setDataMation(sealList, Seal::getSealAdmin); + iAuthUserService.setDataMation(sealList, Seal::getBorrowId); + return sealList; + } + + /** + * 获取所有启用的印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllEnabledSealList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Seal::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Seal::getCreateTime)); + List sealList = list(queryWrapper); + outputObject.setBeans(sealList); + outputObject.settotal(sealList.size()); + } + + /** + * 获取我借用中的所有印章信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyRevertSealList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Seal::getBorrowId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Seal::getCreateTime)); + List sealList = list(queryWrapper); + + outputObject.setBeans(sealList); + outputObject.settotal(sealList.size()); + } + + /** + * 设置印章领用信息 + * + * @param id 印章id + * @param useUserId 领用人id + */ + @Override + public void setSealUse(String id, String useUserId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + Seal seal = new Seal(); + seal.setBorrowId(useUserId); + update(seal, updateWrapper); + refreshCache(id); + } + + /** + * 设置印章归还信息 + * + * @param id 印章id + */ + @Override + public void setSealRevert(String id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + Seal seal = new Seal(); + seal.setBorrowId(StringUtil.EMPTY); + update(seal, updateWrapper); + refreshCache(id); + } + + /** + * 获取我借用中的印章列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyRevertSealPageList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setChargePersonId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.querySealList(pageInfo); + iAuthUserService.setMationForMap(beans, "sealAdmin", "sealAdminMation"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealUseLinkServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealUseLinkServiceImpl.java new file mode 100644 index 0000000..f6c3c14 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/seal/service/impl/SealUseLinkServiceImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.eve.seal.dao.SealUseLinkDao; +import com.skyeye.eve.seal.entity.Seal; +import com.skyeye.eve.seal.entity.SealUseLink; +import com.skyeye.eve.seal.service.SealService; +import com.skyeye.eve.seal.service.SealUseLinkService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealUseLinkServiceImpl + * @Description: 印章借用申请关联的印章信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/19 19:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "印章借用申请-印章Link", groupName = "印章模块", manageShow = false) +public class SealUseLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements SealUseLinkService { + + @Autowired + private SealService sealService; + + @Override + public void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + throw new CustomException("印章信息不能为空."); + } + List sealIds = beans.stream().map(SealUseLink::getSealId).distinct().collect(Collectors.toList()); + Map sealMap = sealService.selectMapByIds(sealIds); + beans.forEach(sealUseLink -> { + Seal seal = sealMap.get(sealUseLink.getSealId()); + if (seal == null) { + throw new CustomException("数据中包含不存在的印章信息."); + } + }); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/MaintenanceType.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/MaintenanceType.java new file mode 100644 index 0000000..db381b5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/MaintenanceType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaintenanceType + * @Description: 车辆维修类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaintenanceType implements SkyeyeEnumClass { + + REPAIR(1, "维修", true, true), + MAINTAIN(2, "保养", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/VehicleState.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/VehicleState.java new file mode 100644 index 0000000..1ab4ea3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/classenum/VehicleState.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: VehicleState + * @Description: 车辆状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum VehicleState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + REPAIR(2, "维修", true, false), + SCRAP(3, "报废", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (VehicleState bean : VehicleState.values()) { + if (state.equals(bean.getKey())) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/AccidentController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/AccidentController.java new file mode 100644 index 0000000..7a52483 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/AccidentController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Accident; +import com.skyeye.eve.vehicle.service.AccidentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AccidentController + * @Description: 车辆事故管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆事故管理", tags = "车辆事故管理", modelName = "车辆模块") +public class AccidentController { + + @Autowired + private AccidentService accidentService; + + /** + * 遍历车辆事故列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "accident001", value = "遍历车辆事故列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AccidentController/queryAccidentList") + public void queryAccidentList(InputObject inputObject, OutputObject outputObject) { + accidentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改事故信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicleAccident", value = "新增/修改事故信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Accident.class) + @RequestMapping("/post/AccidentController/writeVehicleAccident") + public void writeVehicleAccident(InputObject inputObject, OutputObject outputObject) { + accidentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除事故信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "accident003", value = "根据id删除事故信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AccidentController/deleteAccidentById") + public void deleteAccidentById(InputObject inputObject, OutputObject outputObject) { + accidentService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InspectionController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InspectionController.java new file mode 100644 index 0000000..05bb1bf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InspectionController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Inspection; +import com.skyeye.eve.vehicle.service.InspectionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InspectionController + * @Description: 车辆年检管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆年检管理", tags = "车辆年检管理", modelName = "车辆模块") +public class InspectionController { + + @Autowired + private InspectionService inspectionService; + + /** + * 遍历所有的年检列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inspection001", value = "遍历所有的年检列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InspectionController/queryInspectionList") + public void queryInspectionList(InputObject inputObject, OutputObject outputObject) { + inspectionService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改年检信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicleInspection", value = "新增/修改年检信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Inspection.class) + @RequestMapping("/post/InspectionController/writeVehicleInspection") + public void writeVehicleInspection(InputObject inputObject, OutputObject outputObject) { + inspectionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除年检信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inspection003", value = "根据id删除年检信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InspectionController/deleteInspectionById") + public void deleteInspectionById(InputObject inputObject, OutputObject outputObject) { + inspectionService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InsuranceController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InsuranceController.java new file mode 100644 index 0000000..aeba3f0 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/InsuranceController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Insurance; +import com.skyeye.eve.vehicle.service.InsuranceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InsuranceController + * @Description: 车辆保险管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆保险管理", tags = "车辆保险管理", modelName = "车辆模块") +public class InsuranceController { + + @Autowired + private InsuranceService insuranceService; + + /** + * 遍历车辆保险列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insurance001", value = "遍历车辆保险列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InsuranceController/queryInsuranceList") + public void queryInsuranceList(InputObject inputObject, OutputObject outputObject) { + insuranceService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改保险信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicleInsurance", value = "新增/修改保险信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Insurance.class) + @RequestMapping("/post/InsuranceController/writeVehicleInsurance") + public void writeVehicleInsurance(InputObject inputObject, OutputObject outputObject) { + insuranceService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除保险信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insurance003", value = "根据id删除保险信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InsuranceController/deleteInsuranceById") + public void deleteInsuranceById(InputObject inputObject, OutputObject outputObject) { + insuranceService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/MaintenanceController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/MaintenanceController.java new file mode 100644 index 0000000..7221a57 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/MaintenanceController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Maintenance; +import com.skyeye.eve.vehicle.service.MaintenanceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaintenanceController + * @Description: 车辆维修管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆维修管理", tags = "车辆维修管理", modelName = "车辆模块") +public class MaintenanceController { + + @Autowired + private MaintenanceService maintenanceService; + + /** + * 遍历车辆维修保养 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "maintenance001", value = "遍历车辆维修保养", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MaintenanceController/queryMaintenanceList") + public void queryMaintenanceList(InputObject inputObject, OutputObject outputObject) { + maintenanceService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改维修信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicleMaintenance", value = "新增/修改维修信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Maintenance.class) + @RequestMapping("/post/MaintenanceController/writeVehicleMaintenance") + public void writeVehicleMaintenance(InputObject inputObject, OutputObject outputObject) { + maintenanceService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除维修信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "maintenance003", value = "根据id删除维修信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaintenanceController/deleteMaintenanceById") + public void deleteMaintenanceById(InputObject inputObject, OutputObject outputObject) { + maintenanceService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/OilingController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/OilingController.java new file mode 100644 index 0000000..2cde5d6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/OilingController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Oiling; +import com.skyeye.eve.vehicle.service.OilingService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OilingController + * @Description: 车辆加油管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆加油管理", tags = "车辆加油管理", modelName = "车辆模块") +public class OilingController { + + @Autowired + private OilingService oilingService; + + /** + * 遍历车辆加油列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "oiling001", value = "遍历车辆加油列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OilingController/queryOilingList") + public void queryOilingList(InputObject inputObject, OutputObject outputObject) { + oilingService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改加油信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeOiling", value = "新增/修改加油信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Oiling.class) + @RequestMapping("/post/OilingController/writeOiling") + public void writeOiling(InputObject inputObject, OutputObject outputObject) { + oilingService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除加油信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "oiling003", value = "根据id删除加油信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OilingController/deleteOilingById") + public void deleteOilingById(InputObject inputObject, OutputObject outputObject) { + oilingService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleApplyUseController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleApplyUseController.java new file mode 100644 index 0000000..291df21 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleApplyUseController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.VehicleUse; +import com.skyeye.eve.vehicle.service.VehicleApplyUseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: VehicleApplyUseController + * @Description: 用车申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 17:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用车申请", tags = "用车申请", modelName = "车辆模块") +public class VehicleApplyUseController { + + @Autowired + private VehicleApplyUseService vehicleApplyUseService; + + /** + * 获取发起的用车申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle014", value = "获取发起的用车申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VehicleApplyUseController/queryVehicleUseList") + public void queryVehicleUseList(InputObject inputObject, OutputObject outputObject) { + vehicleApplyUseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑用车申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicleUse", value = "新增/编辑用车申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = VehicleUse.class) + @RequestMapping("/post/VehicleApplyUseController/writeVehicleUse") + public void writeVehicleUse(InputObject inputObject, OutputObject outputObject) { + vehicleApplyUseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 用车申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle017", value = "用车申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/VehicleApplyUseController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + vehicleApplyUseService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废用车申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle018", value = "作废用车申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VehicleApplyUseController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + vehicleApplyUseService.invalid(inputObject, outputObject); + } + + /** + * 撤销用车申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle022", value = "撤销用车申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/VehicleApplyUseController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + vehicleApplyUseService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleController.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleController.java new file mode 100644 index 0000000..8cde8dc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/controller/VehicleController.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Vehicle; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: VehicleController + * @Description: 车辆管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 17:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆管理", tags = "车辆管理", modelName = "车辆模块") +public class VehicleController { + + @Autowired + private VehicleService vehicleService; + + /** + * 查询所有的车辆 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle001", value = "查询所有的车辆", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VehicleController/queryVehicleList") + public void queryVehicleList(InputObject inputObject, OutputObject outputObject) { + vehicleService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/修改车辆信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVehicle", value = "新增/修改车辆信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Vehicle.class) + @RequestMapping("/post/VehicleController/writeVehicle") + public void writeVehicle(InputObject inputObject, OutputObject outputObject) { + vehicleService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除车辆信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle003", value = "根据id删除车辆信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VehicleController/deleteVehicleById") + public void deleteVehicleById(InputObject inputObject, OutputObject outputObject) { + vehicleService.deleteById(inputObject, outputObject); + } + + /** + * 车辆恢复正常 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle004", value = "车辆恢复正常", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VehicleController/normalVehicleById") + public void normalVehicleById(InputObject inputObject, OutputObject outputObject) { + vehicleService.normalVehicleById(inputObject, outputObject); + } + + /** + * 车辆维修 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle005", value = "车辆维修", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VehicleController/repairVehicleById") + public void repairVehicleById(InputObject inputObject, OutputObject outputObject) { + vehicleService.repairVehicleById(inputObject, outputObject); + } + + /** + * 车辆报废 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle006", value = "车辆报废", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VehicleController/scrapVehicleById") + public void scrapVehicleById(InputObject inputObject, OutputObject outputObject) { + vehicleService.scrapVehicleById(inputObject, outputObject); + } + + /** + * 查询所有正常的车辆信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle010", value = "查询所有正常的车辆信息", method = "GET", allUse = "2") + @RequestMapping("/post/VehicleController/queryAllNormalVehicleList") + public void queryAllNormalVehicleList(InputObject inputObject, OutputObject outputObject) { + vehicleService.queryAllNormalVehicleList(inputObject, outputObject); + } + + /** + * 查询空闲的司机 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "vehicle012", value = "查询空闲的司机", method = "GET", allUse = "2") + @RequestMapping("/post/VehicleController/queryAvailableDrivers") + public void queryAvailableDrivers(InputObject inputObject, OutputObject outputObject) { + vehicleService.queryAvailableDrivers(inputObject, outputObject); + } + + /** + * 查询所有司机 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllAvailableDrivers", value = "查询所有司机", method = "GET", allUse = "2") + @RequestMapping("/post/VehicleController/queryAllAvailableDrivers") + public void queryAllAvailableDrivers(InputObject inputObject, OutputObject outputObject) { + vehicleService.queryAllAvailableDrivers(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/AccidentDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/AccidentDao.java new file mode 100644 index 0000000..f930297 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/AccidentDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Accident; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AccidentDao + * @Description: 车辆事故管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AccidentDao extends SkyeyeBaseMapper { + + List> queryAccidentList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InspectionDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InspectionDao.java new file mode 100644 index 0000000..e5352ec --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InspectionDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Inspection; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InspectionDao + * @Description: 车辆年检管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InspectionDao extends SkyeyeBaseMapper { + + List> queryInspectionList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceCoverageDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceCoverageDao.java new file mode 100644 index 0000000..843a4b2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceCoverageDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.InsuranceCoverage; + +/** + * @ClassName: InsuranceCoverageDao + * @Description: 车辆保险关联的险种数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InsuranceCoverageDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceDao.java new file mode 100644 index 0000000..288a590 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/InsuranceDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Insurance; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InsuranceDao + * @Description: 车辆保险管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InsuranceDao extends SkyeyeBaseMapper { + + List> queryInsuranceList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/MaintenanceDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/MaintenanceDao.java new file mode 100644 index 0000000..8e0d791 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/MaintenanceDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Maintenance; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaintenanceDao + * @Description: 车辆维修保养数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaintenanceDao extends SkyeyeBaseMapper { + + List> queryMaintenanceList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/OilingDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/OilingDao.java new file mode 100644 index 0000000..fdf607c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/OilingDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Oiling; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OilingDao + * @Description: 车辆加油数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OilingDao extends SkyeyeBaseMapper { + + List> queryOilingList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleApplyUseDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleApplyUseDao.java new file mode 100644 index 0000000..65e4867 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleApplyUseDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.VehicleUse; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: VehicleApplyUseDao + * @Description: 用车申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 17:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface VehicleApplyUseDao extends SkyeyeBaseMapper { + + List> queryVehicleUseList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleDao.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleDao.java new file mode 100644 index 0000000..02e1aae --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/dao/VehicleDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.vehicle.entity.Vehicle; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: VehicleDao + * @Description: 车辆管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 18:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface VehicleDao extends SkyeyeBaseMapper { + + List> queryAvailableDrivers(Map map); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Accident.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Accident.java new file mode 100644 index 0000000..e37c8db --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Accident.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Accident + * @Description: 用车事故实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:accident", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_accident") +@ApiModel("用车事故实体类") +public class Accident extends BaseGeneralInfo { + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("driver_id") + @ApiModelProperty(value = "驾驶员id") + private String driverId; + + @TableField(exist = false) + @Property(value = "驾驶员信息") + private Map driverMation; + + @TableField("accident_time") + @ApiModelProperty(value = "事故时间", required = "required") + private String accidentTime; + + @TableField("accident_area") + @ApiModelProperty(value = "事故地点", required = "required") + private String accidentArea; + + @TableField("accident_detail") + @ApiModelProperty(value = "事故详情") + private String accidentDetail; + + @TableField("confirmation_responsibility") + @ApiModelProperty(value = "责任认定") + private String confirmationResponsibility; + + @TableField("manufacturer") + @ApiModelProperty(value = "维修厂家") + private Integer manufacturer; + + @TableField("repair_start_time") + @ApiModelProperty(value = "送修开始时间") + private String repairStartTime; + + @TableField("repair_end_time") + @ApiModelProperty(value = "送修结束时间") + private String repairEndTime; + + @TableField("repair_price") + @ApiModelProperty(value = "维修费用", required = "double", defaultValue = "0") + private String repairPrice; + + @TableField("repair_content") + @ApiModelProperty(value = "维修内容") + private String repairContent; + + @TableField("loss_fee_price") + @ApiModelProperty(value = "车损费", required = "double", defaultValue = "0") + private String lossFeePrice; + + @TableField("claims_fee_price") + @ApiModelProperty(value = "保险理赔金额", required = "double", defaultValue = "0") + private String claimsFeePrice; + + @TableField("driver_bear_price") + @ApiModelProperty(value = "驾驶员承担费用", required = "double", defaultValue = "0") + private String driverBearPrice; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Inspection.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Inspection.java new file mode 100644 index 0000000..db41305 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Inspection.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Inspection + * @Description: 车辆年检实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:inspection", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_inspection") +@ApiModel("车辆年检实体类") +public class Inspection extends BaseGeneralInfo { + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("inspection_area") + @ApiModelProperty(value = "年检地点") + private String inspectionArea; + + @TableField("contact_information") + @ApiModelProperty(value = "联系电话", required = "phone") + private String contactInformation; + + @TableField("inspection_price") + @ApiModelProperty(value = "年检费用", required = "double", defaultValue = "0") + private String inspectionPrice; + + @TableField("this_inspection_time") + @ApiModelProperty(value = "本次年检时间", required = "required") + private String thisInspectionTime; + + @TableField("next_inspection_time") + @ApiModelProperty(value = "下次年检时间", required = "required") + private String nextInspectionTime; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Insurance.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Insurance.java new file mode 100644 index 0000000..0a69ca3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Insurance.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Insurance + * @Description: 车辆保险实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:insurance", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_insurance") +@ApiModel("车辆保险实体类") +public class Insurance extends BaseGeneralInfo { + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("insurance_company") + @ApiModelProperty(value = "投保公司", required = "required") + private String insuranceCompany; + + @TableField("insured_telephone") + @ApiModelProperty(value = "投保电话", required = "phone") + private String insuredTelephone; + + @TableField("validity_start_time") + @ApiModelProperty(value = "投保有效期开始时间", required = "required") + private String validityStartTime; + + @TableField("validity_end_time") + @ApiModelProperty(value = "投保有效期结束时间", required = "required") + private String validityEndTime; + + @TableField("insurance_all_price") + @ApiModelProperty(value = "投保总费用", required = "required,double") + private String insuranceAllPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "保险险种信息", required = "required,json") + private List vehicleInsuranceCoverages; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/InsuranceCoverage.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/InsuranceCoverage.java new file mode 100644 index 0000000..bc11d42 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/InsuranceCoverage.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: InsuranceCoverage + * @Description: 车辆保险关联的险种实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "vehicle_insurance_coverage") +@ApiModel("车辆保险关联的险种实体类") +public class InsuranceCoverage extends CommonInfo { + + @TableId("id") + private String id; + + @TableField("parent_id") + @Property(value = "车辆保险id") + private String parentId; + + @TableField("coverage_id") + @ApiModelProperty(value = "险种id", required = "required") + private String coverageId; + + @TableField(exist = false) + @Property(value = "险种信息") + private Map coverageMation; + + @TableField("premium") + @ApiModelProperty(value = "保费", required = "required,double") + private String premium; + + @TableField("insured_amount") + @ApiModelProperty(value = "保额", required = "required,double") + private String insuredAmount; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Maintenance.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Maintenance.java new file mode 100644 index 0000000..a5a260b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Maintenance.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Maintenance + * @Description: 车辆维修实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:maintenance", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_maintenance") +@ApiModel("车辆维修实体类") +public class Maintenance extends BaseGeneralInfo { + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("maintenance_type") + @ApiModelProperty(value = "类型,参考#MaintenanceType", required = "required") + private Integer maintenanceType; + + @TableField("maintenance_price") + @ApiModelProperty(value = "费用", required = "required,double") + private String maintenancePrice; + + @TableField("start_time") + @ApiModelProperty(value = "开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间", required = "required") + private String endTime; + + @TableField("content") + @ApiModelProperty(value = "具体内容", required = "required") + private String content; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Oiling.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Oiling.java new file mode 100644 index 0000000..89b448d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Oiling.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Oiling + * @Description: 车辆加油实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:oiling", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_oiling") +@ApiModel("车辆加油实体类") +public class Oiling extends BaseGeneralInfo { + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("oil_time") + @ApiModelProperty(value = "加油日期", required = "required") + private String oilTime; + + @TableField("oil_capacity") + @ApiModelProperty(value = "加油容量", required = "required") + private String oilCapacity; + + @TableField("oil_price") + @ApiModelProperty(value = "加油金额", required = "required,double") + private String oilPrice; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Vehicle.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Vehicle.java new file mode 100644 index 0000000..f6fafa6 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/Vehicle.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Vehicle + * @Description: 车辆实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/6 9:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"licensePlate"}) +@RedisCacheField(name = "assistant:vehicle", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "vehicle") +@ApiModel("车辆实体类") +public class Vehicle extends BaseGeneralInfo { + + @TableField(value = "img") + @ApiModelProperty(value = "车辆图片", required = "required") + private String img; + + @TableField(value = "license_plate") + @ApiModelProperty(value = "车牌", required = "required", fuzzyLike = true) + private String licensePlate; + + @TableField(value = "specifications") + @ApiModelProperty(value = "车辆规格(准载人数)", required = "required,num") + private Integer specifications; + + @TableField(value = "oil_consumption") + @ApiModelProperty(value = "油耗") + private String oilConsumption; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "color") + @ApiModelProperty(value = "车辆颜色") + private String color; + + @TableField(value = "manufacturer") + @ApiModelProperty(value = "生产商") + private String manufacturer; + + @TableField(value = "manufacture_time") + @ApiModelProperty(value = "生产日期") + private String manufactureTime; + + @TableField(value = "supplier") + @ApiModelProperty(value = "供应商") + private String supplier; + + @TableField(value = "purchase_time") + @ApiModelProperty(value = "采购日期") + private String purchaseTime; + + @TableField(value = "engine_number") + @ApiModelProperty(value = "发动机号") + private String engineNumber; + + @TableField(value = "frame_number") + @ApiModelProperty(value = "车架号") + private String frameNumber; + + @TableField(value = "storage_area") + @ApiModelProperty(value = "存放区域") + private String storageArea; + + @TableField(value = "next_inspection_time") + @ApiModelProperty(value = "下次年检时间") + private String nextInspectionTime; + + @TableField(value = "insurance_deadline") + @ApiModelProperty(value = "保险截止日期") + private String insuranceDeadline; + + @TableField(value = "prev_maintain_time") + @ApiModelProperty(value = "上次保养日期") + private String prevMaintainTime; + + @TableField(value = "vehicle_admin") + @ApiModelProperty(value = "管理人") + private String vehicleAdmin; + + @TableField(exist = false) + @Property(value = "管理人") + private Map vehicleAdminMation; + + @TableField(value = "state") + @Property(value = "车辆状态,参考#VehicleState") + private Integer state; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/VehicleUse.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/VehicleUse.java new file mode 100644 index 0000000..2b0b71c --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/entity/VehicleUse.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: VehicleUse + * @Description: 用车申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "assistant:vehicle:use", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "vehicle_use") +@ApiModel("用车申请实体类") +public class VehicleUse extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("vehicle_id") + @ApiModelProperty(value = "车辆id", required = "required") + private String vehicleId; + + @TableField(exist = false) + @Property(value = "车辆信息") + private Vehicle vehicleMation; + + @TableField("driver_id") + @ApiModelProperty(value = "驾驶员id") + private String driverId; + + @TableField(exist = false) + @Property(value = "驾驶员信息") + private Map driverMation; + + @TableField("passenger_num") + @ApiModelProperty(value = "乘车人数", required = "required,num") + private Integer passengerNum; + + @TableField("departure_time") + @ApiModelProperty(value = "出发时间", required = "required") + private String departureTime; + + @TableField("return_time") + @ApiModelProperty(value = "返回时间", required = "required") + private String returnTime; + + @TableField("reasons_for_using_car") + @ApiModelProperty(value = "用车事由", required = "required") + private String reasonsForUsingCar; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/AccidentService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/AccidentService.java new file mode 100644 index 0000000..27248be --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/AccidentService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.Accident; + +/** + * @ClassName: AccidentService + * @Description: 车辆事故管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/11 16:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AccidentService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InspectionService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InspectionService.java new file mode 100644 index 0000000..bab02bc --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InspectionService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.Inspection; + +/** + * @ClassName: InspectionService + * @Description: 车辆年检管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 9:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InspectionService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceCoverageService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceCoverageService.java new file mode 100644 index 0000000..e5f2b83 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceCoverageService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.InsuranceCoverage; + +import java.util.List; + +/** + * @ClassName: InsuranceCoverageService + * @Description: 车辆保险关联的险种服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 10:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InsuranceCoverageService extends SkyeyeBusinessService { + + void deleteInsuranceCoverageByPId(String parentId); + + void saveInsuranceCoverage(String parentId, List vehicleInsuranceCoverages, String userId); + + List queryInsuranceCoverageByPId(String parentId); + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceService.java new file mode 100644 index 0000000..0dfc6b8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/InsuranceService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.Insurance; + +/** + * @ClassName: InsuranceService + * @Description: 车辆保险管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 9:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InsuranceService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/MaintenanceService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/MaintenanceService.java new file mode 100644 index 0000000..a11db5b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/MaintenanceService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.Maintenance; + +/** + * @ClassName: MaintenanceService + * @Description: 车辆维修管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 11:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaintenanceService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/OilingService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/OilingService.java new file mode 100644 index 0000000..63b8078 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/OilingService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.vehicle.entity.Oiling; + +/** + * @ClassName: OilingService + * @Description: 车辆加油服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 11:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OilingService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleApplyUseService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleApplyUseService.java new file mode 100644 index 0000000..3498e67 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleApplyUseService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.eve.vehicle.entity.VehicleUse; + +/** + * @ClassName: VehicleApplyUseService + * @Description: 用车申请服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 17:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface VehicleApplyUseService extends SkyeyeFlowableService { + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleService.java new file mode 100644 index 0000000..77090c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/VehicleService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.vehicle.entity.Vehicle; + +/** + * @ClassName: VehicleService + * @Description: 车辆管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 18:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface VehicleService extends SkyeyeBusinessService { + + void normalVehicleById(InputObject inputObject, OutputObject outputObject); + + void repairVehicleById(InputObject inputObject, OutputObject outputObject); + + void scrapVehicleById(InputObject inputObject, OutputObject outputObject); + + void queryAllNormalVehicleList(InputObject inputObject, OutputObject outputObject); + + void queryAvailableDrivers(InputObject inputObject, OutputObject outputObject); + + void queryAllAvailableDrivers(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/AccidentServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/AccidentServiceImpl.java new file mode 100644 index 0000000..4e93eec --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/AccidentServiceImpl.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.AccidentDao; +import com.skyeye.eve.vehicle.entity.Accident; +import com.skyeye.eve.vehicle.service.AccidentService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AccidentServiceImpl + * @Description: 车辆事故管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/17 21:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆事故管理", groupName = "车辆模块") +public class AccidentServiceImpl extends SkyeyeBusinessServiceImpl implements AccidentService { + + @Autowired + private VehicleService vehicleService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAccidentList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + // 设置驾驶员信息 + List staffIds = beans.stream().map(bean -> bean.get("driverId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String driverId = bean.get("driverId").toString(); + bean.put("driverMation", staffMap.get(driverId)); + }); + return beans; + } + + @Override + public Accident selectById(String id) { + Accident vehicleAccident = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(vehicleAccident, Accident::getVehicleId); + // 驾驶员信息 + Map> staffMap = iAuthUserService + .queryUserMationListByStaffIds(Arrays.asList(vehicleAccident.getDriverId())); + Map staff = staffMap.get(vehicleAccident.getDriverId()); + vehicleAccident.setDriverMation(staff); + return vehicleAccident; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InspectionServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InspectionServiceImpl.java new file mode 100644 index 0000000..6042c91 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InspectionServiceImpl.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.InspectionDao; +import com.skyeye.eve.vehicle.entity.Inspection; +import com.skyeye.eve.vehicle.service.InspectionService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InspectionServiceImpl + * @Description: 车辆年检管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:33 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆年检管理", groupName = "车辆模块") +public class InspectionServiceImpl extends SkyeyeBusinessServiceImpl implements InspectionService { + + @Autowired + private VehicleService vehicleService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryInspectionList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + return beans; + } + + @Override + public Inspection selectById(String id) { + Inspection vehicleInspection = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(vehicleInspection, Inspection::getVehicleId); + return vehicleInspection; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceCoverageServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceCoverageServiceImpl.java new file mode 100644 index 0000000..8e56200 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceCoverageServiceImpl.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.vehicle.dao.InsuranceCoverageDao; +import com.skyeye.eve.vehicle.entity.InsuranceCoverage; +import com.skyeye.eve.vehicle.service.InsuranceCoverageService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: InsuranceCoverageServiceImpl + * @Description: 车辆保险关联的险种服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/12 10:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆保险关联的险种", groupName = "车辆模块", manageShow = false) +public class InsuranceCoverageServiceImpl extends SkyeyeBusinessServiceImpl implements InsuranceCoverageService { + + @Override + public void deleteInsuranceCoverageByPId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(InsuranceCoverage::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public void saveInsuranceCoverage(String parentId, List vehicleInsuranceCoverages, String userId) { + deleteInsuranceCoverageByPId(parentId); + if (CollectionUtil.isNotEmpty(vehicleInsuranceCoverages)) { + for (InsuranceCoverage farmProcedure : vehicleInsuranceCoverages) { + farmProcedure.setParentId(parentId); + } + createEntity(vehicleInsuranceCoverages, userId); + } + } + + @Override + public List queryInsuranceCoverageByPId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(InsuranceCoverage::getParentId), parentId); + List vehicleInsuranceCoverages = list(queryWrapper); + return vehicleInsuranceCoverages; + } +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceServiceImpl.java new file mode 100644 index 0000000..b0dafd3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/InsuranceServiceImpl.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.InsuranceDao; +import com.skyeye.eve.vehicle.entity.Insurance; +import com.skyeye.eve.vehicle.entity.InsuranceCoverage; +import com.skyeye.eve.vehicle.service.InsuranceService; +import com.skyeye.eve.vehicle.service.InsuranceCoverageService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InsuranceServiceImpl + * @Description: 车辆保险服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆保险管理", groupName = "车辆模块") +public class InsuranceServiceImpl extends SkyeyeBusinessServiceImpl implements InsuranceService { + + @Autowired + private VehicleService vehicleService; + + @Autowired + private InsuranceCoverageService insuranceCoverageService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryInsuranceList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + return beans; + } + + @Override + public void writePostpose(Insurance entity, String userId) { + super.writePostpose(entity, userId); + insuranceCoverageService.saveInsuranceCoverage(entity.getId(), entity.getVehicleInsuranceCoverages(), userId); + } + + @Override + public Insurance getDataFromDb(String id) { + Insurance vehicleInsurance = super.getDataFromDb(id); + // 保险险种信息 + List vehicleInsuranceCoverages = insuranceCoverageService.queryInsuranceCoverageByPId(id); + vehicleInsurance.setVehicleInsuranceCoverages(vehicleInsuranceCoverages); + return vehicleInsurance; + } + + @Override + public Insurance selectById(String id) { + Insurance vehicleInsurance = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(vehicleInsurance, Insurance::getVehicleId); + // 保险险种信息 + iSysDictDataService.setDataMation(vehicleInsurance.getVehicleInsuranceCoverages(), InsuranceCoverage::getCoverageId); + return vehicleInsurance; + } + + @Override + protected void deletePostpose(String id) { + insuranceCoverageService.deleteInsuranceCoverageByPId(id); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/MaintenanceServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/MaintenanceServiceImpl.java new file mode 100644 index 0000000..c2c9761 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/MaintenanceServiceImpl.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.MaintenanceDao; +import com.skyeye.eve.vehicle.entity.Maintenance; +import com.skyeye.eve.vehicle.service.MaintenanceService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaintenanceServiceImpl + * @Description: 车辆维修保养服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆维修管理", groupName = "车辆模块") +public class MaintenanceServiceImpl extends SkyeyeBusinessServiceImpl implements MaintenanceService { + + @Autowired + private VehicleService vehicleService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryMaintenanceList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + return beans; + } + + @Override + public Maintenance selectById(String id) { + Maintenance maintenance = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(maintenance, Maintenance::getVehicleId); + return maintenance; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/OilingServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/OilingServiceImpl.java new file mode 100644 index 0000000..cfbfbc1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/OilingServiceImpl.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.OilingDao; +import com.skyeye.eve.vehicle.entity.Oiling; +import com.skyeye.eve.vehicle.service.OilingService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OilingServiceImpl + * @Description: 车辆加油服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/24 15:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆加油管理", groupName = "车辆模块") +public class OilingServiceImpl extends SkyeyeBusinessServiceImpl implements OilingService { + + @Autowired + private VehicleService vehicleService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryOilingList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + return beans; + } + + @Override + public Oiling selectById(String id) { + Oiling oiling = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(oiling, Oiling::getVehicleId); + return oiling; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleApplyUseServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleApplyUseServiceImpl.java new file mode 100644 index 0000000..3d9d068 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleApplyUseServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.vehicle.dao.VehicleApplyUseDao; +import com.skyeye.eve.vehicle.entity.VehicleUse; +import com.skyeye.eve.vehicle.service.VehicleApplyUseService; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: VehicleApplyUseServiceImpl + * @Description: 用车申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 17:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用车申请", groupName = "车辆模块", flowable = true) +public class VehicleApplyUseServiceImpl extends SkyeyeFlowableServiceImpl implements VehicleApplyUseService { + + @Autowired + private VehicleService vehicleService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryVehicleUseList(pageInfo); + vehicleService.setMationForMap(beans, "vehicleId", "vehicleMation"); + // 设置驾驶员信息 + List staffIds = beans.stream().map(bean -> bean.get("driverId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String driverId = bean.get("driverId").toString(); + bean.put("driverMation", staffMap.get(driverId)); + }); + return beans; + } + + @Override + public VehicleUse selectById(String id) { + VehicleUse vehicleUse = super.selectById(id); + // 车辆信息 + vehicleService.setDataMation(vehicleUse, VehicleUse::getVehicleId); + // 驾驶员信息 + Map> staffMap = iAuthUserService + .queryUserMationListByStaffIds(Arrays.asList(vehicleUse.getDriverId())); + Map staff = staffMap.get(vehicleUse.getDriverId()); + vehicleUse.setDriverMation(staff); + return vehicleUse; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleServiceImpl.java new file mode 100644 index 0000000..332dc6f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/eve/vehicle/service/impl/VehicleServiceImpl.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.vehicle.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.UserStaffState; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.conference.entity.ConferenceRoom; +import com.skyeye.eve.vehicle.classenum.VehicleState; +import com.skyeye.eve.vehicle.dao.VehicleDao; +import com.skyeye.eve.vehicle.entity.Vehicle; +import com.skyeye.eve.vehicle.service.VehicleService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: VehicleServiceImpl + * @Description: 车辆管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "车辆管理", groupName = "车辆模块") +public class VehicleServiceImpl extends SkyeyeBusinessServiceImpl implements VehicleService { + + @Override + public void createPrepose(Vehicle entity) { + entity.setState(VehicleState.NORMAL.getKey()); + } + + @Override + public Vehicle selectById(String id) { + Vehicle vehicle = super.selectById(id); + vehicle.setVehicleAdminMation(iAuthUserService.queryDataMationById(vehicle.getVehicleAdmin())); + return vehicle; + } + + /** + * 车辆恢复正常 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void normalVehicleById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Vehicle vehicle = selectById(id); + if (vehicle.getState().equals(VehicleState.REPAIR.getKey()) || vehicle.getState().equals(VehicleState.SCRAP.getKey())) { + // 维修或者报废可以恢复正常 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), VehicleState.NORMAL.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 车辆维修 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void repairVehicleById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Vehicle vehicle = selectById(id); + if (vehicle.getState().equals(VehicleState.NORMAL.getKey()) || vehicle.getState().equals(VehicleState.SCRAP.getKey())) { + // 正常或者报废可以维修 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), VehicleState.REPAIR.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 车辆报废 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void scrapVehicleById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Vehicle vehicle = selectById(id); + if (vehicle.getState().equals(VehicleState.NORMAL.getKey()) || vehicle.getState().equals(VehicleState.REPAIR.getKey())) { + // 正常或者维修可以报废 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ConferenceRoom::getState), VehicleState.SCRAP.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + @Override + public void queryAllNormalVehicleList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Vehicle::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Vehicle::getState), VehicleState.NORMAL.getKey()); + + List vehicleList = list(queryWrapper); + outputObject.setBeans(vehicleList); + outputObject.settotal(vehicleList.size()); + } + + /** + * 查询空闲的司机 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAvailableDrivers(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("state", UserStaffState.ON_THE_JOB.getKey()); + List> beans = skyeyeBaseMapper.queryAvailableDrivers(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void queryAllAvailableDrivers(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = skyeyeBaseMapper.queryAvailableDrivers(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/ComplexMailDeliveryServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/ComplexMailDeliveryServiceImpl.java new file mode 100644 index 0000000..952e9a3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/ComplexMailDeliveryServiceImpl.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ComplexMailDeliveryServiceImpl + * @Description: 邮件发送 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/4 21:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.complex-mail-delivery-service}", + consumerGroup = "${topic.complex-mail-delivery-service}", + selectorExpression = "${spring.profiles.active}") +public class ComplexMailDeliveryServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(ComplexMailDeliveryServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + // 获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String title = map.get("title").toString();// 标题 + String content = map.get("content").toString();// 邮件内容 + String toPeople = map.get("toPeople").toString();// 收件人 + String toCc = map.get("toCc").toString();// 抄送人 + String toBCc = map.get("toBcc").toString();// 暗送人 + String username = map.get("userAddress").toString();// 登录邮箱账号 + String password = map.get("userPassword").toString();// 密码 + String emailEnclosure = map.get("emailEnclosure").toString(); + String emailId = map.get("emailId").toString(); + List> emailEnclosureList = JSONUtil.toList(emailEnclosure, null); + List> beans = new ArrayList<>(); + for (int i = 0; i < emailEnclosureList.size(); i++) { + Map j = emailEnclosureList.get(i); + Map bean = new HashMap<>(); + bean.put("fileName", j.get("fileName")); + bean.put("filePath", j.get("filePath")); + beans.add(bean); + } + // 发送邮件 + String messageId = new MailUtil(username, password, emailServer.get("emailSendServer").toString()) + .send(toPeople, toCc, toBCc, title, content, tPath.replace("images", ""), beans); + if (!ToolUtil.isBlank(messageId)) { + Map emailEditMessageId = new HashMap<>(); + emailEditMessageId.put("id", emailId); + emailEditMessageId.put("messageId", messageId); + emailDao.editEmailMessageIdByEmailId(emailEditMessageId); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("send email failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDeleteServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDeleteServiceImpl.java new file mode 100644 index 0000000..0924b2f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDeleteServiceImpl.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.EmailUtil; +import com.skyeye.common.util.ShowMail; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.classenum.EmailState; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 javax.mail.Folder; +import javax.mail.Message; +import javax.mail.Part; +import javax.mail.internet.MimeMessage; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MailAccessDeleteServiceImpl + * @Description: 已删除邮件获取 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/4 21:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-access-delete-service}", + consumerGroup = "${topic.mail-access-delete-service}", + selectorExpression = "${spring.profiles.active}") +public class MailAccessDeleteServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailAccessDeleteServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + + String storeType = emailServer.get("emailType").toString();//邮箱类型 + String host = emailServer.get("emailReceiptServer").toString();//邮箱收件服务器 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String basePath = tPath + "upload/emailenclosure/";//附件存储路径 + + Folder folder = ToolUtil.getFolderByServer(host, username, password, storeType, "Deleted Messages"); + if (!folder.exists()) {//如果文件夹不存在,则创建 + folder.create(Folder.HOLDS_MESSAGES); + } + folder.open(Folder.READ_ONLY); + Message[] message = folder.getMessages();//获取邮件信息 + ShowMail re = null; + //邮件集合 + List> beans = new ArrayList<>(); + Map bean = null; + //附件集合 + List> enclosureBeans = new ArrayList<>(); + //获取当前邮箱已有的邮件 + List> emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.DELETE.getKey()); + + //创建目录 + ToolUtil.createFolder(basePath); + + //遍历邮件数据 + for (int i = 0; i < message.length; i++) { + if (!message[i].getFolder().isOpen()) { + // 判断是否open,如果close,就重新open + message[i].getFolder().open(Folder.READ_ONLY); + } + re = new ShowMail((MimeMessage) message[i]); + //如果该邮件在本地数据库中不存在并且messageId不为空 + //收件人或者抄送人或者暗送人是当前账号 + if (!ToolUtil.judgeInListByMessage(emailHasMail, re.getMessageId()) && !ToolUtil.isBlank(re.getMessageId()) + && (re.getMailAddress("to").indexOf(username) > -1 || re.getMailAddress("cc").indexOf(username) > -1 || re.getMailAddress("bcc").indexOf(username) > -1)) { + bean = EmailUtil.getEmailMationByUtil(re, message[i]); + String rowId = ToolUtil.getSurFaceId(); + re.setDateFormat(DateUtil.YYYY_MM_DD_HH_MM_SS); + bean.put("id", rowId);//id + bean.put("emailState", "2");//邮件状态 0.草稿 1.正常 2.已删除 + re.setAttachPath(basePath);//设置附件保存基础路径 + enclosureBeans.addAll(re.saveAttachMent((Part) message[i], rowId));//保存附件 + beans.add(bean); + } + if (beans.size() >= 20) {//每20条数据保存一次 + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + beans.clear(); + enclosureBeans.clear(); + emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.DELETE.getKey()); + } + } + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("get Trash acquisition failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDraftsServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDraftsServiceImpl.java new file mode 100644 index 0000000..856809d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessDraftsServiceImpl.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.EmailUtil; +import com.skyeye.common.util.ShowMail; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.classenum.EmailState; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 javax.mail.Folder; +import javax.mail.Message; +import javax.mail.Part; +import javax.mail.internet.MimeMessage; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MailAccessDraftsServiceImpl + * @Description: 草稿箱邮件获取 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/4 21:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-access-drafts-service}", + consumerGroup = "${topic.mail-access-drafts-service}", + selectorExpression = "${spring.profiles.active}") +public class MailAccessDraftsServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailAccessDraftsServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + + String storeType = emailServer.get("emailType").toString();//邮箱类型 + String host = emailServer.get("emailReceiptServer").toString();//邮箱收件服务器 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String basePath = tPath + "upload/emailenclosure/";//附件存储路径 + + // 创建一个数值格式化对象 + NumberFormat numberFormat = NumberFormat.getInstance(); + // 设置精确到小数点后0位 + numberFormat.setMaximumFractionDigits(0); + + Folder folder = ToolUtil.getFolderByServer(host, username, password, storeType, "Drafts"); + if (!folder.exists()) { + // 如果文件夹不存在,则创建 + folder.create(Folder.HOLDS_MESSAGES); + } + folder.open(Folder.READ_ONLY); + Message[] message = folder.getMessages();//获取邮件信息 + ShowMail re = null; + //邮件集合 + List> beans = new ArrayList<>(); + Map bean = null; + //附件集合 + List> enclosureBeans = new ArrayList<>(); + //获取当前邮箱已有的邮件 + List> emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.DRAFT.getKey()); + + //创建目录 + ToolUtil.createFolder(basePath); + + //遍历邮件数据 + for (int i = 0; i < message.length; i++) { + if (!message[i].getFolder().isOpen()) { + // 判断是否open,如果close,就重新open + message[i].getFolder().open(Folder.READ_ONLY); + } + re = new ShowMail((MimeMessage) message[i]); + //如果该邮件在本地数据库中不存在并且messageId不为空 + //发送人为当前邮箱 + if (!ToolUtil.judgeInListByMessage(emailHasMail, re.getMessageId()) && !ToolUtil.isBlank(re.getMessageId()) + && re.getAddressFrom().indexOf(username) > -1) { + bean = EmailUtil.getEmailMationByUtil(re, message[i]); + String rowId = ToolUtil.getSurFaceId(); + bean.put("id", rowId);//id + bean.put("emailState", "0");//邮件状态 0.草稿 1.正常 2.已删除 + re.setAttachPath(basePath);//设置附件保存基础路径 + enclosureBeans.addAll(re.saveAttachMent((Part) message[i], rowId));//保存附件 + beans.add(bean); + } + if (beans.size() >= 20) {//每20条数据保存一次 + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + beans.clear(); + enclosureBeans.clear(); + emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.DRAFT.getKey()); + } + } + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Draft mail access failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessInboxServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessInboxServiceImpl.java new file mode 100644 index 0000000..b5a4632 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessInboxServiceImpl.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.EmailUtil; +import com.skyeye.common.util.ShowMail; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.classenum.EmailState; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 javax.mail.Folder; +import javax.mail.Message; +import javax.mail.Part; +import javax.mail.internet.MimeMessage; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: MailAccessInboxServiceImpl + * @Description: 收件箱邮件获取 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-access-inbox-service}", + consumerGroup = "${topic.mail-access-inbox-service}", + selectorExpression = "${spring.profiles.active}") +public class MailAccessInboxServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailAccessInboxServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + LOGGER.info("get mail start"); + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + LOGGER.info("jobId id is {}", jobId); + try { + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + + String storeType = emailServer.get("emailType").toString();//邮箱类型 + String host = emailServer.get("emailReceiptServer").toString();//邮箱收件服务器 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String basePath = tPath + "upload/emailenclosure/";//附件存储路径 + + // 创建一个数值格式化对象 + NumberFormat numberFormat = NumberFormat.getInstance(); + // 设置精确到小数点后0位 + numberFormat.setMaximumFractionDigits(0); + + Folder folder = ToolUtil.getFolderByServer(host, username, password, storeType, "INBOX"); + if (!folder.exists()) {//如果文件夹不存在,则创建 + folder.create(Folder.HOLDS_MESSAGES); + } + folder.open(Folder.READ_ONLY); + Message[] message = folder.getMessages();//获取邮件信息 + ShowMail re = null; + //邮件集合 + List> beans = new ArrayList<>(); + Map bean = null; + //附件集合 + List> enclosureBeans = new ArrayList<>(); + //获取当前邮箱已有的邮件 + List> emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.NORMAL.getKey()); + + //创建目录 + ToolUtil.createFolder(basePath); + + //遍历邮件数据 + for (int i = 0; i < message.length; i++) { + if (!message[i].getFolder().isOpen()) { + // 判断是否open,如果close,就重新open + message[i].getFolder().open(Folder.READ_ONLY); + } + re = new ShowMail((MimeMessage) message[i]); + try { + LOGGER.info("get message mation is {}", JSONUtil.toJsonStr(re)); + } catch (Exception e) { + continue; + } + // 如果该邮件在本地数据库中不存在并且messageId不为空 ||收件人或者抄送人或者暗送人是当前账号 + if (!ToolUtil.judgeInListByMessage(emailHasMail, re.getMessageId()) + && !ToolUtil.isBlank(re.getMessageId()) + && (re.getMailAddress("to").indexOf(username) > -1 || re.getMailAddress("cc").indexOf(username) > -1 || re.getMailAddress("bcc").indexOf(username) > -1)) { + bean = EmailUtil.getEmailMationByUtil(re, message[i]); + String rowId = ToolUtil.getSurFaceId(); + bean.put("id", rowId);//id + bean.put("emailState", "1");//邮件状态 0.草稿 1.正常 2.已删除 + re.setAttachPath(basePath);//设置附件保存基础路径 + enclosureBeans.addAll(re.saveAttachMent((Part) message[i], rowId));//保存附件 + beans.add(bean); + } + if (beans.size() >= 20) {//每20条数据保存一次 + emailDao.insertEmailListToServer(beans); + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + beans.clear(); + enclosureBeans.clear(); + //重置当前邮箱已有的邮件 + emailHasMail = emailDao.queryEmailListByEmailAddress(username, EmailState.NORMAL.getKey()); + } + } + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + } catch (Exception e) { + LOGGER.warn("Inbox mail acquisition failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + return; + } finally { + } + LOGGER.info("get mail end"); + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Inbox mail acquisition failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessSendedServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessSendedServiceImpl.java new file mode 100644 index 0000000..7720157 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailAccessSendedServiceImpl.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.EmailUtil; +import com.skyeye.common.util.ShowMail; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.classenum.EmailState; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 javax.mail.Folder; +import javax.mail.Message; +import javax.mail.Part; +import javax.mail.internet.MimeMessage; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: MailAccessSendedServiceImpl + * @Description: 已发送邮件获取 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-access-sended-service}", + consumerGroup = "${topic.mail-access-sended-service}", + selectorExpression = "${spring.profiles.active}") +public class MailAccessSendedServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailAccessSendedServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + + String storeType = emailServer.get("emailType").toString();//邮箱类型 + String host = emailServer.get("emailReceiptServer").toString();//邮箱收件服务器 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String basePath = tPath + "upload/emailenclosure/";//附件存储路径 + + // 创建一个数值格式化对象 + NumberFormat numberFormat = NumberFormat.getInstance(); + // 设置精确到小数点后0位 + numberFormat.setMaximumFractionDigits(0); + + Folder folder = ToolUtil.getFolderByServer(host, username, password, storeType, "Sent Messages"); + if (!folder.exists()) {//如果文件夹不存在,则创建 + folder.create(Folder.HOLDS_MESSAGES); + } + folder.open(Folder.READ_ONLY); + Message[] message = folder.getMessages();//获取邮件信息 + ShowMail re = null; + //邮件集合 + List> beans = new ArrayList<>(); + Map bean = null; + //附件集合 + List> enclosureBeans = new ArrayList<>(); + //获取当前邮箱已有的邮件 + List> emailHasMail = emailDao.queryEmailListByEmailFromAddress(username, EmailState.NORMAL.getKey()); + + //创建目录 + ToolUtil.createFolder(basePath); + + //遍历邮件数据 + for (int i = 0; i < message.length; i++) { + if (!message[i].getFolder().isOpen()) { + // 判断是否open,如果close,就重新open + message[i].getFolder().open(Folder.READ_ONLY); + } + re = new ShowMail((MimeMessage) message[i]); + try { + LOGGER.info("get message mation is {}", JSONUtil.toJsonStr(re)); + } catch (Exception e) { + continue; + } + // 如果该邮件在本地数据库中不存在并且messageId不为空,发送人为当前邮箱 + if (!ToolUtil.judgeInListByMessage(emailHasMail, re.getMessageId()) && !ToolUtil.isBlank(re.getMessageId()) + && re.getAddressFrom().indexOf(username) > -1) { + bean = EmailUtil.getEmailMationByUtil(re, message[i]); + String rowId = ToolUtil.getSurFaceId(); + bean.put("id", rowId);//id + bean.put("emailState", "1");//邮件状态 0.草稿 1.正常 2.已删除 + re.setAttachPath(basePath);//设置附件保存基础路径 + enclosureBeans.addAll(re.saveAttachMent((Part) message[i], rowId));//保存附件 + beans.add(bean); + } + if (beans.size() >= 20) {//每20条数据保存一次 + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + beans.clear(); + enclosureBeans.clear(); + emailHasMail = emailDao.queryEmailListByEmailFromAddress(username, EmailState.NORMAL.getKey()); + } + } + if (!beans.isEmpty()) { + emailDao.insertEmailListToServer(beans); + } + if (!enclosureBeans.isEmpty()) { + emailDao.insertEmailEnclosureListToServer(enclosureBeans); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Sent mail get failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsEditServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsEditServiceImpl.java new file mode 100644 index 0000000..f608dcf --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsEditServiceImpl.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.email.entity.Email; +import com.skyeye.eve.email.service.EmailService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: MailDraftsEditServiceImpl + * @Description: 草稿编辑同步 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-drafts-edit-service}", + consumerGroup = "${topic.mail-drafts-edit-service}", + selectorExpression = "${spring.profiles.active}") +public class MailDraftsEditServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailDraftsEditServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private EmailService emailService; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String title = map.get("title").toString();//标题 + String content = map.get("content").toString();//邮件内容 + String toPeople = map.get("toPeople").toString();//收件人 + String toCc = map.get("toCc").toString();//抄送人 + String toBCc = map.get("toBcc").toString();//暗送人 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String emailEnclosure = map.get("emailEnclosure").toString(); + String emailId = map.get("emailId").toString(); + List> emailEnclosureList = JSONUtil.toList(emailEnclosure, null); + List> beans = new ArrayList<>(); + Map bean = null; + for (int i = 0; i < emailEnclosureList.size(); i++) { + Map j = emailEnclosureList.get(i); + bean = new HashMap<>(); + bean.put("fileName", j.get("fileName")); + bean.put("filePath", j.get("filePath")); + beans.add(bean); + } + //获取邮件的messageid + Email message = emailService.selectById(emailId); + //删除之前的草稿件 + new MailUtil(username, password, emailServer.get("emailReceiptServer").toString()) + .deleteEmail(username, title, message.getMessageId()); + //保存邮件为草稿 + String messageId = new MailUtil(username, password, emailServer.get("emailReceiptServer").toString()) + .saveDraftsEmail(toPeople, toCc, toBCc, title, content, tPath.replace("images", ""), beans); + if (!ToolUtil.isBlank(messageId)) { + Map emailEditMessageId = new HashMap<>(); + emailEditMessageId.put("id", emailId); + emailEditMessageId.put("messageId", messageId); + emailDao.editEmailMessageIdByEmailId(emailEditMessageId); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Draft edit synchronization failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSaveServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSaveServiceImpl.java new file mode 100644 index 0000000..6a81e36 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSaveServiceImpl.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: MailDraftsSaveServiceImpl + * @Description: 保存草稿同步 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-drafts-save-service}", + consumerGroup = "${topic.mail-drafts-save-service}", + selectorExpression = "${spring.profiles.active}") +public class MailDraftsSaveServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailDraftsSaveServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + // 获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String title = map.get("title").toString();//标题 + String content = map.get("content").toString();//邮件内容 + String toPeople = map.get("toPeople").toString();//收件人 + String toCc = map.get("toCc").toString();//抄送人 + String toBCc = map.get("toBcc").toString();//暗送人 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String emailEnclosure = map.get("emailEnclosure").toString(); + String emailId = map.get("emailId").toString(); + List> emailEnclosureList = JSONUtil.toList(emailEnclosure, null); + List> beans = new ArrayList<>(); + Map bean = null; + for (int i = 0; i < emailEnclosureList.size(); i++) { + Map j = emailEnclosureList.get(i); + bean = new HashMap<>(); + bean.put("fileName", j.get("fileName")); + bean.put("filePath", j.get("filePath")); + beans.add(bean); + } + //保存邮件为草稿 + String messageId = new MailUtil(username, password, emailServer.get("emailReceiptServer").toString()) + .saveDraftsEmail(toPeople, toCc, toBCc, title, content, tPath.replace("images", ""), beans); + if (!ToolUtil.isBlank(messageId)) { + Map emailEditMessageId = new HashMap<>(); + emailEditMessageId.put("id", emailId); + emailEditMessageId.put("messageId", messageId); + emailDao.editEmailMessageIdByEmailId(emailEditMessageId); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Save draft sync failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSendServiceImpl.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSendServiceImpl.java new file mode 100644 index 0000000..034f8ff --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/MailDraftsSendServiceImpl.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.email.dao.EmailDao; +import com.skyeye.eve.email.entity.Email; +import com.skyeye.eve.email.service.EmailService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.util.MqSendUtil; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: MailDraftsSendServiceImpl + * @Description: 草稿箱邮件发送 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.mail-drafts-send-service}", + consumerGroup = "${topic.mail-drafts-send-service}", + selectorExpression = "${spring.profiles.active}") +public class MailDraftsSendServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(MailDraftsSendServiceImpl.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private EmailDao emailDao; + + @Autowired + private EmailService emailService; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + //获取服务器信息 + Map emailServer = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String title = map.get("title").toString();//标题 + String content = map.get("content").toString();//邮件内容 + String toPeople = map.get("toPeople").toString();//收件人 + String toCc = map.get("toCc").toString();//抄送人 + String toBCc = map.get("toBcc").toString();//暗送人 + String username = map.get("userAddress").toString();//登录邮箱账号 + String password = map.get("userPassword").toString();//密码 + String emailEnclosure = map.get("emailEnclosure").toString(); + String emailId = map.get("emailId").toString(); + List> emailEnclosureList = JSONUtil.toList(emailEnclosure, null); + List> beans = new ArrayList<>(); + Map bean = null; + for (int i = 0; i < emailEnclosureList.size(); i++) { + Map j = emailEnclosureList.get(i); + bean = new HashMap<>(); + bean.put("fileName", j.get("fileName")); + bean.put("filePath", j.get("filePath")); + beans.add(bean); + } + //获取邮件的messageid + Email message = emailService.selectById(emailId); + // 删除之前的草稿件 + if (!ToolUtil.isBlank(message.getMessageId())) { + new MailUtil(username, password, emailServer.get("emailReceiptServer").toString()) + .deleteEmail(username, title, message.getMessageId()); + } + //发送邮件 + String messageId = new MailUtil(username, password, emailServer.get("emailSendServer").toString()) + .send(toPeople, toCc, toBCc, title, content, tPath.replace("images", ""), beans); + if (!ToolUtil.isBlank(messageId)) { + Map emailEditMessageId = new HashMap<>(); + emailEditMessageId.put("id", emailId); + emailEditMessageId.put("messageId", messageId); + emailDao.editEmailMessageIdByEmailId(emailEditMessageId); + } + // 任务完成 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Draft email sending failed, reason is {}.", e); + // 任务失败 + MqSendUtil.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/OutputNotesIsZipConsume.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/OutputNotesIsZipConsume.java new file mode 100644 index 0000000..111f03e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/mq/job/impl/OutputNotesIsZipConsume.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.folder.service.FolderService; +import com.skyeye.eve.note.classenum.FileFolderType; +import com.skyeye.eve.note.dao.NoteDao; +import com.skyeye.eve.note.entity.Note; +import com.skyeye.eve.note.service.NoteService; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import com.youbenzi.md2.export.FileFactory; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.io.FileOutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipOutputStream; + +/** + * @author 卫志强 + * @ClassName: OutputNotesIsZipServiceImpl + * @Description: 笔记输出为压缩包 + * @date 2020年8月23日 + *

+ * RocketMQMessageListener注解参数解释 + * 1. topic:表示需要监听哪个topic的消息 + * 2. consumerGroup:表示消费者组 + * 3. selectorExpression:表示需要监听的tag + */ +@Component +@RocketMQMessageListener( + topic = "${topic.output-notes-is-zip-service}", + consumerGroup = "${topic.output-notes-is-zip-service}", + selectorExpression = "${spring.profiles.active}") +public class OutputNotesIsZipConsume implements RocketMQListener { + + private static Logger LOGGER = LoggerFactory.getLogger(OutputNotesIsZipConsume.class); + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Value("${IMAGES_PATH}") + private String tPath; + + /** + * 系统水印 + */ + @Value("${system.sysWaterMark}") + private String sysWaterMark; + + /** + * 系统地址 + */ + @Value("${webroot.ndc}") + private String webRootNdc; + + @Autowired + private NoteDao noteDao; + + @Autowired + private FolderService folderService; + + @Autowired + private NoteService noteService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + Map mation = new HashMap<>(); + try { + LOGGER.info("start output job, jobId is {}", jobId); + // 任务开始 + this.updateJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + String rowId = map.get("rowId").toString(); + // 类型 + String type = map.get("noteType").toString(); + if (FileFolderType.FOLDER.getKey().equals(type)) { + String zipFile = outputFolder(rowId, map.get("userId").toString()); + mation.put("filePath", zipFile); + } else { + String zipFile = outPutFileContent(rowId, map.get("userId").toString()); + mation.put("filePath", zipFile); + } + + // 任务完成 + this.updateJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, JSONUtil.toJsonStr(mation)); + } catch (Exception e) { + LOGGER.info("job is fail, this message is {}", e); + // 任务失败 + mation.put("message", e); + this.updateJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, JSONUtil.toJsonStr(mation)); + } + } + + private void updateJobMation(String jobId, String status, String responseBody) { + JobMateUpdateMation jobMateUpdateMation = new JobMateUpdateMation(); + jobMateUpdateMation.setJobId(jobId); + jobMateUpdateMation.setStatus(status); + jobMateUpdateMation.setResponseBody(responseBody); + iJobMateMationService.comMQJobMation(jobMateUpdateMation); + } + + /** + * 文件夹(包含文件)输出为压缩包 + * + * @param parentId + * @param userId + * @return + */ + private String outputFolder(String parentId, String userId) { + // 1.获取该目录下的所有目录 + List> folderList = folderService.queryFolderAndChildList(Arrays.asList(parentId)); + // 2.获取所有目录下的所有文件 + List> files = noteDao.queryFileList(folderList, DeleteFlagEnum.NOT_DELETE.getKey()); + // 文件存储基础路径 + String basePath = String.format("%s%s/%s/", tPath, FileConstants.FileUploadPath.getSavePath(FileConstants.FileUploadPath.NOTE.getType()[0]), userId); + FileUtil.createDirs(basePath); + for (Map bean : files) { + String content = bean.containsKey("content") ? bean.get("content").toString() : ""; + bean.put("fileAddress", outPutFileContent(basePath, content, Integer.parseInt(bean.get("type").toString()), userId)); + bean.put("content", ""); + bean.put("fileName", bean.get("name").toString() + ".pdf"); + String[] str = bean.get("parentId").toString().split(","); + bean.put("directParentId", str[str.length - 1]); + bean.put("fileType", bean.get("type")); + } + // 重置父id + for (Map folder : folderList) { + String[] str = folder.get("parentId").toString().split(","); + folder.put("directParentId", str[str.length - 1]); + folder.put("fileName", folder.get("name").toString()); + folder.put("fileType", FileFolderType.FOLDER.getKey()); + } + folderList.addAll(files); + // 将数据转化为树的形式,方便进行父id重新赋值 + folderList = ToolUtil.listToTree(folderList, "id", "directParentId", "children"); + // 打包--压缩包文件名 + String fileName = String.valueOf(System.currentTimeMillis()); + String strZipPath = basePath + fileName + ".zip"; + ZipOutputStream out = null; + try { + out = new ZipOutputStream(new FileOutputStream(strZipPath)); + ToolUtil.recursionZip(out, folderList, "", tPath.replace("images", ""), 2); + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + // 删除临时文件 + for (Map bean : files) { + FileUtil.deleteFile(tPath.replace("images", "") + bean.get("fileAddress").toString()); + } + FileUtil.close(out); + } + return String.format("%s/%s/%s", FileConstants.FileUploadPath.getVisitPath(FileConstants.FileUploadPath.NOTE.getType()[0]), userId, fileName + ".zip"); + } + + /** + * 单个文件输出 + * + * @param basePath 基础路径 + * @param content 内容 + * @param type 类型 + * @param userId 用户id + * @return + */ + private String outPutFileContent(String basePath, String content, int type, String userId) { + String fileName = String.valueOf(System.currentTimeMillis()); + if (ToolUtil.isBlank(content)) { + content = "暂无内容"; + } + switch (type) { + case 1: + // 富文本编辑器 + + break; + case 2: + // markdown笔记 + FileFactory.produce(content, basePath + "/" + fileName + ".pdf", webRootNdc, sysWaterMark); + break; + case 3: + // word笔记 + + break; + case 4: + // ecxel笔记 + + break; + default: + break; + } + return String.format("%s/%s/%s", FileConstants.FileUploadPath.getVisitPath(FileConstants.FileUploadPath.NOTE.getType()[0]), userId, fileName + ".pdf"); + } + + /** + * 单个文件输出 + * + * @param fileId 文件id + * @param userId 用户id + * @return + */ + private String outPutFileContent(String fileId, String userId) { + Note note = noteService.selectById(fileId); + // 文件存储基础路径 + String basePath = String.format("%s%s/%s/", tPath, FileConstants.FileUploadPath.getSavePath(FileConstants.FileUploadPath.NOTE.getType()[0]), userId); + FileUtil.createDirs(basePath); + return outPutFileContent(basePath, note.getContent(), note.getType(), userId); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/AllScheduleMationService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/AllScheduleMationService.java new file mode 100644 index 0000000..b8bdef2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/AllScheduleMationService.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.enumeration.NoticeUserMessageTypeEnum; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.rest.notice.UserMessage; +import com.skyeye.eve.schedule.classenum.ScheduleState; +import com.skyeye.eve.schedule.dao.ScheduleDayDao; +import com.skyeye.eve.schedule.entity.ScheduleDay; +import com.skyeye.eve.schedule.service.ScheduleDayService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.eve.service.IUserNoticeService; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AllScheduleMationService + * @Description: 通知所有人日程提醒 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 15:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class AllScheduleMationService { + + @Autowired + private ScheduleDayDao scheduleDayDao; + + @Autowired + private ScheduleDayService scheduleDayService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private IUserNoticeService iUserNoticeService; + + @XxlJob("allScheduleMationService") + public void call() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String scheduleId = paramMap.get("objectId"); + ScheduleDay scheduleDay = scheduleDayService.selectById(scheduleId); + List> users = scheduleDayDao.queryAllUserAndEmailISNotNull(); + List> userJson = new ArrayList<>(); + for (Map user : users) { + //发送消息 + String content = "尊敬的" + user.get("userName").toString() + ",您好:
《" + scheduleDay.getName() + "》放假时间为:" + scheduleDay.getStartTime() + " ~ " + + scheduleDay.getEndTime() + "
请注意安排好您的工作时间,祝您出行愉快。"; + if (!StrUtil.isBlank(scheduleDay.getRemark())) { + content += "
备注信息:" + scheduleDay.getRemark(); + } + Map uJson = new HashMap<>(); + uJson.put("content", content); + uJson.put("userId", user.get("userId")); + userJson.add(uJson); + //发送邮件 + if (!StrUtil.isBlank(user.get("email").toString()) && user.containsKey("email")) { + Map emailNotice = new HashMap<>(); + emailNotice.put("title", "日程提醒"); + emailNotice.put("content", content); + emailNotice.put("email", user.get("email").toString()); + emailNotice.put("type", MqConstants.JobMateMationJobType.ORDINARY_MAIL_DELIVERY.getJobType()); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(emailNotice)); + jobMateMation.setUserId(paramMap.get("userId")); + iJobMateMationService.sendMQProducer(jobMateMation); + } + } + if (!userJson.isEmpty()) { + insertUserNotice(userJson); + } + // 修改日程状态 + scheduleDayService.editScheduleStateById(scheduleId, ScheduleState.REMINDED_SCHEDULE.getKey()); + iQuartzService.stopAndDeleteTaskQuartz(paramMap.get("objectId")); + } + + private void insertUserNotice(List> userJson) { + // 调用消息系统添加通知 + List userMessageList = new ArrayList<>(); + for (int i = 0; i < userJson.size(); i++) { + Map userJsonObject = userJson.get(i); + UserMessage userMessage = new UserMessage(); + userMessage.setName("日程提醒"); + userMessage.setRemark("您有一条新的日程信息,请及时阅读。"); + userMessage.setContent(userJsonObject.get("content").toString()); + userMessage.setReceiveId(userJsonObject.get("userId").toString()); + userMessage.setType(NoticeUserMessageTypeEnum.SCHEDULE_MESSAGE.getKey()); + userMessage.setCreateUserId(CommonConstants.ADMIN_USER_ID); + userMessageList.add(userMessage); + } + if (!userMessageList.isEmpty()) { + iUserNoticeService.insertUserNoticeMation(userMessageList); + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/HotForumQuartz.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/HotForumQuartz.java new file mode 100644 index 0000000..1e0b944 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/HotForumQuartz.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import com.skyeye.common.util.DateAfterSpacePointTime; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.constans.ForumConstants; +import com.skyeye.eve.forum.dao.ForumContentDao; +import com.skyeye.jedis.JedisClientService; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @ClassName: HotForumQuartz + * @Description: 每天凌晨两点去计算每日热门贴 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 23:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class HotForumQuartz { + + private static Logger log = LoggerFactory.getLogger(HotForumQuartz.class); + + @Autowired + private JedisClientService jedisClient; + + @Autowired + private ForumContentDao forumContentDao; + + /** + * 定时器计算每日热门贴 + */ + @XxlJob("hotForumQuartz") + public void editHotForumMation() { + try { + String yestoday = DateAfterSpacePointTime.getSpecifiedTime( + DateAfterSpacePointTime.ONE_DAY.getType(), DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD, DateAfterSpacePointTime.AroundType.BEFORE); + String everydayBrowseKey = ForumConstants.forumEverydayBrowseIdsByTime(yestoday); + if (!ToolUtil.isBlank(jedisClient.get(everydayBrowseKey))) { + // 获取昨天被浏览过的帖子 + String str = jedisClient.get(everydayBrowseKey); + String[] forumarr = str.split(","); + List> beans = new LinkedList<>(); + List> list = new LinkedList<>(); + for (int i = 0, len = forumarr.length; i < len; i++) { + // 计算一天的浏览量 + String browseNumsKey = ForumConstants.forumBrowseNumsByForumId(forumarr[i]); + String ybrowseNumsKey = ForumConstants.forumYesterdayBrowseNumsByForumId(forumarr[i]); + String bnownum = "0"; + if (!ToolUtil.isBlank(jedisClient.get(browseNumsKey))) { + // 帖子当前的浏览量 + bnownum = jedisClient.get(browseNumsKey); + } + String byestodaynum = "0"; + if (!ToolUtil.isBlank(jedisClient.get(ybrowseNumsKey))) { + // 帖子昨天的浏览量 + byestodaynum = jedisClient.get(ybrowseNumsKey); + } + // 帖子一天的浏览量 + String bnum = String.valueOf(Integer.parseInt(bnownum) - Integer.parseInt(byestodaynum)); + + //计算一天的评论量 + String commentNumsKey = ForumConstants.forumCommentNumsByForumId(forumarr[i]); + String ycommentNumsKey = ForumConstants.forumYesterdayCommentNumsByForumId(forumarr[i]); + String cnownum = "0"; + if (!ToolUtil.isBlank(jedisClient.get(commentNumsKey))) { + // 帖子当前的评论量 + cnownum = jedisClient.get(commentNumsKey); + } + String cyestodaynum = "0"; + if (!ToolUtil.isBlank(jedisClient.get(ycommentNumsKey))) { + // 帖子昨天的评论量 + cyestodaynum = jedisClient.get(ycommentNumsKey); + } + // 帖子一天的评论量 + String cnum = String.valueOf(Integer.parseInt(cnownum) - Integer.parseInt(cyestodaynum)); + + Map map = new HashMap<>(); + map.put("id", ToolUtil.getSurFaceId()); + map.put("forumId", forumarr[i]); + map.put("bnum", bnum); + map.put("cnum", cnum); + map.put("time", yestoday); + list.add(map); + // 更新浏览量 + jedisClient.set(ybrowseNumsKey, bnownum); + // 更新评论量 + jedisClient.set(ycommentNumsKey, cnownum); + + String everyforumEverydayNums = ForumConstants.everyforumEverydayNumsByIdAndTime(forumarr[i], yestoday); + // 将每个帖子每天的浏览量+评论量存入redis中 + jedisClient.set(everyforumEverydayNums, String.valueOf(Integer.parseInt(bnum) + Integer.parseInt(cnum))); + + if (list.size() >= 20) { + // 每20条数据保存一次,将每天被浏览过的帖子存入统计表中 + forumContentDao.insertForumStatisticsDayByList(list); + if (!beans.isEmpty()) { + list.addAll(beans); + beans.clear(); + } + // 根据近七天的浏览量和评论量的算术平均值对list进行排序 + list = sortListByNums(list, yestoday); + // 取前六条放入beans中 + beans.addAll(list.subList(0, 6)); + list.clear(); + } + } + + if (!list.isEmpty()) { + // 将每天被浏览过的帖子存入统计表中 + forumContentDao.insertForumStatisticsDayByList(list); + if (!beans.isEmpty()) { + list.addAll(beans); + beans.clear(); + } + // 根据近七天的浏览量和评论量的算术平均值对list进行排序 + list = sortListByNums(list, yestoday); + int count = list.size(); + int pageMaxSize = 6; + if (count < pageMaxSize) { + pageMaxSize = count; + } + // 取前六条放入beans中 + beans.addAll(list.subList(0, pageMaxSize)); + } + + if (!beans.isEmpty()) { + forumContentDao.insertForumHotByList(beans); + } + } + // 清空每天被浏览过的帖子 + jedisClient.del(everydayBrowseKey); + } catch (Exception e) { + log.warn("editHotForumMation error.", e); + } + } + + /** + * 获取过去7天内的日期数组 + * + * @return 日期数组 + * @throws ParseException + */ + public static ArrayList pastDay(String time) throws ParseException { + ArrayList pastDaysList = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YYYY_MM_DD); + Date date = sdf.parse(time); + for (int i = 6; i >= 0; i--) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - i); + Date today = calendar.getTime(); + String result = sdf.format(today); + pastDaysList.add(result); + } + return pastDaysList; + } + + /** + * 根据近七天的浏览量和评论量的算术平均值对list进行排序 + * + * @return 日期数组 + * @throws ParseException + */ + public List> sortListByNums(List> list, String time) throws ParseException { + // 格式化小数 + DecimalFormat df = new DecimalFormat("0.00"); + for (Map m : list) { + // 获取近七天的日期数组集合 + ArrayList datelist = pastDay(time); + int nums = 0; + for (String date : datelist) { + String everyforumEverydayNum = ForumConstants.everyforumEverydayNumsByIdAndTime(m.get("forumId").toString(), date); + if (!ToolUtil.isBlank(jedisClient.get(everyforumEverydayNum))) { + // 获取每个帖子每天的浏览量+评论量 + nums += Integer.parseInt(jedisClient.get(everyforumEverydayNum)); + } + } + // 将帖子近七天的评论量、浏览量的算术平均值保留两位小数放入map中 + m.put("nums", String.valueOf(df.format((float) nums / 7))); + } + // 按帖子近七天的评论量、浏览量的算术平均值给集合排序 + list.sort(new Comparator>() { + @Override + public int compare(Map m1, Map m2) { + Integer m1num = (int) Float.parseFloat(m1.get("nums").toString()) * 100; + Integer m2num = (int) Float.parseFloat(m2.get("nums").toString()) * 100; + int flag = m1num.compareTo(m2num); + return -flag; // 取反,按倒序排列 + } + }); + return list; + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/MyScheduleDayMationService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/MyScheduleDayMationService.java new file mode 100644 index 0000000..b963d5d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/MyScheduleDayMationService.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.enumeration.NoticeUserMessageTypeEnum; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.rest.notice.UserMessage; +import com.skyeye.eve.schedule.classenum.ScheduleState; +import com.skyeye.eve.schedule.entity.ScheduleDay; +import com.skyeye.eve.schedule.service.ScheduleDayService; +import com.skyeye.eve.service.*; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: MyScheduleDayMationService + * @Description: 我的日程提醒 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 15:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class MyScheduleDayMationService { + + @Autowired + private ScheduleDayService scheduleDayService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private IAuthUserService iAuthUserService; + + @Autowired + private IUserNoticeService iUserNoticeService; + + @XxlJob("myScheduleDayMationService") + public void call() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String userId = paramMap.get("userId"); + String scheduleId = paramMap.get("objectId"); + Map userMation = iAuthUserService.queryDataMationById(userId); + // 获取日程信息 + ScheduleDay scheduleDay = scheduleDayService.selectById(scheduleId); + //发送消息 + String content = "尊敬的" + userMation.get("userName").toString() + ",您好:
您于" + scheduleDay.getCreateTime() + "设定的日程《" + + scheduleDay.getName() + "》即将于" + scheduleDay.getStartTime() + "开始,请做好准备哦。"; + if (!ToolUtil.isBlank(scheduleDay.getRemark())) { + content += "
备注信息:" + scheduleDay.getRemark(); + } + + // 调用消息系统添加通知 + insertUserNotice(userId, content); + + // 发送邮件 + if (!MapUtil.checkKeyIsNull(userMation, "email")) { + Map emailNotice = new HashMap<>(); + emailNotice.put("title", "日程提醒"); + emailNotice.put("content", content); + emailNotice.put("email", userMation.get("email").toString()); + emailNotice.put("type", MqConstants.JobMateMationJobType.ORDINARY_MAIL_DELIVERY.getJobType()); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(emailNotice)); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + // 修改日程状态 + scheduleDayService.editScheduleStateById(scheduleId, ScheduleState.REMINDED_SCHEDULE.getKey()); + iQuartzService.stopAndDeleteTaskQuartz(scheduleId); + } + + private void insertUserNotice(String userId, String content) { + UserMessage userMessage = new UserMessage(); + userMessage.setName("日程提醒"); + userMessage.setRemark("您有一条新的日程信息,请及时阅读。"); + userMessage.setContent(content); + userMessage.setReceiveId(userId); + userMessage.setType(NoticeUserMessageTypeEnum.SCHEDULE_MESSAGE.getKey()); + userMessage.setCreateUserId(CommonConstants.ADMIN_USER_ID); + iUserNoticeService.insertUserNoticeMation(Arrays.asList(userMessage)); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/QuartzNoticeMationService.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/QuartzNoticeMationService.java new file mode 100644 index 0000000..70056df --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/QuartzNoticeMationService.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import cn.hutool.json.JSONUtil; +import com.skyeye.eve.notice.service.NoticeService; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @ClassName: QuartzNoticeMationService + * @Description: 定时上线公告 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 16:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class QuartzNoticeMationService { + + @Autowired + private NoticeService noticeService; + + private static final Logger LOGGER = LoggerFactory.getLogger(QuartzNoticeMationService.class); + + @XxlJob("quartzNoticeMationService") + public void call() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String noticeId = paramMap.get("objectId"); + LOGGER.info("start quartz notice, notice id is: {}", noticeId); + // 上线状态 + noticeService.editNoticeStateToUp(noticeId); + LOGGER.info("end quartz notice, notice id is: {}", noticeId); + } + +} diff --git a/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/TemporaryFileDeleteQuartz.java b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/TemporaryFileDeleteQuartz.java new file mode 100644 index 0000000..d49839b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/java/com/skyeye/xxljob/TemporaryFileDeleteQuartz.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import com.skyeye.common.util.DateUtil; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.File; + +/** + * @ClassName: TemporaryFileDeleteQuartz + * @Description: 定时删除临时的云压缩文件 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/14 11:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class TemporaryFileDeleteQuartz { + + private static Logger log = LoggerFactory.getLogger(TemporaryFileDeleteQuartz.class); + + @Value("${IMAGES_PATH}") + private String tPath; + + private long DAY_MINUTE_TIME = 24 * 60; + + /** + * 定时删除临时的云压缩文件,每天23点执行 + */ + @XxlJob("temporaryFileDeleteQuartz") + public void deleteTemporaryFile() { + log.info("TemporaryFileDeleteQuartz start"); + try { + // 临时文件存储路径 + String basePath = tPath + "\\upload\\fileconsole\\temporaryfile\\"; + File pack = new File(basePath); + if (!pack.isDirectory()) { + // 创建目录 + pack.mkdirs(); + } + // 读取指定路径下的文件名和目录名 + getAllFileByRecursion(pack.listFiles()); + } catch (Exception e) { + log.warn("TemporaryFileDeleteQuartz error.", e); + } + log.info("TemporaryFileDeleteQuartz end"); + } + + public void getAllFileByRecursion(File[] fileList) { + for (int i = 0; i < fileList.length; i++) { + if (fileList[i].isFile()) { + // 如果是文件,获取文件最后的修改时间 + String upTime = DateUtil.getDateStr(fileList[i].lastModified()); + // 获取当前时间和文件最后修改时间的时间差(多少分钟) + long time = DateUtil.getDistanceMinute(upTime, DateUtil.getTimeAndToString()); + if (time > DAY_MINUTE_TIME) { + fileList[i].delete(); + } + } else { + //如果是文件夹 + getAllFileByRecursion(fileList[i].listFiles()); + } + } + } + +} diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesMapper.xml new file mode 100644 index 0000000..0a4eeed --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesPurchaseMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesPurchaseMapper.xml new file mode 100644 index 0000000..5e1ccc2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesPurchaseMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesUseMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesUseMapper.xml new file mode 100644 index 0000000..e05f6c5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/articles/ArticlesUseMapper.xml @@ -0,0 +1,58 @@ + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileCatalogMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileCatalogMapper.xml new file mode 100644 index 0000000..cbff7ca --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileCatalogMapper.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileConsoleMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileConsoleMapper.xml new file mode 100644 index 0000000..7d8dcc7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileConsoleMapper.xml @@ -0,0 +1,258 @@ + + + + + + + + + + + + insert into file_catalog + (id, `name`, parent_id, delete_flag, source_id, create_id, create_time, last_update_id ,last_update_time) + values + + (#{item.newId}, #{item.name}, #{item.newParentId}, #{item.deleteFlag}, #{item.id}, #{item.createId}, #{item.createTime}, #{item.createId}, #{item.createTime}) + + + + + insert into file_catelog_papers + (id, `name`, thumbnail, address, type, size, size_type, chunk, chunk_size, parent_id, delete_flag, source_id, create_id, create_time, last_update_id, last_update_time) + values + + (#{item.newId}, #{item.name}, #{item.thumbnail}, #{item.address}, #{item.type}, #{item.size}, #{item.sizeType}, #{item.chunk}, #{item.chunkSize}, + #{item.newParentId}, #{item.deleteFlag}, #{item.id}, #{item.createId}, #{item.createTime}, #{item.createId}, #{item.createTime}) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileRecycleBinMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileRecycleBinMapper.xml new file mode 100644 index 0000000..494d2d7 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileRecycleBinMapper.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileShareMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileShareMapper.xml new file mode 100644 index 0000000..b37784a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/diskcloud/FileShareMapper.xml @@ -0,0 +1,94 @@ + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailMapper.xml new file mode 100644 index 0000000..bd93de5 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + insert into email_mail + (id, title, send_date, replay_sign, is_new, is_contain_attach, from_people, to_people, to_cc, to_bcc, message_id, content, create_time, state) + values + + (#{item.id}, #{item.title}, #{item.sendDate}, #{item.replaySign}, #{item.isNew}, #{item.isContainAttach}, #{item.fromPeople}, #{item.toPeople}, #{item.toCc}, + #{item.toBcc}, #{item.messageId}, #{item.content}, #{item.createTime}, #{item.emailState}) + + + + + insert into email_enclosure + (id, file_name, file_ext_name, file_path, file_size, parent_id) + values + + (#{item.id}, #{item.fileName}, #{item.fileExtName}, #{item.filePath}, #{item.fileSize}, #{item.parentId}) + + + + + UPDATE email_mail + + + message_id = #{messageId}, + + + WHERE id = #{id} + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailSendModelMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailSendModelMapper.xml new file mode 100644 index 0000000..4462ce2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/email/EmailSendModelMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/folder/FolderMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/folder/FolderMapper.xml new file mode 100644 index 0000000..95e309a --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/folder/FolderMapper.xml @@ -0,0 +1,56 @@ + + + + + + + + + + insert into note_folder + (id, `name`, parent_id, delete_flag, create_id, create_time, last_update_id, last_update_time) + values + + (#{item.newId}, #{item.name}, #{item.newParentId}, #{item.deleteFlag}, #{item.createId}, #{item.createTime}, #{item.lastUpdateId}, #{item.lastUpdateTime}) + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumContentMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumContentMapper.xml new file mode 100644 index 0000000..fb9b136 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumContentMapper.xml @@ -0,0 +1,452 @@ + + + + + + + + INSERT into forum_content + (id, forum_content, type, state, report_state, tag_id, forum_title, forum_desc, anonymous, create_id, create_time) + VALUES(#{id}, #{content}, #{forumType}, #{state}, #{reportState}, #{tagId}, #{title}, #{desc}, #{anonymous}, #{createId}, #{createTime}) + + + + UPDATE forum_content + + state = 2 + + WHERE id = #{id} + + + + + + UPDATE forum_content + + + forum_title = #{title}, + + + tag_id = #{tagId}, + + + forum_content = #{content}, + + + anonymous = #{anonymous}, + + + type = #{forumType}, + + + forum_desc = #{desc}, + + + WHERE id = #{id} + + + + + + + + INSERT into forum_comment + (id, forum_id, content, comment_id, belong_comment_id, reply_id, comment_time) + VALUES(#{id}, #{forumId}, #{content}, #{commentId}, #{belongCommentId}, #{replyId}, #{commentTime}) + + + + INSERT into forum_comment + (id, forum_id, content, comment_id, belong_comment_id, reply_id, comment_time) + VALUES(#{id}, #{forumId}, #{content}, #{commentId}, #{belongCommentId}, #{replyId}, #{commentTime}) + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE + FROM + forum_comment + where id = #{id} OR belong_comment_id = #{id} + + + + + + DELETE + FROM + forum_notice + where id = #{id} + + + + insert into forum_hot + (id, forum_id, update_time) + values + + (#{item.id}, #{item.forumId}, #{item.time}) + + + + + insert into forum_statistics_day + (id, forum_id, browse_num, comment_num, create_time) + values + + (#{item.id}, #{item.forumId}, #{item.bnum}, #{item.cnum}, #{item.time}) + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumReportMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumReportMapper.xml new file mode 100644 index 0000000..f503f1b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumReportMapper.xml @@ -0,0 +1,139 @@ + + + + + + INSERT into forum_report + (id, forum_id, report_type_id, report_other_content, report_desc, examine_state, report_id, report_time) + VALUES(#{id}, #{forumId}, #{reportType}, #{reportContent}, #{reportDesc}, #{examineState}, #{reportId}, #{reportTime}) + + + + + + UPDATE forum_report + + + examine_id = #{examineId}, + + + examine_time = #{examineTime}, + + + examine_state = #{examineState}, + + examine_nopass_reason = #{examineNopassReason}, + + WHERE id = #{id} + + + + + + + + + + + + INSERT into forum_notice + (id, forum_id, notice_title, notice_content, receive_id, type, state, create_time) + VALUES(#{id}, #{forumId}, #{noticeTitle}, #{noticeContent}, #{receiveId}, #{type}, #{state}, #{createTime}) + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumSensitiveWordsMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumSensitiveWordsMapper.xml new file mode 100644 index 0000000..78f1939 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumSensitiveWordsMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + INSERT into forum_sensitive_words + (id, sensitive_word, create_id, create_time) + VALUES(#{id}, #{sensitiveWord}, #{createId}, #{createTime}) + + + + DELETE + FROM + forum_sensitive_words + WHERE + id = #{id} + + + + + + UPDATE forum_sensitive_words + + sensitive_word = #{sensitiveWord} + + WHERE id = #{id} + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumTagMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumTagMapper.xml new file mode 100644 index 0000000..b8a2955 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/forum/ForumTagMapper.xml @@ -0,0 +1,154 @@ + + + + + + + + + + INSERT into forum_tag + (id, tag_name, order_by, state, create_id, create_time) + VALUES(#{id}, #{tagName}, #{orderBy}, #{state}, #{createId}, #{createTime}) + + + + + + UPDATE forum_tag + + state = 4 + + WHERE id = #{id} + + + + UPDATE forum_tag + + state = 2 + + WHERE id = #{id} + + + + + + UPDATE forum_tag + + state = 3 + + WHERE id = #{id} + + + + + + UPDATE forum_tag + + tag_name = #{tagName} + + WHERE id = #{id} + + + + + + UPDATE forum_tag + + order_by = #{upOrderBy}, + + WHERE id = #{id} + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwModelMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwModelMapper.xml new file mode 100644 index 0000000..925ff19 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwModelMapper.xml @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwReceiveTemplatesMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwReceiveTemplatesMapper.xml new file mode 100644 index 0000000..1b73cce --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwReceiveTemplatesMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwSendTemplatesMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwSendTemplatesMapper.xml new file mode 100644 index 0000000..6dc3278 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwSendTemplatesMapper.xml @@ -0,0 +1,59 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwTemplatesMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwTemplatesMapper.xml new file mode 100644 index 0000000..c0eb073 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/gw/GwTemplatesMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/jobdiary/JobDiaryMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/jobdiary/JobDiaryMapper.xml new file mode 100644 index 0000000..fa599e2 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/jobdiary/JobDiaryMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/knowledge/KnowledgeContentMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/knowledge/KnowledgeContentMapper.xml new file mode 100644 index 0000000..91b99fe --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/knowledge/KnowledgeContentMapper.xml @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceMapper.xml new file mode 100644 index 0000000..36f04c3 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceMapper.xml @@ -0,0 +1,38 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceRevertMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceRevertMapper.xml new file mode 100644 index 0000000..47f4d75 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceRevertMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceUseMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceUseMapper.xml new file mode 100644 index 0000000..29d1b05 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/licence/LicenceUseMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppMapper.xml new file mode 100644 index 0000000..1938216 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppTypeMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppTypeMapper.xml new file mode 100644 index 0000000..ddcebb4 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/lightapp/LightAppTypeMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/mail/MailTypeMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/mail/MailTypeMapper.xml new file mode 100644 index 0000000..b2f822f --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/mail/MailTypeMapper.xml @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/message/NoticeMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/message/NoticeMapper.xml new file mode 100644 index 0000000..a0304c1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/message/NoticeMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/message/UserMessageMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/message/UserMessageMapper.xml new file mode 100644 index 0000000..2fd3a62 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/message/UserMessageMapper.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/note/NoteMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/note/NoteMapper.xml new file mode 100644 index 0000000..ec04c36 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/note/NoteMapper.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + insert into note_content + (id, `name`, icon_logo, remark, content, type, parent_id, delete_flag, create_id, create_time, last_update_id, last_update_time) + values + + (#{item.newId}, #{item.name}, #{item.iconLogo}, #{item.remark}, #{item.content}, #{item.type}, + #{item.newParentId}, #{item.deleteFlag}, #{item.createId}, #{item.createTime}, #{item.lastUpdateId}, #{item.lastUpdateTime}) + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectFlowMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectFlowMapper.xml new file mode 100644 index 0000000..03556a8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectFlowMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + INSERT into plan_project_flow + (id, project_id, title, p_id, type, json_content, is_share, create_id, create_time) + VALUES + (#{id}, #{projectId}, #{title}, #{pId}, #{type}, #{jsonContent}, #{isShare}, #{createId}, #{createTime}) + + + + + + DELETE + FROM + plan_project_flow + WHERE + id = #{id} + + + + + + + + UPDATE plan_project_flow + + + title = #{title}, + + + is_share = #{isShare}, + + + json_content = #{jsonContent}, + + + WHERE id = #{id} + + + + + + UPDATE plan_project_flow + + + json_content = #{jsonContent}, + + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectMapper.xml new file mode 100644 index 0000000..d0e4f57 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/planpro/PlanProjectMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + INSERT into plan_project + (id, project_name, project_desc, is_share, create_id, create_time, last_update_id, last_update_time) + VALUES + (#{id}, #{projectName}, #{projectDesc}, #{isShare}, #{createId}, #{createTime}, #{createId}, #{createTime}) + + + + DELETE + FROM + plan_project + WHERE + id = #{id} + + + + + + UPDATE plan_project + + project_name = #{projectName}, + project_desc = #{projectDesc}, + + is_share = #{isShare}, + + last_update_id = #{lastUpdateId}, + last_update_time = #{lastUpdateTime} + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/schedule/ScheduleDayMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/schedule/ScheduleDayMapper.xml new file mode 100644 index 0000000..602f51e --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/schedule/ScheduleDayMapper.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyBorrowMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyBorrowMapper.xml new file mode 100644 index 0000000..b92124b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyBorrowMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyRevertMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyRevertMapper.xml new file mode 100644 index 0000000..b0ea176 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealApplyRevertMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealMapper.xml new file mode 100644 index 0000000..4c5d020 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/seal/SealMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/AccidentMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/AccidentMapper.xml new file mode 100644 index 0000000..a7baa76 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/AccidentMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InspectionMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InspectionMapper.xml new file mode 100644 index 0000000..e80e9c8 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InspectionMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InsuranceMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InsuranceMapper.xml new file mode 100644 index 0000000..c6fdede --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/InsuranceMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/MaintenanceMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/MaintenanceMapper.xml new file mode 100644 index 0000000..1812319 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/MaintenanceMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/OilingMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/OilingMapper.xml new file mode 100644 index 0000000..6422c7d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/OilingMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleApplyUseMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleApplyUseMapper.xml new file mode 100644 index 0000000..cc1e8a1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleApplyUseMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleMapper.xml b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleMapper.xml new file mode 100644 index 0000000..8b68fb1 --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/mapper/vehicle/VehicleMapper.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/forum.xml b/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/forum.xml new file mode 100644 index 0000000..0cbb48d --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/forum.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/planpro.xml b/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/planpro.xml new file mode 100644 index 0000000..3164c5b --- /dev/null +++ b/skyeye-adm/adm-pro/src/main/resources/reqmapping/mapping/planpro.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-survey/.gitignore b/skyeye-adm/adm-survey/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-adm/adm-survey/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-adm/adm-survey/pom.xml b/skyeye-adm/adm-survey/pom.xml new file mode 100644 index 0000000..50dcaa3 --- /dev/null +++ b/skyeye-adm/adm-survey/pom.xml @@ -0,0 +1,30 @@ + + + + skyeye-adm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + adm-survey + + + 8 + 8 + UTF-8 + + + + + + com.skyeye + adm-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/controller/DwQuCheckboxController.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/controller/DwQuCheckboxController.java new file mode 100644 index 0000000..bf617e6 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/controller/DwQuCheckboxController.java @@ -0,0 +1,4 @@ +package com.skyeye.eve.checkbox.controller; + +public class DwQuCheckboxController { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwAnCheckboxDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwAnCheckboxDao.java new file mode 100644 index 0000000..e607817 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwAnCheckboxDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.checkbox.dao; + +import com.skyeye.eve.checkbox.entity.DwAnCheckbox; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwAnCheckboxDao + * @Description: 答卷多选题保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnCheckboxDao extends SkyeyeBaseMapper { + +} + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwQuCheckboxDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwQuCheckboxDao.java new file mode 100644 index 0000000..d897c16 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/dao/DwQuCheckboxDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.checkbox.dao; + +import com.skyeye.eve.checkbox.entity.DwQuCheckbox; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwQuCheckboxDao + * @Description: 多选题选项交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuCheckboxDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwAnCheckbox.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwAnCheckbox.java new file mode 100644 index 0000000..90ade8c --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwAnCheckbox.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.checkbox.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwAnCheckbox + * @Description: 答卷多选题保存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_an_checkbox") +@ApiModel(value = "答卷多选题保存实体类") +public class DwAnCheckbox extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " ") + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("qu_item_id") + @ApiModelProperty(value = " " ) + private String quItemId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwQuCheckbox.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwQuCheckbox.java new file mode 100644 index 0000000..9a0cd17 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/entity/DwQuCheckbox.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.checkbox.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwQuCheckbox + * @Description: 多选题选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_qu_checkbox") +@ApiModel(value = "多选题选项实体类") +public class DwQuCheckbox extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("option_title") + @ApiModelProperty(value = "选项标题") + private String optionTitle; + + @TableField("check_type") + @ApiModelProperty(value = "说明的验证方式") + private Integer checkType; + + @TableField("is_note") + @ApiModelProperty(value = "是否带说明 0否 1是", required = "required") + private Integer isNote; + + @TableField("is_required_fill") + @ApiModelProperty(value = "说明内容是否必填 0否 1是", required = "required") + private Integer isRequiredFill; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwAnCheckboxService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwAnCheckboxService.java new file mode 100644 index 0000000..7f3eef6 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwAnCheckboxService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.checkbox.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.checkbox.entity.DwAnCheckbox; + +/** + * @ClassName: DwAnCheckboxService + * @Description: 答卷多选题保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnCheckboxService extends SkyeyeBusinessService { + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwQuCheckboxService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwQuCheckboxService.java new file mode 100644 index 0000000..5778faa --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/DwQuCheckboxService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.checkbox.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.checkbox.entity.DwQuCheckbox; + +/** + * @ClassName: DwQuCheckboxService + * @Description: 多选题选项接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuCheckboxService extends SkyeyeBusinessService { + +} + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwAnCheckboxServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwAnCheckboxServiceImpl.java new file mode 100644 index 0000000..f074cec --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwAnCheckboxServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.checkbox.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.checkbox.dao.DwAnCheckboxDao; +import com.skyeye.eve.checkbox.entity.DwAnCheckbox; +import com.skyeye.eve.checkbox.service.DwAnCheckboxService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnCheckboxServiceImpl + * @Description: 答卷多选题保存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷多选题保存", groupName = "答卷多选题保存", manageShow = false) +public class DwAnCheckboxServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnCheckboxService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwQuCheckboxServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwQuCheckboxServiceImpl.java new file mode 100644 index 0000000..b7a4395 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/checkbox/service/impl/DwQuCheckboxServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.checkbox.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.checkbox.dao.DwQuCheckboxDao; +import com.skyeye.eve.checkbox.entity.DwQuCheckbox; +import com.skyeye.eve.checkbox.service.DwQuCheckboxService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuCheckboxServiceImpl + * @Description: 多选题选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷单选题选项", groupName = "答卷单选题选项", manageShow = false) +public class DwQuCheckboxServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuCheckboxService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenCheckboxDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenCheckboxDao.java new file mode 100644 index 0000000..3b90d73 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenCheckboxDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwAnChenCheckbox; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwQuCheckboxDao + * @Description: 答卷矩阵多选题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenCheckboxDao extends SkyeyeBaseMapper { + +} + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenFbkDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenFbkDao.java new file mode 100644 index 0000000..ca6d206 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenFbkDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + + +import com.skyeye.eve.chen.entity.DwAnChenFbk; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwAnChenFbkDao + * @Description: 答卷矩阵填空题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenFbkDao extends SkyeyeBaseMapper { + +} + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenRadioDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenRadioDao.java new file mode 100644 index 0000000..f524964 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenRadioDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwAnChenRadio; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwAnChenRadioDao + * @Description: 答卷矩阵单选题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenRadioDao extends SkyeyeBaseMapper { + +} + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenScoreDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenScoreDao.java new file mode 100644 index 0000000..4fe3b8a --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnChenScoreDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwAnChenScore; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwAnChenScoreDao + * @Description: 答卷矩阵评分题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenScoreDao extends SkyeyeBaseMapper { + +} + + + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnCompChenRadioDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnCompChenRadioDao.java new file mode 100644 index 0000000..6d14648 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwAnCompChenRadioDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwAnCompChenRadio; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwAnCompChenRadioDao + * @Description: 答卷复合矩阵单选题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnCompChenRadioDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenColumnDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenColumnDao.java new file mode 100644 index 0000000..c5f01e7 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenColumnDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwQuChenColumn; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwQuChenColumnDao + * @Description: 矩陈题列选项交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenColumnDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenOptionDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenOptionDao.java new file mode 100644 index 0000000..eed3b11 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenOptionDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwQuChenOption; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwQuChenColumnDao + * @Description: 矩陈题列选项交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenOptionDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenRowDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenRowDao.java new file mode 100644 index 0000000..3644745 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/dao/DwQuChenRowDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.dao; + +import com.skyeye.eve.chen.entity.DwQuChenRow; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + + +/** + * @ClassName: DwQuChenRowDao + * @Description: 矩陈题行选项交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenRowDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenCheckbox.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenCheckbox.java new file mode 100644 index 0000000..4513c93 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenCheckbox.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnChenCheckbox + * @Description: 答卷矩阵多选题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_chen_checkbox") +@ApiModel(value = "答卷矩阵多选题实体类") +public class DwAnChenCheckbox extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_col_id") + @ApiModelProperty(value = " " ) + private String quColId; + + @TableField("qu_row_id") + @ApiModelProperty(value = " " ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenFbk.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenFbk.java new file mode 100644 index 0000000..e77697d --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenFbk.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnChenFbk + * @Description: 答卷矩阵填空题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_chen_fbk") +@ApiModel(value = "答卷矩阵填空题实体类") +public class DwAnChenFbk extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer_value") + @ApiModelProperty(value = " " ) + private String answerValue; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_col_id") + @ApiModelProperty(value = " " ) + private String quColId; + + @TableField("qu_row_id") + @ApiModelProperty(value = " " ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenRadio.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenRadio.java new file mode 100644 index 0000000..50ea05f --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenRadio.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnChenRadio + * @Description: 答卷矩阵单选题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_chen_radio") +@ApiModel(value = "答卷矩阵单选题实体类") +public class DwAnChenRadio extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_col_id") + @ApiModelProperty(value = " " ) + private String quColId; + + @TableField("qu_row_id") + @ApiModelProperty(value = " " ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenScore.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenScore.java new file mode 100644 index 0000000..c1c43d5 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnChenScore.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnChenScore + * @Description: 答卷矩阵评分题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_chen_score") +@ApiModel(value = "答卷矩阵评分题实体类") +public class DwAnChenScore extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("answer_score") + @ApiModelProperty(value = " " ) + private String answer_score; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_col_id") + @ApiModelProperty(value = " " ) + private String quColId; + + @TableField("qu_row_id") + @ApiModelProperty(value = " " ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnCompChenRadio.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnCompChenRadio.java new file mode 100644 index 0000000..31949dc --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwAnCompChenRadio.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnCompChenRadio + * @Description: 答卷复合矩阵单选题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_comp_chen_radio") +@ApiModel(value = "答卷复合矩阵单选题实体类") +public class DwAnCompChenRadio extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("qu_option_id") + @ApiModelProperty(value = " " ) + private String quOptionId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_col_id") + @ApiModelProperty(value = " " ) + private String quColId; + + @TableField("qu_row_id") + @ApiModelProperty(value = " " ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenColumn.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenColumn.java new file mode 100644 index 0000000..38e4ef5 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenColumn.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuChenColumn + * @Description: 矩陈题列选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_qu_chen_column") +@ApiModel(value = "矩陈题列选项实体类") +public class DwQuChenColumn extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenOption.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenOption.java new file mode 100644 index 0000000..2ae7bb9 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenOption.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuChenOption + * @Description: 矩陈题题选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_qu_chen_option") +@ApiModel(value = "矩陈题题选项实体类") +public class DwQuChenOption extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenRow.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenRow.java new file mode 100644 index 0000000..538019a --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/entity/DwQuChenRow.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.chen.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuChenRow + * @Description: 矩陈题行选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_qu_chen_row") +@ApiModel(value = "矩陈题行选项实体类") +public class DwQuChenRow extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenCheckboxService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenCheckboxService.java new file mode 100644 index 0000000..b917e7e --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenCheckboxService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwAnChenCheckbox; + +/** + * @ClassName: DwAnChenCheckboxService + * @Description: 答卷单选题保存表接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenCheckboxService extends SkyeyeBusinessService { + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenFbkService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenFbkService.java new file mode 100644 index 0000000..bba2574 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenFbkService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwAnChenFbk; + +/** + * @ClassName: DwAnChenFbkService + * @Description: 答卷矩阵填空题接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenFbkService extends SkyeyeBusinessService { + + +} + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenRadioService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenRadioService.java new file mode 100644 index 0000000..19ef44e --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenRadioService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwAnChenRadio; + +/** + * @ClassName: DwAnChenRadioService + * @Description: 答卷矩阵单选题接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenRadioService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenScoreService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenScoreService.java new file mode 100644 index 0000000..ce5b77a --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnChenScoreService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwAnChenScore; + +/** + * @ClassName: DwAnChenScoreService + * @Description: 答卷矩阵评分题接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnChenScoreService extends SkyeyeBusinessService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnCompChenRadioService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnCompChenRadioService.java new file mode 100644 index 0000000..8a02d7c --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwAnCompChenRadioService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwAnCompChenRadio; + +/** + * @ClassName: DwAnCompChenRadioService + * @Description: 答卷复合矩阵单选题接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnCompChenRadioService extends SkyeyeBusinessService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenColumnService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenColumnService.java new file mode 100644 index 0000000..de41efb --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenColumnService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwQuChenColumn; + +/** + * @ClassName: DwQuChenColumnService + * @Description: 矩陈题列选项接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenColumnService extends SkyeyeBusinessService{ +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenOptionService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenOptionService.java new file mode 100644 index 0000000..1c48dd3 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenOptionService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwQuChenOption; + +/** + * @ClassName: DwQuChenOptionService + * @Description: 矩陈题题选项接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenOptionService extends SkyeyeBusinessService{ +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenRowService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenRowService.java new file mode 100644 index 0000000..a2ff110 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/DwQuChenRowService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.chen.entity.DwQuChenRow; + +/** + * @ClassName: DwQuChenRowService + * @Description: 矩陈题行选项接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuChenRowService extends SkyeyeBusinessService{ +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenCheckboxServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenCheckboxServiceImpl.java new file mode 100644 index 0000000..56c9631 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenCheckboxServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnChenCheckboxDao; +import com.skyeye.eve.chen.entity.DwAnChenCheckbox; +import com.skyeye.eve.chen.service.DwAnChenCheckboxService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnCheckboxServiceImpl + * @Description: 答卷矩阵多选题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷矩阵多选题", groupName = "答卷矩阵多选题", manageShow = false) +public class DwAnChenCheckboxServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnChenCheckboxService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenFbkServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenFbkServiceImpl.java new file mode 100644 index 0000000..89f49cd --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenFbkServiceImpl.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnChenFbkDao; +import com.skyeye.eve.chen.entity.DwAnChenFbk; +import com.skyeye.eve.chen.service.DwAnChenFbkService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnChenFbkServiceImpl + * @Description: 答卷矩阵填空题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷矩阵填空题", groupName = "答卷矩阵填空题", manageShow = false) +public class DwAnChenFbkServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnChenFbkService { + +} + + + + + + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenRadioServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenRadioServiceImpl.java new file mode 100644 index 0000000..7ad62e0 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenRadioServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnChenRadioDao; +import com.skyeye.eve.chen.entity.DwAnChenRadio; +import com.skyeye.eve.chen.service.DwAnChenRadioService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnChenRadioServiceImpl + * @Description: 答卷矩阵单选题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷矩阵单选题", groupName = "答卷矩阵单选题", manageShow = false) +public class DwAnChenRadioServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnChenRadioService { + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenScoreServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenScoreServiceImpl.java new file mode 100644 index 0000000..b374730 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnChenScoreServiceImpl.java @@ -0,0 +1,24 @@ +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnChenScoreDao; +import com.skyeye.eve.chen.entity.DwAnChenScore; +import com.skyeye.eve.chen.service.DwAnChenScoreService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnChenScoreServiceImpl + * @Description: 答卷矩阵评分题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ + +@Service +@SkyeyeService(name = "答卷矩阵评分题", groupName = "答卷矩阵评分题", manageShow = false) +public class DwAnChenScoreServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnChenScoreService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnCompChenRadioServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnCompChenRadioServiceImpl.java new file mode 100644 index 0000000..25b1973 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwAnCompChenRadioServiceImpl.java @@ -0,0 +1,21 @@ +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnCompChenRadioDao; +import com.skyeye.eve.chen.entity.DwAnCompChenRadio; +import com.skyeye.eve.chen.service.DwAnCompChenRadioService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnCompChenRadioServiceImpl + * @Description: 答卷复合矩阵单选题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷复合矩阵单选题", groupName = "答卷复合矩阵单选题", manageShow = false) +public class DwAnCompChenRadioServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnCompChenRadioService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenColumnServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenColumnServiceImpl.java new file mode 100644 index 0000000..08eca1b --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenColumnServiceImpl.java @@ -0,0 +1,21 @@ +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwQuChenColumnDao; +import com.skyeye.eve.chen.entity.DwQuChenColumn; +import com.skyeye.eve.chen.service.DwQuChenColumnService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnCompChenRadioServiceImpl + * @Description: 矩陈题列选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "矩陈题列选项", groupName = "矩陈题列选项", manageShow = false) +public class DwQuChenColumnServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuChenColumnService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenOptionServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenOptionServiceImpl.java new file mode 100644 index 0000000..9412527 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenOptionServiceImpl.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwQuChenOptionDao; +import com.skyeye.eve.chen.entity.DwQuChenOption; +import com.skyeye.eve.chen.service.DwQuChenOptionService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuChenOptionServiceImpl + * @Description: 矩陈题题选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷矩阵单选题", groupName = "答卷矩阵单选题", manageShow = false) +public class DwQuChenOptionServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuChenOptionService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenRowServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenRowServiceImpl.java new file mode 100644 index 0000000..4fc77e9 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/chen/service/impl/DwQuChenRowServiceImpl.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.chen.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwQuChenRowDao; +import com.skyeye.eve.chen.entity.DwQuChenRow; +import com.skyeye.eve.chen.service.DwQuChenRowService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuChenRowServiceImpl + * @Description: 矩陈题行选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "矩陈题行选项", groupName = "矩陈题行选项", manageShow = false) +public class DwQuChenRowServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuChenRowService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/controller/DwSurveyDirectoryController.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/controller/DwSurveyDirectoryController.java new file mode 100644 index 0000000..8ff9276 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/controller/DwSurveyDirectoryController.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.DwSurveyDirectoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DwSurveyDirectoryController { + + @Autowired + private DwSurveyDirectoryService dwSurveyDirectoryService; + + /** + * 获取调查问卷列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/queryDwSurveyDirectoryList") + public void queryDwSurveyDirectoryList(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.queryDwSurveyDirectoryList(inputObject, outputObject); + } + + /** + * 新增调查问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/insertDwSurveyDirectoryMation") + public void insertDwSurveyDirectoryMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.insertDwSurveyDirectoryMation(inputObject, outputObject); + } + + /** + * 获取调查问卷题目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/queryDwSurveyDirectoryMationById") + public void queryDwSurveyDirectoryMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.queryDwSurveyDirectoryMationById(inputObject, outputObject); + } + + /** + * 获取调查问卷信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/queryDwSurveyMationById") + public void queryDwSurveyMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.queryDwSurveyMationById(inputObject, outputObject); + } + + /** + * 编辑调查问卷信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/editDwSurveyMationById") + public void editDwSurveyMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.editDwSurveyMationById(inputObject, outputObject); + } + + /** + * 添加填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuFillblankMation") + public void addQuFillblankMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuFillblankMation(inputObject, outputObject); + } + + /** + * 添加评分题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuScoreMation") + public void addQuScoreMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuScoreMation(inputObject, outputObject); + } + + /** + * 添加排序题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuOrderquMation") + public void addQuOrderquMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuOrderquMation(inputObject, outputObject); + } + + /** + * 添加分页标记 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuPagetagMation") + public void addQuPagetagMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuPagetagMation(inputObject, outputObject); + } + + /** + * 添加单选题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuRadioMation") + public void addQuRadioMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuRadioMation(inputObject, outputObject); + } + + /** + * 添加多选题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuCheckBoxMation") + public void addQuCheckBoxMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuCheckBoxMation(inputObject, outputObject); + } + + /** + * 添加多选填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuMultiFillblankMation") + public void addQuMultiFillblankMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuMultiFillblankMation(inputObject, outputObject); + } + + /** + * 添加段落题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuParagraphMation") + public void addQuParagraphMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuParagraphMation(inputObject, outputObject); + } + + /** + * 添加矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/addQuChenMation") + public void addQuChenMation(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.addQuChenMation(inputObject, outputObject); + } + + /** + * 删除问题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionMationById") + public void deleteQuestionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionMationById(inputObject, outputObject); + } + + /** + * 删除矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题列选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionChenColumnMationById") + public void deleteQuestionChenColumnMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionChenColumnMationById(inputObject, outputObject); + } + + /** + * 删除矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题行选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionChenRowMationById") + public void deleteQuestionChenRowMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionChenRowMationById(inputObject, outputObject); + } + + /** + * 删除单选题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionRadioOptionMationById") + public void deleteQuestionRadioOptionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionRadioOptionMationById(inputObject, outputObject); + } + + /** + * 删除多选题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionChedkBoxOptionMationById") + public void deleteQuestionChedkBoxOptionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionChedkBoxOptionMationById(inputObject, outputObject); + } + + /** + * 删除评分题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionScoreOptionMationById") + public void deleteQuestionScoreOptionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionScoreOptionMationById(inputObject, outputObject); + } + + /** + * 删除排序选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionOrderOptionMationById") + public void deleteQuestionOrderOptionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionOrderOptionMationById(inputObject, outputObject); + } + + /** + * 删除多项填空题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteQuestionMultiFillblankOptionMationById") + public void deleteQuestionMultiFillblankOptionMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteQuestionMultiFillblankOptionMationById(inputObject, outputObject); + } + + /** + * 问卷发布 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/editSurveyStateToReleaseById") + public void editSurveyStateToReleaseById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.editSurveyStateToReleaseById(inputObject, outputObject); + } + + /** + * 获取调查问卷题目信息用来生成html页面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/queryDwSurveyDirectoryMationByIdToHTML") + public void queryDwSurveyDirectoryMationByIdToHTML(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.queryDwSurveyDirectoryMationByIdToHTML(inputObject, outputObject); + } + + /** + * 删除问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/deleteSurveyMationById") + public void deleteSurveyMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.deleteSurveyMationById(inputObject, outputObject); + } + + /** + * 分析报告问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/querySurveyFxMationById") + public void querySurveyFxMationById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.querySurveyFxMationById(inputObject, outputObject); + } + + /** + * 复制问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/insertSurveyMationCopyById") + public void insertSurveyMationCopyById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.insertSurveyMationCopyById(inputObject, outputObject); + } + + /** + * 判断该ip的用户是否回答过此问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/queryAnswerSurveyMationByIp") + public void queryAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.queryAnswerSurveyMationByIp(inputObject, outputObject); + } + + /** + * 用户回答问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/insertAnswerSurveyMationByIp") + public void insertAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.insertAnswerSurveyMationByIp(inputObject, outputObject); + } + + /** + * 手动结束问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/DwSurveyDirectoryController/updateSurveyMationEndById") + public void updateSurveyMationEndById(InputObject inputObject, OutputObject outputObject) { + dwSurveyDirectoryService.updateSurveyMationEndById(inputObject, outputObject); + } + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/dao/DwSurveyDirectoryDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/dao/DwSurveyDirectoryDao.java new file mode 100644 index 0000000..eee4531 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/dao/DwSurveyDirectoryDao.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface DwSurveyDirectoryDao { + + List> queryDwSurveyDirectoryList(Map map); + + int insertDwSurveyDirectoryMation(Map map); + + List> queryQuestionListByBelongId(Map map); + + List> queryQuestionLogicListByQuestionId(Map question); + + List> queryQuestionChenRowListByQuestionId(Map question); + + List> queryQuestionChenColumnListByQuestionId(Map question); + + List> queryQuestionMultiFillBlankListByQuestionId(Map question); + + List> queryQuestionRadioListByQuestionId(Map question); + + List> queryQuestionCheckBoxListByQuestionId(Map question); + + List> queryQuestionChenOptionListByQuestionId(Map question); + + List> queryQuestionScoreListByQuestionId(Map question); + + List> queryQuestionOrderByListByQuestionId(Map question); + + List> queryChildQuestionListByBelongId(Map question); + + Map querySurveyMationById(@Param("id") String id); + + int editDwSurveyMationById(Map map); + + int addQuestionMation(Map map); + + int addQuestionLogicsMationList(List> quLogics); + + int addQuestionScoreMationList(List> quScore); + + int addQuestionOrderquMationList(List> quOrderqu); + + int addQuestionRadioMationList(List> quRadio); + + int addQuestionCheckBoxMationList(List> quCheckBox); + + int addQuestionMultiFillblankMationList(List> quMultiFillblank); + + int addQuestionColumnMationList(List> quColumn); + + int addQuestionRowMationList(List> quRow); + + Map queryQuestionMationById(Map map); + + int deleteLogicQuestionMationById(Map map); + + int deleteQuestionMationById(Map map); + + int deleteQuestionOptionMationByQuId(Map map); + + int updateQuestionOrderByIdByQuId(Map question); + + Map queryQuestionChenColumnById(Map map); + + int deleteLogicQuestionChenColumnMationById(Map map); + + int deleteQuestionChenColumnMationById(Map map); + + Map queryQuestionChenRowById(Map map); + + int deleteQuestionChenRowMationById(Map map); + + int deleteLogicQuestionChenRowMationById(Map map); + + Map queryQuestionRadioOptionById(Map map); + + int deleteQuestionRadioOptionMationById(Map map); + + int deleteLogicQuestionRadioOptionMationById(Map map); + + Map queryQuestionChedkBoxOptionById(Map map); + + int deleteQuestionChedkBoxOptionMationById(Map map); + + int deleteLogicQuestionChedkBoxOptionMationById(Map map); + + Map queryQuestionScoreOptionById(Map map); + + int deleteQuestionScoreOptionMationById(Map map); + + int deleteLogicQuestionScoreOptionMationById(Map map); + + Map queryQuestionOrderOptionById(Map map); + + int deleteQuestionOrderOptionMationById(Map map); + + int deleteLogicQuestionOrderOptionMationById(Map map); + + Map queryQuestionMultiFillblankOptionById(Map map); + + int deleteQuestionMultiFillblankOptionMationById(Map map); + + int deleteLogicQuestionMultiFillblankOptionMationById(Map map); + + int editQuestionMationById(Map map); + + int editQuestionLogicsMationList(List> editquLogics); + + int editQuestionScoreMationList(List> editquScore); + + int editQuestionOrderquMationList(List> editquOrderqu); + + int editQuestionRadioMationList(List> editquRadio); + + int editQuestionCheckBoxMationList(List> editquCheckbox); + + int editQuestionMultiFillblankMationList(List> editquMultiFillblank); + + int editQuestionColumnMationList(List> editquColumn); + + int editQuestionRowMationList(List> editquRow); + + int deleteSurveyMationById(Map map); + + int editSurveyStateToReleaseById(Map map); + + List> queryRadioGroupStat(Map question); + + List> queryCheckBoxGroupStat(Map question); + + Map queryFillBlankGroupStat(Map question); + + Map queryAnswerGroupStat(Map question); + + List> queryMultiFillBlankGroupStat(Map question); + + List> queryEnumQuGroupStat(Map question); + + List> queryChenRadioGroupStat(Map question); + + List> queryChenFbkGroupStat(Map question); + + List> queryChenCheckBoxGroupStat(Map question); + + List> queryChenScoreGroupStat(Map question); + + List> queryScoreGroupStat(Map question); + + List> queryOrderQuGroupStat(Map question); + + int insertSurveyMationCopyById(Map map); + + List> queryQuestionMationCopyById(Map map); + + int addQuestionMationCopyBySurveyId(List> questions); + + List> queryQuestionRadioListByCopyId(Map question); + + int addQuestionRadioMationCopyList(List> questionRadio); + + List> queryQuestionCheckBoxListByCopyId(Map question); + + int addQuestionCheckBoxMationCopyList(List> questionCheckBoxs); + + List> queryQuestionMultiFillBlankListByCopyId(Map question); + + int addQuestionMultiFillBlankMationCopyList(List> questionMultiFillBlanks); + + List> queryQuestionChenRowListByCopyId(Map question); + + int addQuestionChenRowMationCopyList(List> questionChenRows); + + List> queryQuestionChenColumnListByCopyId(Map question); + + int addQuestionChenColumnMationCopyList(List> questionChenColumns); + + List> queryQuestionChenOptionListByCopyId(Map question); + + List> queryQuestionScoreListByCopyId(Map question); + + int addQuestionScoreMationCopyList(List> questionScores); + + List> queryQuestionOrderByListByCopyId(Map question); + + int addQuestionOrderByMationCopyList(List> questionOrderBys); + + int editSurveyAnswerNumById(Map surveyMation); + + int saveAnYesnoMaps(List> beans); + + int saveAnRadioMaps(List> beans); + + int saveAnMultiFillMaps(List> beans); + + int saveScoreMaps(List> beans); + + int saveChenCheckboxMaps(List> beans); + + int saveCompAnRadioMaps(List> beans); + + int saveCompChehRadioMaps(List> beans); + + int saveChenScoreMaps(List> beans); + + int saveAnCheckboxMaps(List> beans); + + int saveAnFillMaps(List> beans); + + int saveAnAnswerMaps(List> beans); + + int saveCompAnCheckboxMaps(List> beans); + + int saveEnumMaps(List> beans); + + int saveQuOrderMaps(List> beans); + + int saveChenRadioMaps(List> beans); + + int saveChenFbkMaps(List> beans); + + int insertSurveyAnswer(Map surveyAnswer); + + Map querySurveyAnswerMationByIp(Map map); + + List> querySurveyAnswerMationOverFiveMinByIp(Map map); + + int editSurveyStateToEndNumById(Map surveyMation); + + int updateSurveyMationEndById(Map map); + + int editSurveyStateToEndNumZdById(Map map); + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwAnDfillblank.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwAnDfillblank.java new file mode 100644 index 0000000..92cb0a7 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwAnDfillblank.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.multifllblank.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnDfillblank + * @Description: 答卷多行填空题保存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_dfillblank") +@ApiModel(value = "答卷多行填空题保存表实体类") +public class DwAnDfillblank extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = " " ) + private String answer; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("qu_item_id") + @ApiModelProperty(value = " " ) + private String quItemId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwQuMultiFllblank.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwQuMultiFllblank.java new file mode 100644 index 0000000..b527a66 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/multifllblank/entity/DwQuMultiFllblank.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.multifllblank.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwQuMultiFllblank + * @Description: 多行填空题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_qu_multi_fillblank") +@ApiModel(value = "多行填空题实体类") +public class DwQuMultiFllblank extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("option_title") + @ApiModelProperty(value = "选项标题") + private String optionTitle; + + @TableField("check_type") + @ApiModelProperty(value = "说明的验证方式") + private Integer checkType; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnAnswerDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnAnswerDao.java new file mode 100644 index 0000000..44ab524 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnAnswerDao.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwAnAnswer; + + +/** + * @ClassName: DwAnAnswerDao + * @Description: 答卷问答题保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnAnswerDao extends SkyeyeBaseMapper { + +} + + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnEnumquDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnEnumquDao.java new file mode 100644 index 0000000..e4e5d76 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnEnumquDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwAnEnumqu; + + +/** + * @ClassName: DwAnEnumquDao + * @Description: 答卷枚举题答案交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnEnumquDao extends SkyeyeBaseMapper { + +} + + + + + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnFillblankDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnFillblankDao.java new file mode 100644 index 0000000..85bcf1b --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnFillblankDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwAnFillblank; + + +/** + * @ClassName: DwAnFillblankDao + * @Description: 答卷填空题保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnFillblankDao extends SkyeyeBaseMapper { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnYesnoDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnYesnoDao.java new file mode 100644 index 0000000..8f8d248 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwAnYesnoDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwAnYesno; + + +/** + * @ClassName: DwAnYesnoDao + * @Description: 答卷判断题交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnYesnoDao extends SkyeyeBaseMapper { + +} + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwMailInviteInboxDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwMailInviteInboxDao.java new file mode 100644 index 0000000..6cdab75 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwMailInviteInboxDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwMailInviteInbox; + + +/** + * @ClassName: DwMailInviteInboxDao + * @Description: 答案是非题结果保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwMailInviteInboxDao extends SkyeyeBaseMapper { + +} + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuOrderbyDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuOrderbyDao.java new file mode 100644 index 0000000..45f599d --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuOrderbyDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwQuOrderby; + + +/** + * @ClassName: DwQuOrderbyDao + * @Description: 排序题行选项交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuOrderbyDao extends SkyeyeBaseMapper { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionBankDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionBankDao.java new file mode 100644 index 0000000..73f3cf3 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionBankDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwQuestionBank; + + +/** + * @ClassName: DwQuestionBankDao + * @Description: 题库交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionBankDao extends SkyeyeBaseMapper { + +} + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionDao.java new file mode 100644 index 0000000..80b61ac --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwQuestion; + + +/** + * @ClassName: DwQuestionDao + * @Description: 题库交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionDao extends SkyeyeBaseMapper { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionLogicDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionLogicDao.java new file mode 100644 index 0000000..c8eec91 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwQuestionLogicDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwQuestionLogic; + + +/** + * @ClassName: DwQuestionLogicDao + * @Description: 题目逻辑设置交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionLogicDao extends SkyeyeBaseMapper { + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyAnswerDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyAnswerDao.java new file mode 100644 index 0000000..6f2f9ff --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyAnswerDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwSurveyAnswer; + + +/** + * @ClassName: DwSurveyAnswerDao + * @Description: 问卷回答信息表交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwSurveyAnswerDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyDirectoryDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyDirectoryDao.java new file mode 100644 index 0000000..f389697 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyDirectoryDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + + +/** + * @ClassName: DwSurveyDirectoryDao + * @Description: 问卷目录及问卷交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +//public interface DwSurveyDirectoryDao extends SkyeyeBaseMapper { +// +//} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyMailInviteDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyMailInviteDao.java new file mode 100644 index 0000000..caf21f5 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/dao/DwSurveyMailInviteDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.question.entity.DwSurveyMailInvite; + + +/** + * @ClassName: DwSurveyMailInviteDao + * @Description: 问卷选择发送邮件调查时的邮件服务交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwSurveyMailInviteDao extends SkyeyeBaseMapper { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnAnswer.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnAnswer.java new file mode 100644 index 0000000..b35946d --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnAnswer.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnAnswer + * @Description: 答卷问答题保存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_an_answer") +@ApiModel(value = "答卷问答题保存实体类") +public class DwAnAnswer extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = " " ) + private String answer; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnEnumqu.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnEnumqu.java new file mode 100644 index 0000000..54c170e --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnEnumqu.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnDfillblank + * @Description: 答卷枚举题答案实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_dfillblank") +@ApiModel(value = "答卷枚举题答案实体类")//ddyg +public class DwAnEnumqu extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = " " ) + private String answer; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("enum_item") + @ApiModelProperty(value = " " ) + private String enumItem; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnFillblank.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnFillblank.java new file mode 100644 index 0000000..ef91a4d --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnFillblank.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnFillblank + * @Description: 答卷填空题保存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_fillblank") +@ApiModel(value = "答卷填空题保存实体类") +public class DwAnFillblank extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = " " ) + private String answer; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnYesno.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnYesno.java new file mode 100644 index 0000000..44e861e --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwAnYesno.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnYesno + * @Description: 答卷判断题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_yesno") +@ApiModel(value = "答卷判断题实体类") +public class DwAnYesno extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " " ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " " ) + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = " " ) + private String quId; + + @TableField("visibility") + @ApiModelProperty(value = " " ) + private Integer visibility; + + @TableField("year_answer") + @ApiModelProperty(value = " " ) + private String year_answer; + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwMailInviteInbox.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwMailInviteInbox.java new file mode 100644 index 0000000..9690c08 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwMailInviteInbox.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwMailInviteInbox + * @Description: 答案是非题结果保存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_mail_invite_inbox") +@ApiModel(value = "答案是非题结果保存实体类") +public class DwMailInviteInbox extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("email") + @ApiModelProperty(value = "") + private String email; + + @TableField("name") + @ApiModelProperty(value = "") + private String name; + + @TableField("sendcloud_id") + @ApiModelProperty(value = "sendclound返回的任务id") + private String sendcloudId; + + @TableField("status") + @ApiModelProperty(value = "0未发送 1已提交 2请求=投递 3发送 4打开 5点击 100发送失败201取消订阅 202软退信 203垃圾举报 204无效邮件", required = "required") + private Integer status; + + @TableField("survey_mail_invite_id") + @ApiModelProperty(value = "") + private String surveyMailInviteId; + + @TableField("us_contacts_id") + @ApiModelProperty(value = "") + private String usContactsId; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuOrderby.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuOrderby.java new file mode 100644 index 0000000..0b27bb2 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuOrderby.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwQuOrderby + * @Description: 排序题行选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_qu_orderby") +@ApiModel(value = "排序题行选项实体类") +public class DwQuOrderby extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("option_title") + @ApiModelProperty(value = "选项标题") + private String optionTitle; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestion.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestion.java new file mode 100644 index 0000000..b91fd48 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestion.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuestion + * @Description:问题表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_question") +@ApiModel(value = "问题表实体类") +public class DwQuestion extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer_input_row") + @ApiModelProperty(value = "填空的input行") + private Integer answerInputRow; + + @TableField("answer_input_width") + @ApiModelProperty(value = "填空的input宽度") + private Integer answerInputWidth; + + @TableField("belong_id") + @ApiModelProperty(value = "所属问卷或题库", required = "required") + private String belongId; + + @TableField("cell_count") + @ApiModelProperty(value = "按列显示时,列数", required = "required") + private Integer cellCount; + + @TableField("check_type") + @ApiModelProperty(value = "说明的验证方式") + private Integer checkType; + + @TableField("contacts_attr") + @ApiModelProperty(value = "1关联到联系人属性 0不关联到联系人属性") + private Integer contactsAttr; + + + @TableField("contacts_field") + @ApiModelProperty(value = "关联的联系人字段") + private String contactsField; + + @TableField("copy_from_id") + @ApiModelProperty(value = "如果是复制的题,则有复制于那一题") + private String copyFromId; + + @TableField("hv") + @ApiModelProperty(value = "1水平显示 2垂直显示", required = "required") + private Integer hv; + + @TableField("is_required") + @ApiModelProperty(value = "是否必答 0非必答 1必答", required = "required") + private Integer isRequired; + + @TableField("keywords") + @ApiModelProperty(value = "关键字") + private String keywords; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("param_int01") + @ApiModelProperty(value = "枚举题 枚举项数目 ,评分题起始分值") + private Integer paramInt01; + + @TableField("param_int02") + @ApiModelProperty(value = "评分题,最大分值") + private Integer paramInt02; + + @TableField("parent_qu_id") + @ApiModelProperty(value = "所属大题 只有小题才有此属性 即quTag=3的题") + private String parentQuId; + + @TableField("qu_name") + @ApiModelProperty(value = "题目名称") + private String quName; + + @TableField("qu_note") + @ApiModelProperty(value = "题目说明") + private String quNote; + + @TableField("qu_tag") + @ApiModelProperty(value = "是否是大小题 1默认题 2大题 3大题下面的小题", required = "required") + private Integer quTag; + + @TableField("qu_title") + @ApiModelProperty(value = "题干") + private String quTitle; + + @TableField("qu_type") + @ApiModelProperty(value = "题目类型", required = "required") + private Integer quType; + + @TableField("rand_order") + @ApiModelProperty(value = "选项随机排列 1随机排列 0不随机排列", required = "required") + private Integer randOrder; + + @TableField("tag") + @ApiModelProperty(value = "标记 1题库中的题 2问卷中的题") + private Integer tag; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("yesno_option") + @ApiModelProperty(value = "是非题的选项 ") + private Integer yesno_option; + + @TableField("datetime") + @ApiModelProperty(value = "创建时间") + private String datetime; + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionBank.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionBank.java new file mode 100644 index 0000000..cda4734 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionBank.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuestionBank + * @Description:题库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_question") +@ApiModel(value = "题库实体类") +public class DwQuestionBank extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("bank_name") + @ApiModelProperty(value = "题库名称", required = "required") + private String bankName; + + @TableField("bank_note") + @ApiModelProperty(value = "说明") + private String bankNote; + + @TableField("bank_state") + @ApiModelProperty(value = "状态 0设计状态 1发布状态", required = "required") + private Integer bankState; + + @TableField("bank_tag") + @ApiModelProperty(value = "共享题库 0 官方库 1用户共享 2用户自己的库", required = "required") + private Integer bankTag; + + @TableField("dir_type") + @ApiModelProperty(value = "1目录,2题库", required = "required") + private Integer dirType; + + @TableField("parent_id") + @ApiModelProperty(value = "dir_type为2时有此参数") + private String parentId; + + @TableField("excerpt_num") + @ApiModelProperty(value = "引用次数", required = "required") + private Integer excerptNum; + + @TableField("group_id1") + @ApiModelProperty(value = "问卷所属的组 功能分组") + private String groupId1; + + @TableField("group_id2") + @ApiModelProperty(value = "分组2\t行业分组") + private String groupId2; + + @TableField("qu_num") + @ApiModelProperty(value = "题目数", required = "required") + private Integer quNum; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionLogic.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionLogic.java new file mode 100644 index 0000000..3573879 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwQuestionLogic.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwQuestionLogic + * @Description:题目逻辑设置实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_question_logic") +@ApiModel(value = "题目逻辑设置实体类") +public class DwQuestionLogic extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("title") + @ApiModelProperty(value = "标题") + private String title; + + @TableField("cg_qu_item_id") + @ApiModelProperty(value = "回答选择题的选项ID (0任意选项)") + private String cgQuItemId; + + @TableField("ck_qu_id") + @ApiModelProperty(value = "回答选择的题ID", required = "required") + private String ckQuId; + + @TableField("ge_le") + @ApiModelProperty(value = "评分题 ge大于,le小于") + private String geLe; + + @TableField("logic_type") + @ApiModelProperty(value = "逻辑类型 (1=跳转,2显示)", required = "required") + private Integer logicType; + + @TableField("score_num") + @ApiModelProperty(value = "") + private Integer scoreNum; + + @TableField("sk_qu_id") + @ApiModelProperty(value = "要跳转的题 (end1提前结束-计入结果 end2提前结束-不计结果)") + private String skQuId; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyAnswer.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyAnswer.java new file mode 100644 index 0000000..62c3335 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyAnswer.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwSurveyAnswer + * @Description:问卷回答信息表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_survey_answer") +@ApiModel(value = "问卷回答信息表实体类") +public class DwSurveyAnswer extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("survey_id") + @ApiModelProperty(value = "问卷ID", required = "required") + private String surveyId; + + @TableField("bg_an_date") + @ApiModelProperty(value = "回答开始时间", required = "required") + private String bgAnDate; + + @TableField("end_an_date") + @ApiModelProperty(value = "回答结束时间", required = "required") + private String endAnDate; + + @TableField("complete_num") + @ApiModelProperty(value = "回答的题数") + private Integer completeNum; + + @TableField("complete_item_num") + @ApiModelProperty(value = "回答的题项目数 ---- 表示有些题下面会有多重回答") + private Integer completeItemNum; + + @TableField("data_source") + @ApiModelProperty(value = "数据来源 0网调 1录入数据 2移动数据 3导入数据", required = "required") + private Integer dataSource; + + @TableField("handle_state") + @ApiModelProperty(value = "审核状态 0未处理 1通过 2不通过", required = "required") + private Integer handleState; + + @TableField("ip_addr") + @ApiModelProperty(value = "回答者IP") + private String ipAddr; + + @TableField("addr") + @ApiModelProperty(value = "回答者是详细地址") + private String addr; + + @TableField("city") + @ApiModelProperty(value = "回答者城市 ") + private String city; + + @TableField("is_complete") + @ApiModelProperty(value = "是否完成 1完成 0未完成", required = "required") + private Integer isComplete; + + @TableField("is_effective") + @ApiModelProperty(value = "是否是有效数据 1有效 0无效", required = "required") + private Integer isEffective; + + @TableField("pc_mac") + @ApiModelProperty(value = "回答者MAC") + private String pcMac; + + @TableField("qu_num") + @ApiModelProperty(value = "回答的题数", required = "required") + private Integer quNum; + + @TableField("total_time") + @ApiModelProperty(value = "用时", required = "required") + private Integer totalTime; + + @TableField("create_id") + @ApiModelProperty(value = "回答者ID") + private String createId; + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyDirectory.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyDirectory.java new file mode 100644 index 0000000..468688c --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyDirectory.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwSurveyDirectory + * @Description:问卷目录及问卷实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_survey_directory") +@ApiModel(value = "问卷目录及问卷实体类") +public class DwSurveyDirectory extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("survey_name") + @ApiModelProperty(value = "问卷名称", required = "required") + private String surveyName; + + @TableField("survey_note") + @ApiModelProperty(value = "问卷说明") + private String surveyNote; + + @TableField("survey_qu_num") + @ApiModelProperty(value = "问卷下面有多少题目数", required = "required") + private Integer surveyQuNum; + + @TableField("survey_state") + @ApiModelProperty(value = "问卷状态 0默认设计状态 1执行中 2结束 ", required = "required") + private Integer surveyState; + + @TableField("real_start_time") + @ApiModelProperty(value = "回答的题项目数 ---- 表示有些题下面会有多重回答") + private String realStartTime; + + @TableField("real_end_time") + @ApiModelProperty(value = "实际结束时间") + private String realEndTime; + + @TableField("survey_model") + @ApiModelProperty(value = "问卷所属的问卷模块 1问卷模块 2试题模块", required = "required") + private Integer surveyModel; + + @TableField("an_item_least_num") + @ApiModelProperty(value = "可以回答的最少选项数目", required = "required") + private Integer anItemLeastNum; + + @TableField("an_item_most_num") + @ApiModelProperty(value = "可以回答的最多选项数目", required = "required") + private Integer anItemMostNum; + + @TableField("effective") + @ApiModelProperty(value = "问卷有效性限制 ---1不限制,2使用Cookie技术,3使用来源IP检测,4 每台电脑或手机只能答一次 ", required = "required") + private Integer ceffective; + + @TableField("effective_ip") + @ApiModelProperty(value = "每个IP只能答一次 1是 0否", required = "required") + private Integer effectiveIp; + + @TableField("effective_time") + @ApiModelProperty(value = "如果每个IP能答多次,每隔多长时间可以答一次(分钟)", required = "required") + private Integer effectiveTime; + + @TableField("yn_end_num") + @ApiModelProperty(value = "是否依据收到的份数结束 1是 0否", required = "required") + private Integer ynEndNum; + + @TableField("end_num") + @ApiModelProperty(value = "依据收到的份数", required = "required") + private Integer endNum; + + @TableField("yn_end_time") + @ApiModelProperty(value = "是否依据时间结束 1是 0否", required = "required") + private Integer ynEndTime; + + @TableField("end_time") + @ApiModelProperty(value = "手动设置的结束时间") + private String endTime; + + @TableField("rule") + @ApiModelProperty(value = "调查规则 1公开, 2私有, 3令牌(表示启用访问密码)", required = "required") + private Integer rule; + + @TableField("rule_code") + @ApiModelProperty(value = "rule为3时的令牌密码") + private String ruleCode; + + @TableField("answer_num") + @ApiModelProperty(value = "回答次数", required = "required") + private Integer answerNum; + + @TableField("refresh") + @ApiModelProperty(value = "有重复回答启用验证码 1是 0否", required = "required") + private Integer refresh; + + @TableField("excerpt_num") + @ApiModelProperty(value = "引用次数") + private Integer excerptNum; + + @TableField("html_path") + @ApiModelProperty(value = "静态HTML保存路径") + private String htmlPath; + + @TableField("is_share") + @ApiModelProperty(value = "是否共享问卷 0不共享 1共享", required = "required") + private Integer isShare; + + @TableField("sid") + @ApiModelProperty(value = "用于短链接的ID") + private String sid; + + @TableField("dir_type") + @ApiModelProperty(value = "1目录 2问卷", required = "required") + private Integer dirType; + + @TableField("end_type") + @ApiModelProperty(value = "结束方式 1手动结束,2依据结束时间,3依据收到的份数") + private Integer endType; + + @TableField("mail_only") + @ApiModelProperty(value = "只有邮件邀请唯一链接的受访者可回答 1启用 0不启用", required = "required") + private Integer mailOnly; + + @TableField("survey_tag") + @ApiModelProperty(value = "问卷标识 默认 0待审核 1审核通过 2审核未通过 3审核中", required = "required") + private Integer surveyTag; + + @TableField("view_answer") + @ApiModelProperty(value = "是否公开结果 0不 1公开", required = "required") + private Integer viewAnswer; + + @TableField("visibility") + @ApiModelProperty(value = "是否被删除 1.未删除 0.已删除", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyMailInvite.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyMailInvite.java new file mode 100644 index 0000000..63822c2 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/entity/DwSurveyMailInvite.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwSurveyMailInvite + * @Description:问卷选择发送邮件调查时的邮件服务实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_survey_mail_invite") +@ApiModel(value = "问卷选择发送邮件调查时的邮件服务实体类") +public class DwSurveyMailInvite extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("dw_send_user_mail") + @ApiModelProperty(value = "发件人邮箱", required = "required") + private String dwSendUserMail; + + @TableField("error_msg") + @ApiModelProperty(value = "错误信息") + private String error_msg; + + @TableField("audit") + @ApiModelProperty(value = "审核 0未审核 1审核通过 2审核拒绝 3审核中", required = "required") + private Integer audit; + + @TableField("sendcloud_msg_id") + @ApiModelProperty(value = " ") + private String sendcloud_msg_id; + + @TableField("status") + @ApiModelProperty(value = "状态 0未发送 1正在发送 2发送完成 3发送失败 4发送异常", required = "required") + private Integer status; + + @TableField("subject") + @ApiModelProperty(value = "") + private String subject; + + @TableField("inbox_num") + @ApiModelProperty(value = "总收件人数") + private Integer inbox_num; + + @TableField("send_num") + @ApiModelProperty(value = "已经发送的数") + private Integer send_num; + + @TableField("success_num") + @ApiModelProperty(value = "发送中成功的数") + private Integer success_num; + + @TableField("fail_num") + @ApiModelProperty(value = "发送中失败的数") + private Integer fail_num; + + @TableField("survey_id") + @ApiModelProperty(value = "问卷ID", required = "required") + private String survey_id; + + @TableField("create_id") + @ApiModelProperty(value = "发送人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "发送时间", required = "required") + private String createTime; +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnAnswerService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnAnswerService.java new file mode 100644 index 0000000..ff906bd --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnAnswerService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwAnAnswer; + +/** + * @ClassName: DwAnAnswerService + * @Description: 答卷问答题保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnAnswerService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnEnumquService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnEnumquService.java new file mode 100644 index 0000000..d59185a --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnEnumquService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwAnEnumqu; + +/** + * @ClassName: DwAnEnumquService + * @Description: 答卷枚举题答案接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnEnumquService extends SkyeyeBusinessService { + + +} + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnFillblankService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnFillblankService.java new file mode 100644 index 0000000..ee42907 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnFillblankService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwAnFillblank; + +/** + * @ClassName: DwAnFillblankService + * @Description: 答卷填空题保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnFillblankService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnYesnoService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnYesnoService.java new file mode 100644 index 0000000..5022939 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwAnYesnoService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwAnYesno; + +/** + * @ClassName: DwAnYesnoService + * @Description: 答卷判断题接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnYesnoService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwMailInviteInboxService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwMailInviteInboxService.java new file mode 100644 index 0000000..e882652 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwMailInviteInboxService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwMailInviteInbox; + +/** + * @ClassName: DwMailInviteInboxService + * @Description: 答案是非题结果保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwMailInviteInboxService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuOrderbyService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuOrderbyService.java new file mode 100644 index 0000000..f5432f5 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuOrderbyService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwQuOrderby; + +/** + * @ClassName: DwQuOrderbyService + * @Description: 排序题行选项接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuOrderbyService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionBankService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionBankService.java new file mode 100644 index 0000000..c480f94 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionBankService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwQuestionBank; + +/** + * @ClassName: DwQuestionBankService + * @Description: 题库接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionBankService extends SkyeyeBusinessService { + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionLogicService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionLogicService.java new file mode 100644 index 0000000..72755d6 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionLogicService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwQuestionLogic; + +/** + * @ClassName: DwQuestionLogicService + * @Description: 题目逻辑设置接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionLogicService extends SkyeyeBusinessService { + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionService.java new file mode 100644 index 0000000..c1d3c21 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwQuestionService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwQuestion; + +/** + * @ClassName: DwQuestionService + * @Description: 问题表接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuestionService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyAnswerService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyAnswerService.java new file mode 100644 index 0000000..1d032f0 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyAnswerService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwSurveyAnswer; + +/** + * @ClassName: DwSurveyAnswerService + * @Description: 问卷回答信息表接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwSurveyAnswerService extends SkyeyeBusinessService { + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyDirectoryService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyDirectoryService.java new file mode 100644 index 0000000..28382e2 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyDirectoryService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwSurveyDirectory; + +/** + * @ClassName: DwSurveyDirectoryService + * @Description: 问卷目录及问卷接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwSurveyDirectoryService extends SkyeyeBusinessService { + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyMailInviteService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyMailInviteService.java new file mode 100644 index 0000000..508900f --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/DwSurveyMailInviteService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.question.entity.DwSurveyMailInvite; + +/** + * @ClassName: DwSurveyMailInviteService + * @Description: 问卷选择发送邮件调查时的邮件服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwSurveyMailInviteService extends SkyeyeBusinessService { + + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnAnswerServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnAnswerServiceImpl.java new file mode 100644 index 0000000..4b1b151 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnAnswerServiceImpl.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.chen.dao.DwAnChenCheckboxDao; +import com.skyeye.eve.chen.entity.DwAnChenCheckbox; +import com.skyeye.eve.chen.service.DwAnChenCheckboxService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnAnswerServiceImpl + * @Description: 答卷问答题保存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷问答题保存", groupName = "答卷问答题保存", manageShow = false) +public class DwAnAnswerServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnChenCheckboxService { + +} + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnEnumquServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnEnumquServiceImpl.java new file mode 100644 index 0000000..6937305 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnEnumquServiceImpl.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwAnEnumquDao; +import com.skyeye.eve.question.entity.DwAnEnumqu; +import com.skyeye.eve.question.service.DwAnEnumquService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnEnumquServiceImpl + * @Description: 答卷枚举题答案服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷枚举题答案", groupName = "答卷枚举题答案", manageShow = false) +public class DwAnEnumquServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnEnumquService { + +} + + + + + + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnFillblankServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnFillblankServiceImpl.java new file mode 100644 index 0000000..611ff45 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnFillblankServiceImpl.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwAnFillblankDao; +import com.skyeye.eve.question.entity.DwAnFillblank; +import com.skyeye.eve.question.service.DwAnFillblankService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnFillblankServiceImpl + * @Description: 答卷填空题保存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷填空题保存", groupName = "答卷填空题保存", manageShow = false) +public class DwAnFillblankServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnFillblankService { + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnYesnoServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnYesnoServiceImpl.java new file mode 100644 index 0000000..4b03ff7 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwAnYesnoServiceImpl.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwAnYesnoDao; +import com.skyeye.eve.question.entity.DwAnYesno; +import com.skyeye.eve.question.service.DwAnYesnoService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnYesnoServiceImpl + * @Description: 答卷判断题服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷判断题", groupName = "答卷判断题", manageShow = false) +public class DwAnYesnoServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnYesnoService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwMailInviteInboxServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwMailInviteInboxServiceImpl.java new file mode 100644 index 0000000..0f888fb --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwMailInviteInboxServiceImpl.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwMailInviteInboxDao; +import com.skyeye.eve.question.entity.DwMailInviteInbox; +import com.skyeye.eve.question.service.DwMailInviteInboxService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwMailInviteInboxServiceImpl + * @Description: 答案是非题结果保存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答案是非题结果保存", groupName = "答案是非题结果保存", manageShow = false) +public class DwMailInviteInboxServiceImpl extends SkyeyeBusinessServiceImpl implements DwMailInviteInboxService { + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuOrderbyServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuOrderbyServiceImpl.java new file mode 100644 index 0000000..29d8d08 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuOrderbyServiceImpl.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwQuOrderbyDao; +import com.skyeye.eve.question.entity.DwQuOrderby; +import com.skyeye.eve.question.service.DwQuOrderbyService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuOrderbyServiceImpl + * @Description: 排序题行选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "排序题行选项", groupName = "排序题行选项", manageShow = false) +public class DwQuOrderbyServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuOrderbyService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionBankServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionBankServiceImpl.java new file mode 100644 index 0000000..523babc --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionBankServiceImpl.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwQuestionBankDao; +import com.skyeye.eve.question.entity.DwQuestionBank; +import com.skyeye.eve.question.service.DwQuestionBankService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnYesnoServiceImpl + * @Description: 题库服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "题库", groupName = "题库", manageShow = false) +public class DwQuestionBankServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuestionBankService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionLogicServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionLogicServiceImpl.java new file mode 100644 index 0000000..0cc6fd1 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionLogicServiceImpl.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwQuestionLogicDao; +import com.skyeye.eve.question.entity.DwQuestionLogic; +import com.skyeye.eve.question.service.DwQuestionLogicService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuestionLogicServiceImpl + * @Description: 题目逻辑设置服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "题目逻辑设置", groupName = "题目逻辑设置", manageShow = false) +public class DwQuestionLogicServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuestionLogicService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionServiceImpl.java new file mode 100644 index 0000000..d810f42 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwQuestionServiceImpl.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwQuestionDao; +import com.skyeye.eve.question.entity.DwQuestion; +import com.skyeye.eve.question.service.DwQuestionService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuestionServiceImpl + * @Description: 问题表服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "问题表", groupName = "问题表", manageShow = false) +public class DwQuestionServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuestionService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyAnswerServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyAnswerServiceImpl.java new file mode 100644 index 0000000..747a0b7 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyAnswerServiceImpl.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwSurveyAnswerDao; +import com.skyeye.eve.question.entity.DwSurveyAnswer; +import com.skyeye.eve.question.service.DwSurveyAnswerService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwSurveyAnswerServiceImpl + * @Description: 问卷回答信息表服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "问卷回答信息表", groupName = "问卷回答信息表", manageShow = false) +public class DwSurveyAnswerServiceImpl extends SkyeyeBusinessServiceImpl implements DwSurveyAnswerService { + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyDirectoryServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyDirectoryServiceImpl.java new file mode 100644 index 0000000..f867f29 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyDirectoryServiceImpl.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +//import com.skyeye.eve.question.dao.DwSurveyDirectoryDao; + + +/** + * @ClassName: DwSurveyAnswerServiceImpl + * @Description: 问卷目录及问卷服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +//@Service +//@SkyeyeService(name = "问卷目录及问卷", groupName = "问卷目录及问卷", manageShow = false) +//public class DwSurveyDirectoryServiceImpl extends SkyeyeBusinessServiceImpl implements DwSurveyDirectoryService { +// +//} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyMailInviteServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyMailInviteServiceImpl.java new file mode 100644 index 0000000..b8ce9cd --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/question/service/impl/DwSurveyMailInviteServiceImpl.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.question.service.impl; + + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.question.dao.DwSurveyMailInviteDao; +import com.skyeye.eve.question.entity.DwSurveyMailInvite; +import com.skyeye.eve.question.service.DwSurveyMailInviteService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwSurveyMailInviteServiceImpl + * @Description: 问卷选择发送邮件调查时的邮件服务服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "问卷选择发送邮件调查时的邮件服务", groupName = "问卷选择发送邮件调查时的邮件服务", manageShow = false) +public class DwSurveyMailInviteServiceImpl extends SkyeyeBusinessServiceImpl implements DwSurveyMailInviteService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwAnRadioDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwAnRadioDao.java new file mode 100644 index 0000000..77986ea --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwAnRadioDao.java @@ -0,0 +1,18 @@ +package com.skyeye.eve.radio.dao; +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.radio.entity.DwAnRadio; + +/** + * @ClassName: DwAnRadioDao + * @Description: 答卷单选题保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnRadioDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwQuRadioDao.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwQuRadioDao.java new file mode 100644 index 0000000..f535344 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/dao/DwQuRadioDao.java @@ -0,0 +1,15 @@ +package com.skyeye.eve.radio.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.radio.entity.DwQuRadio; + +/** + * @ClassName: DwQuRadioDao + * @Description: 单选题保存交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuRadioDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwAnRadio.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwAnRadio.java new file mode 100644 index 0000000..6bd35e6 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwAnRadio.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.radio.entity; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnRadio + * @Description: 答卷单选题保存表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_checkbox") +@ApiModel(value = "答卷单选题保存实体类") +public class DwAnRadio extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("belong_answer_id") + @ApiModelProperty(value = " ") + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = " ") + private String belongId; + + @TableField("other_text") + @ApiModelProperty(value = " ") + private String otherText; + + @TableField("qu_id") + @ApiModelProperty(value = " ") + private String quId; + + @TableField("qu_item_id") + @ApiModelProperty(value = " ") + private String quItemId; + + @TableField("visibility") + @ApiModelProperty(value = " ") + private Integer visibility; + + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwQuRadio.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwQuRadio.java new file mode 100644 index 0000000..c3a9e18 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/entity/DwQuRadio.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.radio.entity; + + import com.baomidou.mybatisplus.annotation.TableField; + import com.baomidou.mybatisplus.annotation.TableId; + import com.baomidou.mybatisplus.annotation.TableName; + import com.skyeye.annotation.api.ApiModel; + import com.skyeye.annotation.api.ApiModelProperty; + import com.skyeye.annotation.unique.UniqueField; + import com.skyeye.common.entity.CommonInfo; + import lombok.Data; + +/** + * @ClassName: DwQuRadio + * @Description: 单选题选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_qu_radio") +@ApiModel(value = "单选题选项实体类") +public class DwQuRadio extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容", required = "required") + private String optionName; + + @TableField("option_title") + @ApiModelProperty(value = "选项标题") + private String optionTitle; + + @TableField("check_type") + @ApiModelProperty(value = "说明的验证方式") + private Integer checkType; + + @TableField("is_note") + @ApiModelProperty(value = "是否带说明 0否 1是", required = "required") + private Integer isNote; + + @TableField("is_required_fill") + @ApiModelProperty(value = "说明内容是否必填 0非必填 1必填", required = "required") + private Integer isRequiredFill; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + +} \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwAnRadioService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwAnRadioService.java new file mode 100644 index 0000000..4aaa7eb --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwAnRadioService.java @@ -0,0 +1,16 @@ +package com.skyeye.eve.radio.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.radio.entity.DwAnRadio; + +/** + * @ClassName: DwAnRadioService + * @Description: 答卷单选题保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwAnRadioService extends SkyeyeBusinessService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwQuRadioService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwQuRadioService.java new file mode 100644 index 0000000..5fbac06 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/DwQuRadioService.java @@ -0,0 +1,15 @@ +package com.skyeye.eve.radio.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.radio.entity.DwQuRadio; + +/** + * @ClassName: DwQuRadioService + * @Description: 单选题保存接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DwQuRadioService extends SkyeyeBusinessService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwAnRadioServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwAnRadioServiceImpl.java new file mode 100644 index 0000000..0f4f626 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwAnRadioServiceImpl.java @@ -0,0 +1,22 @@ +package com.skyeye.eve.radio.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.radio.dao.DwAnRadioDao; +import com.skyeye.eve.radio.entity.DwAnRadio; +import com.skyeye.eve.radio.service.DwAnRadioService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwAnRadioServiceImpl + * @Description: 答卷单选题保存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "答卷单选题保存", groupName = "答卷单选题保存", manageShow = false) +public class DwAnRadioServiceImpl extends SkyeyeBusinessServiceImpl implements DwAnRadioService { + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwQuRadioServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwQuRadioServiceImpl.java new file mode 100644 index 0000000..09e932c --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/radio/service/impl/DwQuRadioServiceImpl.java @@ -0,0 +1,21 @@ +package com.skyeye.eve.radio.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.eve.radio.dao.DwQuRadioDao; +import com.skyeye.eve.radio.entity.DwQuRadio; +import com.skyeye.eve.radio.service.DwQuRadioService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: DwQuRadioServiceImpl + * @Description: 单选题选项服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "单选题选项", groupName = "单选题选项", manageShow = false) +public class DwQuRadioServiceImpl extends SkyeyeBusinessServiceImpl implements DwQuRadioService { +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnOrder.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnOrder.java new file mode 100644 index 0000000..e089856 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnOrder.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.score.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnOrder + * @Description: 答卷评分题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_order") +@ApiModel(value = "答卷评分题实体类") +public class DwAnOrder extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = "答案" ) + private String answer; + + @TableField("belong_answer_id") + @ApiModelProperty(value = "对应的答卷信息表" ) + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = "所属问卷ID" ) + private String belongId; + + @TableField("ordery_num") + @ApiModelProperty(value = "" ) + private String orderyNum; + + @TableField("qu_id") + @ApiModelProperty(value = "题目ID" ) + private String quId; + + @TableField("qu_row_id") + @ApiModelProperty(value = "" ) + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = "1 是 0非" ) + private Integer visibility; + + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnScore.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnScore.java new file mode 100644 index 0000000..498890f --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwAnScore.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.eve.score.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: DwAnScore + * @Description: 答卷评分题实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "dw_an_score") +@ApiModel(value = "答卷评分题实体类") +public class DwAnScore extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("answer") + @ApiModelProperty(value = "答案") + private String answer; + + @TableField("answer_score") + @ApiModelProperty(value = "") + private String answer_score; + + @TableField("belong_answer_id") + @ApiModelProperty(value = "对应的答卷信息表") + private String belongAnswerId; + + @TableField("belong_id") + @ApiModelProperty(value = "所属问卷ID") + private String belongId; + + @TableField("qu_id") + @ApiModelProperty(value = "题目ID") + private String quId; + + @TableField("qu_row_id") + @ApiModelProperty(value = "") + private String quRowId; + + @TableField("visibility") + @ApiModelProperty(value = "1 是 0非")//是否为空 + private Integer visibility; + +} + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwQuScore.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwQuScore.java new file mode 100644 index 0000000..1a28342 --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/score/entity/DwQuScore.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.score.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + + +/** + * @ClassName: DwQuScore + * @Description: 评分题行选项实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/8 14:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "dw_qu_score") +@ApiModel(value = "评分题行选项实体类") +public class DwQuScore extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("qu_id") + @ApiModelProperty(value = "所属题", required = "required") + private String quId; + + @TableField("option_name") + @ApiModelProperty(value = "选项内容") + private String optionName; + + @TableField("option_title") + @ApiModelProperty(value = "选项标题") + private String optionTitle; + + @TableField("order_by_id") + @ApiModelProperty(value = "排序ID") + private Integer orderById; + + @TableField("visibility") + @ApiModelProperty(value = "是否显示 0不显示 1显示", required = "required") + private Integer visibility; + + @TableField("create_id") + @ApiModelProperty(value = "创建人", required = "required") + private String createId; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; + + +} + + diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/DwSurveyDirectoryService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/DwSurveyDirectoryService.java new file mode 100644 index 0000000..ab1057e --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/DwSurveyDirectoryService.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface DwSurveyDirectoryService { + + void queryDwSurveyDirectoryList(InputObject inputObject, OutputObject outputObject); + + void insertDwSurveyDirectoryMation(InputObject inputObject, OutputObject outputObject); + + void queryDwSurveyDirectoryMationById(InputObject inputObject, OutputObject outputObject); + + void queryDwSurveyMationById(InputObject inputObject, OutputObject outputObject); + + void editDwSurveyMationById(InputObject inputObject, OutputObject outputObject); + + void addQuFillblankMation(InputObject inputObject, OutputObject outputObject); + + void addQuScoreMation(InputObject inputObject, OutputObject outputObject); + + void addQuOrderquMation(InputObject inputObject, OutputObject outputObject); + + void addQuPagetagMation(InputObject inputObject, OutputObject outputObject); + + void addQuRadioMation(InputObject inputObject, OutputObject outputObject); + + void addQuCheckBoxMation(InputObject inputObject, OutputObject outputObject); + + void addQuMultiFillblankMation(InputObject inputObject, OutputObject outputObject); + + void addQuParagraphMation(InputObject inputObject, OutputObject outputObject); + + void addQuChenMation(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionChenColumnMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionChenRowMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionRadioOptionMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionChedkBoxOptionMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionScoreOptionMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionOrderOptionMationById(InputObject inputObject, OutputObject outputObject); + + void deleteQuestionMultiFillblankOptionMationById(InputObject inputObject, OutputObject outputObject); + + void editSurveyStateToReleaseById(InputObject inputObject, OutputObject outputObject); + + void queryDwSurveyDirectoryMationByIdToHTML(InputObject inputObject, OutputObject outputObject); + + void deleteSurveyMationById(InputObject inputObject, OutputObject outputObject); + + void querySurveyFxMationById(InputObject inputObject, OutputObject outputObject); + + void insertSurveyMationCopyById(InputObject inputObject, OutputObject outputObject); + + void queryAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject); + + void insertAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject); + + void updateSurveyMationEndById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/impl/DwSurveyDirectoryServiceImpl.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/impl/DwSurveyDirectoryServiceImpl.java new file mode 100644 index 0000000..7b0afee --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/service/impl/DwSurveyDirectoryServiceImpl.java @@ -0,0 +1,1967 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.IPSeeker; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.question.CheckType; +import com.skyeye.common.util.question.QuType; +import com.skyeye.common.util.question.QuestionUtil; +import com.skyeye.eve.dao.DwSurveyDirectoryDao; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.DwSurveyDirectoryService; +import com.skyeye.eve.service.IQuartzService; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.util.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DwSurveyDirectoryServiceImpl + * @Description: 问卷功能服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/3 23:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DwSurveyDirectoryServiceImpl implements DwSurveyDirectoryService { + + @Autowired + private DwSurveyDirectoryDao dwSurveyDirectoryDao; + + @Autowired + private IQuartzService iQuartzService; + + /** + * 获取调查问卷列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDwSurveyDirectoryList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = dwSurveyDirectoryDao.queryDwSurveyDirectoryList(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增调查问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertDwSurveyDirectoryMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("sId", ToolUtil.randomStr(6, 12));//用于短链接的ID + map.put("dirType", 2);//2问卷 + map.put("surveyModel", 1);//问卷所属的问卷模块 1问卷模块 + map.put("surveyNote", "非常感谢您的参与!如有涉及个人信息,我们将严格保密。"); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + dwSurveyDirectoryDao.insertDwSurveyDirectoryMation(map); + } + + /** + * 获取调查问卷题目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDwSurveyDirectoryMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + List> questions = dwSurveyDirectoryDao.queryQuestionListByBelongId(map);//获取问卷中的题 + List> questionLeftList = new ArrayList<>(); + for (Map question : questions) { + Map questionItem = new HashMap<>(); + questionItem.put("id", question.get("id")); + questionItem.put("quTitle", question.get("quTitle")); + questionItem.put("quType", question.get("quType")); + questionLeftList.add(questionItem); + getQuestionOptionListMation(question); + } + surveyMation.put("questionLeftList", questionLeftList); + outputObject.setBean(surveyMation); + outputObject.setBeans(questions); + outputObject.settotal(1); + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + + /** + * 获取问题项 + * + * @param question + * @return + */ + public Map getQuestionOptionListMation(Map question) { + String quType = QuType.getActionName(Integer.parseInt(question.get("quType").toString()));//获取题目类型 + if (quType.equals(QuType.RADIO.getActionName()) || quType.equals(QuType.COMPRADIO.getActionName())) { + List> questionRadio = dwSurveyDirectoryDao.queryQuestionRadioListByQuestionId(question);//获取多行填空题 + question.put("questionRadio", questionRadio); + } else if (quType.equals(QuType.CHECKBOX.getActionName()) || quType.equals(QuType.COMPCHECKBOX.getActionName())) { + List> questionCheckBox = dwSurveyDirectoryDao.queryQuestionCheckBoxListByQuestionId(question);//获取多选题 + question.put("questionCheckBox", questionCheckBox); + } else if (quType.equals(QuType.MULTIFILLBLANK.getActionName())) { + List> questionMultiFillBlank = dwSurveyDirectoryDao.queryQuestionMultiFillBlankListByQuestionId(question);//获取多行填空题 + question.put("questionMultiFillBlank", questionMultiFillBlank); + } else if (quType.equals(QuType.BIGQU.getActionName())) { + List> childQuestions = dwSurveyDirectoryDao.queryChildQuestionListByBelongId(question);//获取问卷中的题 + for (Map item : childQuestions) { + getQuestionOptionListMation(item); + } + question.put("option", childQuestions); + } else if (quType.equals(QuType.CHENRADIO.getActionName()) || quType.equals(QuType.CHENCHECKBOX.getActionName()) || quType.equals(QuType.CHENSCORE.getActionName()) + || quType.equals(QuType.CHENFBK.getActionName()) || quType.equals(QuType.COMPCHENRADIO.getActionName())) {// 矩阵单选,矩阵多选,矩阵填空题,复合矩阵单选 + List> questionChenRow = dwSurveyDirectoryDao.queryQuestionChenRowListByQuestionId(question);//获取行选项 + List> questionChenColumn = dwSurveyDirectoryDao.queryQuestionChenColumnListByQuestionId(question);//获取列选项 + for (Map bean : questionChenRow) { + for (Map item : questionChenColumn) { + item.put("rowId", bean.get("id")); + } + bean.put("questionChenColumn", questionChenColumn); + } + question.put("questionChenRow", questionChenRow); + question.put("questionChenColumn", questionChenColumn); + if (quType.equals(QuType.COMPCHENRADIO.getActionName())) {//如果是复合矩阵单选题, 则还有题选项 + List> questionChenOption = dwSurveyDirectoryDao.queryQuestionChenOptionListByQuestionId(question);//获取选项 + question.put("questionChenOption", questionChenOption); + } + } else if (quType.equals(QuType.SCORE.getActionName())) { + List> questionScore = dwSurveyDirectoryDao.queryQuestionScoreListByQuestionId(question);//获取评分题 + question.put("quScores", questionScore); + } else if (quType.equals(QuType.ORDERQU.getActionName())) { + List> questionOrderBy = dwSurveyDirectoryDao.queryQuestionOrderByListByQuestionId(question);//获取排序题 + question.put("questionOrderBy", questionOrderBy); + } + List> questionLogic = dwSurveyDirectoryDao.queryQuestionLogicListByQuestionId(question);// 获取逻辑信息 + question.put("questionLogic", questionLogic); + question.put("quTypeName", quType.toUpperCase()); + return question; + } + + /** + * 获取调查问卷信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDwSurveyMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + outputObject.setBean(surveyMation); + outputObject.settotal(1); + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + + /** + * 编辑调查问卷信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editDwSurveyMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + dwSurveyDirectoryDao.editDwSurveyMationById(map);//编辑问卷信息 + } + + /** + * 编辑题目信息 + * map-> belongId:试卷id + * quTitle:问题标题 + * orderById:序号 + * tag:表示题目是试卷题还是题库中题 + * answerInputWidth:填空的input宽度 + * answerInputRow:填空的input行 + * contactsAttr:1关联到联系人属性 0不关联到联系人属性 + * contactsField:关联的联系人字段 + * checkType:说明的验证方式 + * hv:1水平显示 2垂直显示 + * randOrder:选项随机排列 1随机排列 0不随机排列 + * cellCount:按列显示时,列数 + * logic:逻辑设置json串 + * quId:问题id------非必填 + * + * @return + */ + public String compileQuestion(Map question) { + String quId = ""; + //判断题目id是否为空,为空则新增,不为空则修改 + if (ToolUtil.isBlank(question.get("quId").toString())) { + quId = ToolUtil.getSurFaceId(); + question.put("id", quId); + question.put("quTag", 1); + question.put("visibility", 1); + question.put("createTime", DateUtil.getTimeAndToString()); + dwSurveyDirectoryDao.addQuestionMation(question); + } else { + quId = question.get("quId").toString(); + dwSurveyDirectoryDao.editQuestionMationById(question); + } + return quId; + } + + /** + * 设置问题逻辑 + * + * @param quId + * @param logicStr + * @param userId + * @return + */ + public List> setLogics(String quId, String logicStr, String userId) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + QuestionUtil.setLogics(quId, logicStr, userId, insertList, editList); + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionLogicsMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionLogicsMationList(editList); + } + insertList.addAll(editList); + return insertList; + } + + /** + * 添加填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuFillblankMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.FILLBLANK.getIndex()); + String checkType = map.get("checkType").toString(); + if ("undefined".equals(checkType)) { + map.put("checkType", ""); + checkType = ""; + } + if (!ToolUtil.isBlank(checkType) && !ToolUtil.isNumeric(checkType)) { + map.put("checkType", CheckType.valueOf(checkType).getIndex()); + } + //添加问题并返回问题id + String quId = compileQuestion(map); + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加评分题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuScoreMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.SCORE.getIndex()); + // 添加问题并返回问题id + String quId = compileQuestion(map); + + // 获取模板绑定信息 + List> score = JSONUtil.toList(map.get("scoreTd").toString(), null); + if (score.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + QuestionUtil.setQuestionOptionMation(quId, score, insertList, editList, userId, -1); + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionScoreMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionScoreMationList(editList); + } + insertList.addAll(editList); + map.put("quItems", insertList); + } + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加排序题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuOrderquMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.ORDERQU.getIndex()); + //添加问题并返回问题id + String quId = compileQuestion(map); + + List> orderqu = JSONUtil.toList(map.get("orderquTd").toString(), null);//获取模板绑定信息 + if (orderqu.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + QuestionUtil.setQuestionOptionMation(quId, orderqu, insertList, editList, userId, -1); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionOrderquMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionOrderquMationList(editList); + } + insertList.addAll(editList); + map.put("quItems", insertList); + } + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加分页标记 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuPagetagMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.PAGETAG.getIndex()); + //添加问题并返回问题id + String quId = compileQuestion(map); + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加单选题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuRadioMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.RADIO.getIndex()); + //添加问题并返回问题id + String quId = compileQuestion(map); + + List> radio = JSONUtil.toList(map.get("radioTd").toString(), null);//获取模板绑定信息 + if (CollectionUtils.isNotEmpty(radio)) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + QuestionUtil.setQuestionOptionMation(quId, radio, insertList, editList, userId, QuType.RADIO.getIndex()); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionRadioMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionRadioMationList(editList); + } + insertList.addAll(editList); + map.put("quItems", insertList); + } + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加多选题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuCheckBoxMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.CHECKBOX.getIndex()); + // 添加问题并返回问题id + String quId = compileQuestion(map); + + List> checkbox = JSONUtil.toList(map.get("checkboxTd").toString(), null);//获取模板绑定信息 + if (checkbox.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + QuestionUtil.setQuestionOptionMation(quId, checkbox, insertList, editList, userId, QuType.CHECKBOX.getIndex()); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionCheckBoxMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionCheckBoxMationList(editList); + } + insertList.addAll(editList); + map.put("quItems", insertList); + } + + // 设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加多选填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuMultiFillblankMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.MULTIFILLBLANK.getIndex()); + //添加问题并返回问题id + String quId = compileQuestion(map); + + List> multiFillblank = JSONUtil.toList(map.get("multiFillblankTd").toString(), null);//获取模板绑定信息 + if (multiFillblank.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + QuestionUtil.setQuestionOptionMation(quId, multiFillblank, insertList, editList, userId, -1); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionMultiFillblankMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionMultiFillblankMationList(editList); + } + insertList.addAll(editList); + map.put("quItems", insertList); + } + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加段落题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuParagraphMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("quType", QuType.PARAGRAPH.getIndex()); + //添加问题并返回问题id + String quId = compileQuestion(map); + + //设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), inputObject.getLogParams().get("id").toString())); + outputObject.setBean(map); + } + + /** + * 添加矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void addQuChenMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + int quType = QuType.getIndex(map.get("quType").toString()); + if (-1 == quType) { + outputObject.setreturnMessage("参数值错误!"); + return; + } else { + map.put("quType", quType); + } + String userId = inputObject.getLogParams().get("id").toString(); + //添加问题并返回问题id + String quId = compileQuestion(map); + List> column = JSONUtil.toList(map.get("column").toString(), null);//获取模板绑定信息 + if (column.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + QuestionUtil.setQuestionOptionMation(quId, column, insertList, editList, userId, -1); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionColumnMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionColumnMationList(editList); + } + insertList.addAll(editList); + map.put("quColumnItems", insertList); + } + + List> row = JSONUtil.toList(map.get("row").toString(), null);//获取模板绑定信息 + if (row.size() > 0) { + List> insertList = new ArrayList<>(); + List> editList = new ArrayList<>(); + QuestionUtil.setQuestionOptionMation(quId, row, insertList, editList, userId, -1); + + if (!insertList.isEmpty()) { + dwSurveyDirectoryDao.addQuestionRowMationList(insertList); + } + if (!editList.isEmpty()) { + dwSurveyDirectoryDao.editQuestionRowMationList(editList); + } + insertList.addAll(editList); + map.put("quRowItems", insertList); + } + + // 设置问题逻辑 + map.put("quLogics", setLogics(quId, map.get("logic").toString(), userId)); + outputObject.setBean(map); + } + + /** + * 删除问题 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map question = dwSurveyDirectoryDao.queryQuestionMationById(map); + if (question != null) { + if (question.get("surveyState").toString().equals("0")) {//设计状态 + String tableName = QuType.getTableName(Integer.parseInt(question.get("quType").toString())); + if (!ToolUtil.isBlank(tableName)) { + String[] questionId = QuType.getQuestionId(Integer.parseInt(question.get("quType").toString())).split(","); + String[] str = tableName.split(","); + for (int i = 0; i < str.length; i++) { + map.put("tableName", str[i]); + map.put("key", questionId[i]); + dwSurveyDirectoryDao.deleteQuestionOptionMationByQuId(map); + } + } + dwSurveyDirectoryDao.deleteQuestionMationById(map);//执行物理删除问题 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionMationById(map);//执行逻辑删除问题 + } + dwSurveyDirectoryDao.updateQuestionOrderByIdByQuId(question);//修改该问题排序后面的序号减1 + } + } + + /** + * 删除矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题列选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionChenColumnMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionChenColumnById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionChenColumnMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionChenColumnMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除矩阵单选题,矩阵多选题,矩阵评分题,矩阵填空题行选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionChenRowMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionChenRowById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionChenRowMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionChenRowMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除单选题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionRadioOptionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionRadioOptionById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionRadioOptionMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionRadioOptionMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除多选题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionChedkBoxOptionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionChedkBoxOptionById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionChedkBoxOptionMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionChedkBoxOptionMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除评分题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionScoreOptionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionScoreOptionById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionScoreOptionMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionScoreOptionMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除排序选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionOrderOptionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionOrderOptionById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionOrderOptionMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionOrderOptionMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 删除多项填空题选项 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteQuestionMultiFillblankOptionMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map option = dwSurveyDirectoryDao.queryQuestionMultiFillblankOptionById(map); + if (option != null) { + if (option.get("surveyState").toString().equals("0")) {//设计状态 + dwSurveyDirectoryDao.deleteQuestionMultiFillblankOptionMationById(map);//执行物理删除 + } else {//执行中或者结束 + dwSurveyDirectoryDao.deleteLogicQuestionMultiFillblankOptionMationById(map);//执行逻辑删除问题 + } + } + } + + /** + * 发布问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editSurveyStateToReleaseById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + if ("0".equals(surveyMation.get("surveyState").toString())) {//设计状态可以发布问卷 + List> questions = dwSurveyDirectoryDao.queryQuestionListByBelongId(map);//获取问卷中的题 + if (!questions.isEmpty() && questions.size() > 0) { + map.put("startTime", DateUtil.getTimeAndToString()); + map.put("questionNum", questions.size()); + dwSurveyDirectoryDao.editSurveyStateToReleaseById(map); + if ("1".equals(surveyMation.get("ynEndTime").toString())) { + // 是否依据时间结束 + this.startUpTaskQuartz(surveyMation.get("id").toString(), surveyMation.get("surveyName").toString(), surveyMation.get("endTime").toString()); + } + } else { + outputObject.setreturnMessage("该问卷没有调查项,无法发布问卷。"); + } + } else { + outputObject.setreturnMessage("该问卷已发布,请刷新数据。"); + } + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + + private void startUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.END_SURVEY_MATION.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + /** + * 获取调查问卷题目信息用来生成html页面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDwSurveyDirectoryMationByIdToHTML(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + List> questions = dwSurveyDirectoryDao.queryQuestionListByBelongId(map);//获取问卷中的题 + int pageNo = 1; + for (Map question : questions) { + String quType = QuType.getActionName(Integer.parseInt(question.get("quType").toString())); + if (quType.equals(QuType.PAGETAG.getActionName())) { + pageNo++; + } + } + for (Map question : questions) { + question.put("pageNo", pageNo); + getQuestionOptionListMation(question); + } + surveyMation.put("pageNo", pageNo); + outputObject.setBean(surveyMation); + outputObject.setBeans(questions); + outputObject.settotal(1); + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + + /** + * 删除问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteSurveyMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + dwSurveyDirectoryDao.deleteSurveyMationById(map);//删除问卷 + } + + /** + * 分析报告问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySurveyFxMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + List> questions = dwSurveyDirectoryDao.queryQuestionListByBelongId(map);//获取问卷中的题 + for (Map question : questions) { + question.put("quTypeName", QuType.getCName(Integer.parseInt(question.get("quType").toString()))); + getQuestionOptionListMation(question); + getQuestionOptionReportListMation(question); + } + outputObject.setBean(surveyMation); + outputObject.setBeans(questions); + outputObject.settotal(1); + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + + /** + * 统计获取数量 + * + * @param question + * @return + */ + public Map getQuestionOptionReportListMation(Map question) { + String quType = QuType.getActionName(Integer.parseInt(question.get("quType").toString()));//获取题目类型 + if (quType.equals(QuType.RADIO.getActionName()) || quType.equals(QuType.COMPRADIO.getActionName())) {//单选 复合单选 + List> beans = dwSurveyDirectoryDao.queryRadioGroupStat(question); + List> radios = (List>) question.get("questionRadio"); + int count = 0; + for (Map radio : radios) { + radio.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quItemId").toString().equals(radio.get("id").toString())) { + radio.put("anCount", bean.get("count")); + } + } + count += Integer.parseInt(radio.get("anCount").toString()); + } + for (Map radio : radios) { + radio.put("anAllCount", count); + } + } else if (quType.equals(QuType.CHECKBOX.getActionName()) || quType.equals(QuType.COMPCHECKBOX.getActionName())) {//多选 复合多选 + List> beans = dwSurveyDirectoryDao.queryCheckBoxGroupStat(question); + List> checkBoxs = (List>) question.get("questionCheckBox"); + int count = 0; + for (Map checkBox : checkBoxs) { + checkBox.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quItemId").toString().equals(checkBox.get("id").toString())) { + checkBox.put("anCount", bean.get("count")); + } + } + count += Integer.parseInt(checkBox.get("anCount").toString()); + } + for (Map checkBox : checkBoxs) { + checkBox.put("anAllCount", count); + } + } else if (quType.equals(QuType.FILLBLANK.getActionName())) {//填空题 + Map bean = dwSurveyDirectoryDao.queryFillBlankGroupStat(question); + question.put("rowContent", bean.get("emptyCount")); + question.put("optionContent", bean.get("blankCount")); + question.put("anCount", bean.get("blankCount")); + } else if (quType.equals(QuType.ANSWER.getActionName())) {//多行填空题 + Map bean = dwSurveyDirectoryDao.queryAnswerGroupStat(question); + question.put("rowContent", bean.get("emptyCount")); + question.put("optionContent", bean.get("blankCount")); + question.put("anCount", bean.get("blankCount")); + } else if (quType.equals(QuType.MULTIFILLBLANK.getActionName())) {//组合填空 + List> beans = dwSurveyDirectoryDao.queryMultiFillBlankGroupStat(question); + List> multiFillBlanks = (List>) question.get("questionMultiFillBlank"); + int count = 0; + for (Map multiFillBlank : multiFillBlanks) { + multiFillBlank.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quItemId").toString().equals(multiFillBlank.get("id").toString())) { + multiFillBlank.put("anCount", bean.get("count")); + } + } + count += Integer.parseInt(multiFillBlank.get("anCount").toString()); + } + for (Map multiFillBlank : multiFillBlanks) { + multiFillBlank.put("anAllCount", count); + } + } else if (quType.equals(QuType.ENUMQU.getActionName())) {//枚举题 + List> beans = dwSurveyDirectoryDao.queryEnumQuGroupStat(question); + if (beans.isEmpty()) { + question.put("anCount", 0); + } else { + question.put("anCount", beans.size()); + } + } else if (quType.equals(QuType.CHENRADIO.getActionName())) {//矩阵单选题 + List> beans = dwSurveyDirectoryDao.queryChenRadioGroupStat(question); + List> rows = (List>) question.get("questionChenRow"); + int count = 0; + for (Map row : rows) { + row.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quRowId").toString().equals(row.get("id").toString())) { + row.put("anCount", Integer.parseInt(row.get("anCount").toString()) + Integer.parseInt(bean.get("count").toString())); + } + } + count += Integer.parseInt(row.get("anCount").toString()); + } + for (Map bean : beans) { + bean.put("anAllCount", count); + for (Map row : rows) { + if (row.get("id").toString().equals(bean.get("quRowId").toString())) { + bean.put("anCount", row.get("anCount").toString()); + } + } + } + question.put("anChenRadios", beans); + } else if (quType.equals(QuType.CHENFBK.getActionName())) {//矩阵填空题 + List> beans = dwSurveyDirectoryDao.queryChenFbkGroupStat(question); + List> rows = (List>) question.get("questionChenRow"); + int count = 0; + for (Map row : rows) { + row.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quRowId").toString().equals(row.get("id").toString())) { + row.put("anCount", Integer.parseInt(row.get("anCount").toString()) + Integer.parseInt(bean.get("count").toString())); + } + } + count += Integer.parseInt(row.get("anCount").toString()); + } + for (Map bean : beans) { + bean.put("anAllCount", count); + for (Map row : rows) { + if (row.get("id").toString().equals(bean.get("quRowId").toString())) { + bean.put("anCount", row.get("anCount").toString()); + } + } + } + question.put("anChenFbks", beans); + } else if (quType.equals(QuType.CHENCHECKBOX.getActionName())) {//矩阵多选题 + List> beans = dwSurveyDirectoryDao.queryChenCheckBoxGroupStat(question); + List> rows = (List>) question.get("questionChenRow"); + int count = 0; + for (Map row : rows) { + row.put("anCount", 0); + for (Map bean : beans) { + if (bean.get("quRowId").toString().equals(row.get("id").toString())) { + row.put("anCount", Integer.parseInt(row.get("anCount").toString()) + Integer.parseInt(bean.get("count").toString())); + } + } + count += Integer.parseInt(row.get("anCount").toString()); + } + for (Map bean : beans) { + bean.put("anAllCount", count); + for (Map row : rows) { + if (row.get("id").toString().equals(bean.get("quRowId").toString())) { + bean.put("anCount", row.get("anCount").toString()); + } + } + } + question.put("anChenCheckboxs", beans); + } else if (quType.equals(QuType.CHENSCORE.getActionName())) {//矩阵评分题 + List> beans = dwSurveyDirectoryDao.queryChenScoreGroupStat(question); + question.put("anChenScores", beans); + } else if (quType.equals(QuType.SCORE.getActionName())) {//评分题 + List> beans = dwSurveyDirectoryDao.queryScoreGroupStat(question); + List> scores = (List>) question.get("quScores"); + int count = 0; + for (Map score : scores) { + score.put("anCount", 0); + score.put("avgScore", "0.00"); + for (Map bean : beans) { + if (bean.get("quRowId").toString().equals(score.get("id").toString())) { + score.put("anCount", bean.get("count")); + score.put("avgScore", Float.parseFloat(bean.get("avgScore").toString())); + } + } + count += Integer.parseInt(score.get("anCount").toString()); + } + for (Map score : scores) { + score.put("anAllCount", count); + } + } else if (quType.equals(QuType.ORDERQU.getActionName())) {//排序题 + List> beans = dwSurveyDirectoryDao.queryOrderQuGroupStat(question); + List> orderQus = (List>) question.get("questionOrderBy"); + for (Map bean : beans) { + for (Map orderQu : orderQus) { + if (bean.get("quRowId").toString().equals(orderQu.get("id").toString())) { + orderQu.put("anOrderSum", bean.get("sumOrderNum")); + } + } + } + } + return question; + } + + /** + * 复制问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertSurveyMationCopyById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("sId", ToolUtil.randomStr(6, 12));//用于短链接的ID + map.put("dirType", 2);//2问卷 + map.put("surveyModel", 1);//问卷所属的问卷模块 1问卷模块 + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + // 复制问卷 + dwSurveyDirectoryDao.insertSurveyMationCopyById(map); + List> questions = dwSurveyDirectoryDao.queryQuestionMationCopyById(map); + String surveyId = map.get("id").toString(); + for (Map question : questions) { + question.put("copyFormId", question.get("id")); + question.put("id", ToolUtil.getSurFaceId()); + question.put("createTime", DateUtil.getTimeAndToString()); + question.put("belongId", surveyId); + copyQuestionOptionListMation(question); + } + dwSurveyDirectoryDao.addQuestionMationCopyBySurveyId(questions); + } + + /** + * 复制题目选项 + * + * @param question + */ + public void copyQuestionOptionListMation(Map question) { + String quType = QuType.getActionName(Integer.parseInt(question.get("quType").toString()));//获取题目类型 + if (quType.equals(QuType.RADIO.getActionName()) || quType.equals(QuType.COMPRADIO.getActionName())) { + List> questionRadios = dwSurveyDirectoryDao.queryQuestionRadioListByCopyId(question);//获取多行填空题 + setBaseMation(question, questionRadios); + if (!questionRadios.isEmpty()) { + dwSurveyDirectoryDao.addQuestionRadioMationCopyList(questionRadios); + } + } else if (quType.equals(QuType.CHECKBOX.getActionName()) || quType.equals(QuType.COMPCHECKBOX.getActionName())) { + List> questionCheckBoxs = dwSurveyDirectoryDao.queryQuestionCheckBoxListByCopyId(question);//获取多选题 + setBaseMation(question, questionCheckBoxs); + if (!questionCheckBoxs.isEmpty()) { + dwSurveyDirectoryDao.addQuestionCheckBoxMationCopyList(questionCheckBoxs); + } + } else if (quType.equals(QuType.MULTIFILLBLANK.getActionName())) { + List> questionMultiFillBlanks = dwSurveyDirectoryDao.queryQuestionMultiFillBlankListByCopyId(question);//获取多行填空题 + setBaseMation(question, questionMultiFillBlanks); + if (!questionMultiFillBlanks.isEmpty()) { + dwSurveyDirectoryDao.addQuestionMultiFillBlankMationCopyList(questionMultiFillBlanks); + } + } else if (quType.equals(QuType.BIGQU.getActionName())) { + } else if (quType.equals(QuType.CHENRADIO.getActionName()) || quType.equals(QuType.CHENCHECKBOX.getActionName()) || quType.equals(QuType.CHENSCORE.getActionName()) + || quType.equals(QuType.CHENFBK.getActionName()) || quType.equals(QuType.COMPCHENRADIO.getActionName())) {// 矩阵单选,矩阵多选,矩阵填空题,复合矩阵单选 + List> questionChenRows = dwSurveyDirectoryDao.queryQuestionChenRowListByCopyId(question);//获取行选项 + List> questionChenColumns = dwSurveyDirectoryDao.queryQuestionChenColumnListByCopyId(question);//获取列选项 + setBaseMation(question, questionChenRows); + if (!questionChenRows.isEmpty()) { + dwSurveyDirectoryDao.addQuestionChenRowMationCopyList(questionChenRows); + } + setBaseMation(question, questionChenColumns); + if (!questionChenColumns.isEmpty()) { + dwSurveyDirectoryDao.addQuestionChenColumnMationCopyList(questionChenColumns); + } + if (quType.equals(QuType.COMPCHENRADIO.getActionName())) {//如果是复合矩阵单选题, 则还有题选项 + List> questionChenOptions = dwSurveyDirectoryDao.queryQuestionChenOptionListByCopyId(question);//获取选项 + setBaseMation(question, questionChenOptions); + } + } else if (quType.equals(QuType.SCORE.getActionName())) { + List> questionScores = dwSurveyDirectoryDao.queryQuestionScoreListByCopyId(question);//获取评分题 + setBaseMation(question, questionScores); + if (!questionScores.isEmpty()) { + dwSurveyDirectoryDao.addQuestionScoreMationCopyList(questionScores); + } + } else if (quType.equals(QuType.ORDERQU.getActionName())) { + List> questionOrderBys = dwSurveyDirectoryDao.queryQuestionOrderByListByCopyId(question);//获取排序题 + setBaseMation(question, questionOrderBys); + if (!questionOrderBys.isEmpty()) { + dwSurveyDirectoryDao.addQuestionOrderByMationCopyList(questionOrderBys); + } + } + } + + private void setBaseMation(Map question, List> list) { + for (Map bean : list) { + bean.put("id", ToolUtil.getSurFaceId()); + bean.put("createTime", DateUtil.getTimeAndToString()); + bean.put("quId", question.get("id")); + } + } + + /** + * 判断该ip的用户是否回答过此问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + if (judgeWhetherExaming(map, PutObject.getRequest(), outputObject)) { + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + outputObject.setBean(surveyMation); + } + } + + /** + * 用户回答问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertAnswerSurveyMationByIp(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map data = JSONUtil.toBean(map.get("jsonData").toString(), null); + map.put("id", data.get("surveyId")); + HttpServletRequest request = PutObject.getRequest(); + if (judgeWhetherExaming(map, request, outputObject)) { + //问卷调查ip + String ipAddr = ToolUtil.getIpByRequest(request); + Map> quMaps = buildSaveSurveyMap(request, data); + //问卷答卷信息 + Map surveyAnswer = new HashMap<>(); + String addr = IPSeeker.getCountry(ipAddr); + String city = IPSeeker.getCurCityByCountry(addr); + surveyAnswer.put("ipAddr", ipAddr); + surveyAnswer.put("addr", addr); + surveyAnswer.put("city", city); + surveyAnswer.put("id", data.get("surveyId")); + surveyAnswer.put("dataSource", 0); + surveyAnswer.put("bgAnDate", map.get("bgAnDate")); + saveAnswer(surveyAnswer, quMaps); + } + } + + /** + * 是否可以参加调研 + * + * @param map + * @param request + * @param outputObject 出参以及提示信息的返回值对象 + * @return + */ + public boolean judgeWhetherExaming(Map map, HttpServletRequest request, OutputObject outputObject) { + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + //问卷是否存在 + if (surveyMation != null && !surveyMation.isEmpty()) { + if ("1".equals(surveyMation.get("surveyState").toString())) { + //每台电脑或手机只能答一次 + if ("4".equals(surveyMation.get("effective").toString()) || "1".equals(surveyMation.get("effectiveIp").toString())) { + //获取答卷ip + map.put("ip", ToolUtil.getIpByRequest(request)); + Map answerMation = dwSurveyDirectoryDao.querySurveyAnswerMationByIp(map); + if (answerMation != null && !answerMation.isEmpty()) { + outputObject.setreturnMessage("您已参与过该问卷,请休息一会儿。"); + return false; + } + } else { + //不做ip限制,则默认每五分钟才能答一次 + List> answerMation = dwSurveyDirectoryDao.querySurveyAnswerMationOverFiveMinByIp(map); + if (answerMation != null && !answerMation.isEmpty()) { + outputObject.setreturnMessage("您已参与过该问卷,请休息一会儿。"); + return false; + } + } + //是否依据收到的份数结束 + if ("1".equals(surveyMation.get("ynEndNum").toString())) { + if (Integer.parseInt(surveyMation.get("answerNum").toString()) + 1 > Integer.parseInt(surveyMation.get("endNum").toString())) { + outputObject.setreturnMessage("问卷已结束。"); + return false; + } + } + //是否依据时间结束 + if ("1".equals(surveyMation.get("ynEndTime").toString())) { + //当前时间和设置的结束时间作比较 + if (DateUtil.compare(surveyMation.get("endTime").toString(), DateUtil.getTimeAndToString())) { + outputObject.setreturnMessage("问卷已结束。"); + return false; + } + } + } else { + outputObject.setreturnMessage("问卷已结束。"); + return false; + } + } else { + outputObject.setreturnMessage("该问卷信息已不存在"); + } + return true; + } + + /** + * 用户回答问卷时获取key-value值 + * + * @param request + * @param params + * @return + */ + public Map> buildSaveSurveyMap(HttpServletRequest request, Map params) { + Map> quMaps = new HashMap>(); + Map yesnoMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.YESNO.getIndex() + "_");// 是非 + quMaps.put("yesnoMaps", yesnoMaps); + Map radioMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.RADIO.getIndex() + "_");// 单选 + Map checkboxMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.CHECKBOX.getIndex() + "_");// 多选 + Map fillblankMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.FILLBLANK.getIndex() + "_");// 填空 + quMaps.put("fillblankMaps", fillblankMaps); + //dfillValue;quItemId问题选项id;otherText其他文本信息 + String dfillValue, quItemId, otherText; + //map中间参数;anCheckbox选项对象;mapRow矩阵题中间对象 + Map map, anCheckbox, mapRow; + Map dfillblankMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.MULTIFILLBLANK.getIndex() + "_");// 多项填空 + for (String key : dfillblankMaps.keySet()) { + dfillValue = dfillblankMaps.get(key).toString(); + map = WebUtils.getParametersStartingWith(request, dfillValue); + dfillblankMaps.put(key, map); + } + quMaps.put("multifillblankMaps", dfillblankMaps); + Map answerMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.ANSWER.getIndex() + "_");// 多行填空 + quMaps.put("answerMaps", answerMaps); + Map compRadioMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.COMPRADIO.getIndex() + "_");// 复合单选 + Map anRadio; + for (String key : compRadioMaps.keySet()) { + quItemId = compRadioMaps.get(key).toString(); + otherText = params.get("text_qu_" + QuType.COMPRADIO.getIndex() + "_" + key + "_" + quItemId).toString(); + anRadio = new HashMap<>(); + anRadio.put("quId", key); + anRadio.put("quItemId", quItemId); + anRadio.put("otherText", otherText); + compRadioMaps.put(key, anRadio); + } + quMaps.put("compRadioMaps", compRadioMaps); + Map compCheckboxMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.COMPCHECKBOX.getIndex() + "_");// 复合多选 + + for (String key : compCheckboxMaps.keySet()) { + dfillValue = compCheckboxMaps.get(key).toString(); + map = WebUtils.getParametersStartingWith(request, "tag_" + dfillValue); + for (String key2 : map.keySet()) { + quItemId = map.get(key2).toString(); + otherText = params.get("text_" + dfillValue + quItemId).toString(); + anCheckbox = new HashMap<>(); + anCheckbox.put("quItemId", quItemId); + anCheckbox.put("otherText", otherText); + map.put(key2, anCheckbox); + } + compCheckboxMaps.put(key, map); + } + quMaps.put("compCheckboxMaps", compCheckboxMaps); + Map enumMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.ENUMQU.getIndex() + "_");// 枚举 + quMaps.put("enumMaps", enumMaps); + Map scoreMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.SCORE.getIndex() + "_");// 分数 + for (String key : scoreMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, scoreMaps.get(key).toString()); + scoreMaps.put(key, map); + } + quMaps.put("scoreMaps", scoreMaps); + Map quOrderMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.ORDERQU.getIndex() + "_");// 排序 + for (String key : quOrderMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, quOrderMaps.get(key).toString()); + quOrderMaps.put(key, map); + } + quMaps.put("quOrderMaps", quOrderMaps); + Map chenRadioMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.CHENRADIO.getIndex() + "_"); + for (String key : chenRadioMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, chenRadioMaps.get(key).toString()); + chenRadioMaps.put(key, map); + } + quMaps.put("chenRadioMaps", chenRadioMaps); + Map chenCheckboxMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.CHENCHECKBOX.getIndex() + "_"); + for (String key : chenCheckboxMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, chenCheckboxMaps.get(key).toString()); + for (String keyRow : map.keySet()) { + mapRow = WebUtils.getParametersStartingWith(request, map.get(keyRow).toString()); + map.put(keyRow, mapRow); + } + chenCheckboxMaps.put(key, map); + } + quMaps.put("chenCheckboxMaps", chenCheckboxMaps); + Map chenScoreMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.CHENSCORE.getIndex() + "_"); + for (String key : chenScoreMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, chenScoreMaps.get(key).toString()); + for (String keyRow : map.keySet()) { + mapRow = WebUtils.getParametersStartingWith(request, map.get(keyRow).toString()); + map.put(keyRow, mapRow); + } + chenScoreMaps.put(key, map); + } + quMaps.put("chenScoreMaps", chenScoreMaps); + Map chenFbkMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.CHENFBK.getIndex() + "_"); + for (String key : chenFbkMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, chenFbkMaps.get(key).toString()); + for (String keyRow : map.keySet()) { + mapRow = WebUtils.getParametersStartingWith(request, map.get(keyRow).toString()); + map.put(keyRow, mapRow); + } + chenFbkMaps.put(key, map); + } + quMaps.put("chenFbkMaps", chenFbkMaps); + for (String key : radioMaps.keySet()) { + quItemId = radioMaps.get(key).toString(); + otherText = params.get("text_qu_" + QuType.RADIO.getIndex() + "_" + key + "_" + quItemId).toString(); + anRadio = new HashMap<>(); + anRadio.put("quId", key); + anRadio.put("quItemId", quItemId); + anRadio.put("otherText", otherText); + radioMaps.put(key, anRadio); + } + quMaps.put("compRadioMaps", radioMaps); + for (String key : checkboxMaps.keySet()) { + dfillValue = checkboxMaps.get(key).toString(); + map = WebUtils.getParametersStartingWith(request, dfillValue); + for (String key2 : map.keySet()) { + quItemId = map.get(key2).toString(); + otherText = params.get("text_" + dfillValue + quItemId).toString(); + anCheckbox = new HashMap<>(); + anCheckbox.put("quItemId", quItemId); + anCheckbox.put("otherText", otherText); + map.put(key2, anCheckbox); + } + checkboxMaps.put(key, map); + } + quMaps.put("compCheckboxMaps", checkboxMaps); + Map chenCompChenRadioMaps = WebUtils.getParametersStartingWith(request, "qu_" + QuType.COMPCHENRADIO.getIndex() + "_"); + for (String key : chenCompChenRadioMaps.keySet()) { + map = WebUtils.getParametersStartingWith(request, chenCompChenRadioMaps.get(key).toString()); + for (String keyRow : map.keySet()) { + mapRow = WebUtils.getParametersStartingWith(request, map.get(keyRow).toString()); + map.put(keyRow, mapRow); + } + chenCompChenRadioMaps.put(key, map); + } + quMaps.put("compChenRadioMaps", chenCompChenRadioMaps); + return quMaps; + } + + /** + * 保存答案 + * + * @param surveyAnswer + * @param quMaps 参数 + */ + public void saveAnswer(Map surveyAnswer, Map> quMaps) { + String id = surveyAnswer.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + surveyMation.put("answerNum", Integer.parseInt(surveyMation.get("answerNum").toString()) + 1); + dwSurveyDirectoryDao.editSurveyAnswerNumById(surveyMation);//修改回答数量 + if ("1".equals(surveyMation.get("ynEndNum").toString())) {//是否依据收到的份数结束 + if (Integer.parseInt(surveyMation.get("answerNum").toString()) + 1 >= Integer.parseInt(surveyMation.get("endNum").toString())) { + surveyMation.put("realEndTime", DateUtil.getTimeAndToString()); + dwSurveyDirectoryDao.editSurveyStateToEndNumById(surveyMation);//结束调查 + } + } + //问卷答案 + surveyAnswer.put("bgAnDate", surveyAnswer.get("bgAnDate")); + surveyAnswer.put("endAnDate", DateUtil.getTimeAndToString()); + surveyAnswer.put("totalTime", DateUtil.getDistanceMinute(surveyAnswer.get("bgAnDate").toString(), surveyAnswer.get("endAnDate").toString()));//分钟 + surveyAnswer.put("answerId", ToolUtil.getSurFaceId()); + + int anCount = 0;//回答的题目数,包含多个答案的数量 + // 保存答案 + // 是非题 + Map yesnoMaps = quMaps.get("yesnoMaps"); + anCount += saveAnYesnoMaps(surveyAnswer, yesnoMaps); + // 单选题 + Map radioMaps = quMaps.get("radioMaps"); + anCount += saveAnRadioMaps(surveyAnswer, radioMaps); + // 多选题 + Map checkboxMaps = quMaps.get("checkboxMaps"); + anCount += saveAnCheckboxMaps(surveyAnswer, checkboxMaps); + // 填空题 + Map fillblankMaps = quMaps.get("fillblankMaps"); + anCount += saveAnFillMaps(surveyAnswer, fillblankMaps); + // 多项填空题 + Map multifillblankMaps = quMaps.get("multifillblankMaps"); + anCount += saveAnMultiFillMaps(surveyAnswer, multifillblankMaps); + // 问答题 + Map answerMaps = quMaps.get("answerMaps"); + anCount += saveAnAnswerMaps(surveyAnswer, answerMaps); + // 复合单选题 + Map compRadioMaps = quMaps.get("compRadioMaps"); + anCount += saveCompAnRadioMaps(surveyAnswer, compRadioMaps); + // 复合多选题 + Map compCheckboxMaps = quMaps.get("compCheckboxMaps"); + anCount += saveCompAnCheckboxMaps(surveyAnswer, compCheckboxMaps); + // 枚举题 + Map enumMaps = quMaps.get("enumMaps"); + anCount += saveEnumMaps(surveyAnswer, enumMaps); + // 评分题 + Map scoreMaps = quMaps.get("scoreMaps"); + anCount += saveScoreMaps(surveyAnswer, scoreMaps); + // 排序题 quOrderMaps + Map quOrderMaps = quMaps.get("quOrderMaps"); + anCount += saveQuOrderMaps(surveyAnswer, quOrderMaps); + // 矩阵单选题 + Map chehRadioMaps = quMaps.get("chenRadioMaps"); + anCount += saveChenRadioMaps(surveyAnswer, chehRadioMaps); + // 矩阵多选题 + Map chehCheckboxMaps = quMaps.get("chenCheckboxMaps"); + anCount += saveChenCheckboxMaps(surveyAnswer, chehCheckboxMaps); + // 矩阵填空题 + Map chenFbkMaps = quMaps.get("chenFbkMaps"); + anCount += saveChenFbkMaps(surveyAnswer, chenFbkMaps); + // 复合矩阵单选题 + Map compChehRadioMaps = quMaps.get("compChenRadioMaps"); + anCount += saveCompChehRadioMaps(surveyAnswer, compChehRadioMaps); + // 矩阵填空题 + Map chenScoreMaps = quMaps.get("chenScoreMaps"); + anCount += saveChenScoreMaps(surveyAnswer, chenScoreMaps); + + surveyAnswer.put("completeItemNum", anCount); + int isComplete = 0; + if (anCount >= Integer.parseInt(surveyMation.get("anItemLeastNum").toString())) { + isComplete = 1; + } + surveyAnswer.put("isComplete", isComplete); + + int isEffective = 0; + if (anCount >= 0) {//只要回答一题即为有效 + isEffective = 1; + } + surveyAnswer.put("isEffective", isEffective); + surveyAnswer.put("completeNum", surveyMation.get("surveyQuNum")); + surveyAnswer.put("quNum", surveyMation.get("surveyQuNum")); + dwSurveyDirectoryDao.insertSurveyAnswer(surveyAnswer); + } + + /** + * 保存是非题答案 + * + * @param surveyAnswer + * @param yesnoMaps + * @return + */ + public int saveAnYesnoMaps(Map surveyAnswer, Map yesnoMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + List> beans = new ArrayList<>(); + int answerQuCount = 0; + if (yesnoMaps != null) { + for (String key : yesnoMaps.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("yesnoAnswer", yesnoMaps.get(key).toString()); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnYesnoMaps(beans); + } + return answerQuCount; + } + + private Map setCommonMation(String surveyId, String surveyAnswerId, String key) { + Map bean = new HashMap<>(); + bean.put("id", ToolUtil.getSurFaceId()); + bean.put("surveyId", surveyId); + bean.put("surveyAnswerId", surveyAnswerId); + bean.put("quId", key); + return bean; + } + + /** + * 保存单选题答案 + * + * @param surveyAnswer + * @param radioMaps + * @return + */ + private int saveAnRadioMaps(Map surveyAnswer, Map radioMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (radioMaps != null) { + for (String key : radioMaps.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemId", radioMaps.get(key).toString()); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnRadioMaps(beans); + } + return answerQuCount; + } + + /** + * 保存多项填空题答案 + * + * @param surveyAnswer + * @param dfillMaps + * @return + */ + private int saveAnMultiFillMaps(Map surveyAnswer, Map dfillMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (dfillMaps != null) { + Map map; + for (String key : dfillMaps.keySet()) { + map = (Map) dfillMaps.get(key); + if (map != null && map.size() > 0) { + for (String keyMap : map.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemId", keyMap); + bean.put("answerValue", !map.containsKey(keyMap) ? "" : map.get(keyMap).toString()); + beans.add(bean); + } + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnMultiFillMaps(beans); + } + return answerQuCount; + } + + /** + * 保存评分题 + * + * @param surveyAnswer + * @param scoreMaps + */ + private int saveScoreMaps(Map surveyAnswer, Map scoreMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (scoreMaps != null) { + Map mapRows; + for (String key : scoreMaps.keySet()) { + mapRows = (Map) scoreMaps.get(key); + for (String keyRow : mapRows.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("scoreValue", mapRows.get(keyRow).toString()); + beans.add(bean); + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveScoreMaps(beans); + } + return answerQuCount; + } + + /** + * 保存矩阵多选题 + * + * @param surveyAnswer + * @param chenCheckboxMaps + */ + private int saveChenCheckboxMaps(Map surveyAnswer, Map chenCheckboxMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (chenCheckboxMaps != null) { + Map mapRows, mapRow; + for (String key : chenCheckboxMaps.keySet()) { + mapRows = (Map) chenCheckboxMaps.get(key); + for (String keyRow : mapRows.keySet()) { + mapRow = (Map) mapRows.get(keyRow); + for (String keyCol : mapRow.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("colId", keyCol); + beans.add(bean); + } + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveChenCheckboxMaps(beans); + } + return answerQuCount; + } + + /** + * 复合单选题 + * + * @param surveyAnswer + * @param compRadioMaps + */ + private int saveCompAnRadioMaps(Map surveyAnswer, Map compRadioMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (compRadioMaps != null) { + Map tempAnRadio; + for (String key : compRadioMaps.keySet()) { + answerQuCount++; + tempAnRadio = (Map) compRadioMaps.get(key); + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemId", tempAnRadio.get("quItemId")); + bean.put("otherText", tempAnRadio.get("otherText")); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveCompAnRadioMaps(beans); + } + return answerQuCount; + } + + /** + * 复合矩阵单选题 + * + * @param surveyAnswer + * @param compChenRadioMaps + */ + private int saveCompChehRadioMaps(Map surveyAnswer, Map compChenRadioMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (compChenRadioMaps != null) { + Map mapRows, mapRow; + for (String key : compChenRadioMaps.keySet()) { + mapRows = (Map) compChenRadioMaps.get(key); + for (String keyRow : mapRows.keySet()) { + mapRow = (Map) mapRows.get(keyRow); + for (String keyCol : mapRow.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("colId", keyCol); + bean.put("optionId", mapRow.get(keyCol).toString()); + beans.add(bean); + } + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveCompChehRadioMaps(beans); + } + return answerQuCount; + } + + /** + * 矩陈评分题 + * + * @param surveyAnswer + * @param chenScoreMaps + * @return + */ + private int saveChenScoreMaps(Map surveyAnswer, Map chenScoreMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (chenScoreMaps != null) { + Map mapRows, mapRow; + for (String key : chenScoreMaps.keySet()) { + mapRows = (Map) chenScoreMaps.get(key); + for (String keyRow : mapRows.keySet()) { + mapRow = (Map) mapRows.get(keyRow); + for (String keyCol : mapRow.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("colId", keyCol); + bean.put("answerValue", mapRow.get(keyCol).toString()); + beans.add(bean); + } + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveChenScoreMaps(beans); + } + return answerQuCount; + } + + /** + * 保存多选题答案 + * + * @param surveyAnswer + * @param checkboxMaps + */ + private int saveAnCheckboxMaps(Map surveyAnswer, Map checkboxMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (checkboxMaps != null) { + Map map; + for (String key : checkboxMaps.keySet()) { + map = (Map) checkboxMaps.get(key); + for (String keyMap : map.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemId", map.get(keyMap).toString()); + beans.add(bean); + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnCheckboxMaps(beans); + } + return answerQuCount; + } + + /** + * 保存单项填空题答案 + * + * @param surveyAnswer + * @param fillMaps + */ + private int saveAnFillMaps(Map surveyAnswer, Map fillMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (fillMaps != null) { + for (String key : fillMaps.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("answerValue", fillMaps.get(key).toString()); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnFillMaps(beans); + } + return answerQuCount; + } + + /** + * 保存判断题答案 + * + * @param surveyAnswer + * @param anAnswerMaps + */ + private int saveAnAnswerMaps(Map surveyAnswer, Map anAnswerMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (anAnswerMaps != null) { + for (String key : anAnswerMaps.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("answerValue", anAnswerMaps.get(key).toString()); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveAnAnswerMaps(beans); + } + return answerQuCount; + } + + /** + * 保存复合多选题答案 + * + * @param surveyAnswer + * @param compCheckboxMaps + */ + private int saveCompAnCheckboxMaps(Map surveyAnswer, Map compCheckboxMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (compCheckboxMaps != null) { + Map map, tempAnCheckbox; + for (String key : compCheckboxMaps.keySet()) { + map = (Map) compCheckboxMaps.get(key); + for (String keyMap : map.keySet()) { + answerQuCount++; + tempAnCheckbox = (Map) map.get(keyMap); + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemId", tempAnCheckbox.get("quItemId")); + bean.put("otherText", tempAnCheckbox.get("otherText")); + beans.add(bean); + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveCompAnCheckboxMaps(beans); + } + return answerQuCount; + } + + /** + * 保存枚举题 + * + * @param surveyAnswer + * @param enumMaps + */ + private int saveEnumMaps(Map surveyAnswer, Map enumMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (enumMaps != null) { + for (String key : enumMaps.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("quItemNum", Integer.parseInt(key.split("_")[1])); + bean.put("answerValue", enumMaps.get(key).toString()); + beans.add(bean); + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveEnumMaps(beans); + } + return answerQuCount; + } + + /** + * 保存排序题 + * + * @param surveyAnswer + * @param quOrderMaps + */ + private int saveQuOrderMaps(Map surveyAnswer, Map quOrderMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (quOrderMaps != null) { + Map mapRows; + for (String key : quOrderMaps.keySet()) { + mapRows = (Map) quOrderMaps.get(key); + for (String keyRow : mapRows.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("orderNumValue", mapRows.get(keyRow).toString()); + beans.add(bean); + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveQuOrderMaps(beans); + } + return answerQuCount; + } + + /** + * 保存矩阵单选题 + * + * @param surveyAnswer + * @param chenRadioMaps + */ + private int saveChenRadioMaps(Map surveyAnswer, Map chenRadioMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (chenRadioMaps != null) { + Map mapRows; + for (String key : chenRadioMaps.keySet()) { + mapRows = (Map) chenRadioMaps.get(key); + for (String keyRow : mapRows.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("colId", mapRows.get(keyRow).toString()); + beans.add(bean); + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveChenRadioMaps(beans); + } + return answerQuCount; + } + + /** + * 保存矩阵填空题 + * + * @param surveyAnswer + * @param chenFbkMaps + */ + private int saveChenFbkMaps(Map surveyAnswer, Map chenFbkMaps) { + String surveyId = surveyAnswer.get("id").toString(); + String surveyAnswerId = surveyAnswer.get("answerId").toString(); + int answerQuCount = 0; + List> beans = new ArrayList<>(); + if (chenFbkMaps != null) { + Map mapRows, mapRow; + for (String key : chenFbkMaps.keySet()) { + mapRows = (Map) chenFbkMaps.get(key); + for (String keyRow : mapRows.keySet()) { + mapRow = (Map) mapRows.get(keyRow); + for (String keyCol : mapRow.keySet()) { + answerQuCount++; + Map bean = setCommonMation(surveyId, surveyAnswerId, key); + bean.put("rowId", keyRow); + bean.put("colId", keyCol); + bean.put("answerValue", mapRow.get(keyCol).toString()); + beans.add(bean); + } + } + } + } + if (!beans.isEmpty()) { + dwSurveyDirectoryDao.saveChenFbkMaps(beans); + } + return answerQuCount; + } + + /** + * 手动结束问卷 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void updateSurveyMationEndById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(id); + if (surveyMation != null && !surveyMation.isEmpty()) { + if ("1".equals(surveyMation.get("surveyState").toString())) {//执行中 + map.put("realEndTime", DateUtil.getTimeAndToString()); + dwSurveyDirectoryDao.updateSurveyMationEndById(map); + } + } else { + outputObject.setreturnMessage("该试卷信息不存在。"); + } + } + +} diff --git a/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/xxljob/EndSurveyMationService.java b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/xxljob/EndSurveyMationService.java new file mode 100644 index 0000000..aa7b4eb --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/java/com/skyeye/eve/xxljob/EndSurveyMationService.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.xxljob; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.dao.DwSurveyDirectoryDao; +import com.skyeye.eve.service.IQuartzService; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: EndSurveyMationService + * @Description: 问卷调查 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 16:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class EndSurveyMationService { + + @Autowired + private DwSurveyDirectoryDao dwSurveyDirectoryDao; + + @Autowired + private IQuartzService iQuartzService; + + @XxlJob("endSurveyMationService") + public void call() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String surveyId = paramMap.get("objectId"); + // 获取问卷信息 + Map surveyMation = dwSurveyDirectoryDao.querySurveyMationById(surveyId); + if ("1".equals(surveyMation.get("surveyState").toString())) { + // 执行中可以设置结束时间 + Map map = new HashMap<>(); + map.put("id", surveyId); + map.put("realEndTime", DateUtil.getTimeAndToString()); + dwSurveyDirectoryDao.editSurveyStateToEndNumZdById(map); + } + iQuartzService.stopAndDeleteTaskQuartz(paramMap.get("objectId")); + } + +} diff --git a/skyeye-adm/adm-survey/src/main/resources/mapper/survey/DwSurveyDirectoryMapper.xml b/skyeye-adm/adm-survey/src/main/resources/mapper/survey/DwSurveyDirectoryMapper.xml new file mode 100644 index 0000000..86b65aa --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/resources/mapper/survey/DwSurveyDirectoryMapper.xml @@ -0,0 +1,1554 @@ + + + + + + + + INSERT into dw_survey_directory + (id, survey_name, sid, dir_type, survey_model, survey_note, create_id, create_time) + VALUES + (#{id}, #{surveyName}, #{sId}, #{dirType}, #{surveyModel}, #{surveyNote}, #{createId}, #{createTime}) + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE dw_survey_directory + + effective = #{effective}, + effective_ip = #{effectiveIp}, + rule = #{rule}, + rule_code = #{ruleCode}, + refresh = #{refresh}, + yn_end_num = #{ynEndNum}, + end_num = #{endNum}, + yn_end_time = #{ynEndTime}, + + end_time = #{endTime}, + + + WHERE id = #{id} + + + + INSERT into dw_question + (id, answer_input_row, answer_input_width, belong_id, cell_count, check_type, contacts_attr, contacts_field, copy_from_id, hv, is_required, + keywords, order_by_id, param_int01, param_int02, parent_qu_id, qu_name, qu_note, qu_tag, qu_title, qu_type, rand_order, tag, visibility, + yesno_option, create_time) + VALUES + (#{id}, #{answerInputRow}, #{answerInputWidth}, #{belongId}, #{cellCount}, #{checkType}, #{contactsAttr}, #{contactsField}, #{copyFormId}, #{hv}, #{isRequired}, + #{keywords}, #{orderById}, #{paramInt01}, #{paramInt02}, #{parentQuId}, #{quName}, #{quNote}, #{quTag}, #{quTitle}, #{quType}, #{randOrder}, #{tag}, #{visibility}, + #{yesnoOption}, #{createTime}) + + + + insert into dw_question_logic + (id, title, cg_qu_item_id, ck_qu_id, ge_le, logic_type, score_num, sk_qu_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.title}, #{item.cgQuItemId}, #{item.ckQuId}, #{item.geLe}, #{item.logicType}, + #{item.scoreNum}, #{item.skQuId}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_question_logic + + title = #{item.title}, + cg_qu_item_id = #{item.cgQuItemId}, + ge_le = #{item.geLe}, + logic_type = #{item.logicType}, + score_num = #{item.scoreNum}, + sk_qu_id = #{item.skQuId}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_score + (id, qu_id, option_name, option_title, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_score + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_orderby + (id, qu_id, option_name, option_title, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_orderby + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_radio + (id, qu_id, option_name, option_title, check_type, is_note, is_required_fill, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.isNote}, + #{item.isRequiredFill}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_radio + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + check_type = #{item.checkType}, + is_note = #{item.isNote}, + is_required_fill = #{item.isRequiredFill}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_checkbox + (id, qu_id, option_name, option_title, check_type, is_note, is_required_fill, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.isNote}, + #{item.isRequiredFill}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_checkbox + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + check_type = #{item.checkType}, + is_note = #{item.isNote}, + is_required_fill = #{item.isRequiredFill}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_multi_fillblank + (id, qu_id, option_name, option_title, check_type, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_multi_fillblank + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_chen_column + (id, qu_id, option_name, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_chen_column + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + + WHERE id = #{item.id} + + + + + insert into dw_qu_chen_row + (id, qu_id, option_name, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + UPDATE dw_qu_chen_row + + order_by_id = #{item.orderById}, + option_name = #{item.optionName}, + + WHERE id = #{item.id} + + + + + + + UPDATE dw_question + + visibility = '0', + + WHERE id = #{quId} + + + + DELETE + FROM + dw_question + WHERE + id = #{quId} + + + + DELETE + FROM + ${tableName} + WHERE + ${key} = #{quId} + + + + UPDATE dw_question + + order_by_id = (order_by_id - 1), + + WHERE order_by_id > #{orderById} + AND belong_id = #{belongId} + + + + + + UPDATE dw_qu_chen_column + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_chen_column + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_chen_row + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_chen_row + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_radio + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_radio + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_checkbox + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_checkbox + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_score + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_score + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_orderby + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_orderby + WHERE + id = #{quItemId} + + + + + + UPDATE dw_qu_multi_fillblank + + visibility = '0', + + WHERE id = #{quItemId} + + + + DELETE + FROM + dw_qu_multi_fillblank + WHERE + id = #{quItemId} + + + + UPDATE dw_question + + + answer_input_row = #{answerInputRow}, + + + answer_input_width = #{answerInputWidth}, + + + cell_count = #{cellCount}, + + + check_type = #{checkType}, + + + contacts_attr = #{contactsAttr}, + + + contacts_field = #{contactsField}, + + + hv = #{hv}, + + + is_required = #{isRequired}, + + + order_by_id = #{orderById}, + + + param_int01 = #{paramInt01}, + + + param_int02 = #{paramInt02}, + + + qu_name = #{quName}, + + + qu_note = #{quNote}, + + + qu_tag = #{quTag}, + + + qu_title = #{quTitle}, + + + rand_order = #{randOrder}, + + + WHERE id = #{quId} + + + + UPDATE dw_survey_directory + + visibility = '0', + + WHERE id = #{id} + + + + UPDATE dw_survey_directory + + survey_state = '1', + real_start_time = #{startTime}, + survey_qu_num = #{questionNum}, + an_item_least_num = #{questionNum}, + + WHERE id = #{id} + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT into dw_survey_directory (id, survey_name, sid, dir_type, survey_model, survey_note, create_id, create_time, + survey_qu_num, an_item_least_num, an_item_most_num, effective, effective_ip, effective_time, yn_end_num, end_num, + yn_end_time, end_time, rule, rule_code, answer_num, refresh, excerpt_num, is_share, mail_only, view_answer) + SELECT #{id}, #{surveyName}, #{sId}, #{dirType}, #{surveyModel}, survey_note, #{createId}, #{createTime}, + survey_qu_num, an_item_least_num, an_item_most_num, effective, effective_ip, effective_time, yn_end_num, end_num, + yn_end_time, end_time, rule, rule_code, answer_num, refresh, excerpt_num, is_share, mail_only, view_answer FROM dw_survey_directory WHERE id = #{surveyCopyId} AND visibility = '1' + + + + + + INSERT into dw_question + (id, answer_input_row, answer_input_width, belong_id, cell_count, check_type, contacts_attr, contacts_field, copy_from_id, hv, is_required, + keywords, order_by_id, param_int01, param_int02, parent_qu_id, qu_name, qu_note, qu_tag, qu_title, qu_type, rand_order, tag, visibility, + yesno_option, create_time) + VALUES + + (#{item.id}, #{item.answerInputRow}, #{item.answerInputWidth}, #{item.belongId}, #{item.cellCount}, #{item.checkType}, #{item.contactsAttr}, #{item.contactsField}, + #{item.copyFormId}, #{item.hv}, #{item.isRequired}, #{item.keywords}, #{item.orderById}, #{item.paramInt01}, #{item.paramInt02}, #{item.parentQuId}, #{item.quName}, + #{item.quNote}, #{item.quTag}, #{item.quTitle}, #{item.quType}, #{item.randOrder}, #{item.tag}, #{item.visibility}, #{item.yesnoOption}, #{item.createTime}) + + + + + + + insert into dw_qu_radio + (id, qu_id, option_name, option_title, check_type, is_note, is_required_fill, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.isNote}, + #{item.isRequiredFill}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + insert into dw_qu_checkbox + (id, qu_id, option_name, option_title, check_type, is_note, is_required_fill, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.isNote}, + #{item.isRequiredFill}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + insert into dw_qu_multi_fillblank + (id, qu_id, option_name, option_title, check_type, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.checkType}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + insert into dw_qu_chen_row + (id, qu_id, option_name, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + insert into dw_qu_chen_column + (id, qu_id, option_name, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + + + insert into dw_qu_score + (id, qu_id, option_name, option_title, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + + + insert into dw_qu_orderby + (id, qu_id, option_name, option_title, order_by_id, visibility, create_id, create_time) + values + + (#{item.id}, #{item.quId}, #{item.optionName}, #{item.optionTitle}, #{item.orderById}, #{item.visibility}, #{item.createId}, #{item.createTime}) + + + + + UPDATE dw_survey_directory + + answer_num = #{answerNum}, + + WHERE id = #{id} + + + + insert into dw_an_yesno + (id, belong_answer_id, belong_id, qu_id, visibility, yesno_answer) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.quId}, '1', #{item.yesnoAnswer}) + + + + + insert into dw_an_radio + (id, belong_answer_id, belong_id, other_text, qu_id, visibility, qu_item_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.otherText}, #{item.quId}, '1', #{item.quItemId}) + + + + + insert into dw_an_dfillblank + (id, answer, belong_answer_id, belong_id, qu_id, visibility, qu_item_id) + values + + (#{item.id}, #{item.answerValue}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.quId}, '1', #{item.quItemId}) + + + + + insert into dw_an_score + (id, answser_score, belong_answer_id, belong_id, qu_id, visibility, qu_row_id) + values + + (#{item.id}, #{item.scoreValue}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.quId}, '1', #{item.rowId}) + + + + + insert into dw_an_chen_checkbox + (id, belong_answer_id, belong_id, qu_id, visibility, qu_row_id, qu_col_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.quId}, '1', #{item.rowId}, #{item.colId}) + + + + + insert into dw_an_radio + (id, belong_answer_id, belong_id, other_text, qu_id, visibility, qu_item_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.otherText}, #{item.quId}, '1', #{item.quItemId}) + + + + + insert into dw_an_comp_chen_radio + (id, belong_answer_id, belong_id, qu_col_id, qu_id, visibility, qu_option_id, qu_row_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.colId}, #{item.quId}, '1', #{item.optionId}, #{item.rowId}) + + + + + insert into dw_an_chen_score + (id, belong_answer_id, belong_id, qu_col_id, qu_id, visibility, answser_score, qu_row_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.colId}, #{item.quId}, '1', #{item.answerValue}, #{item.rowId}) + + + + + insert into dw_an_checkbox + (id, belong_answer_id, belong_id, other_text, qu_id, visibility, qu_item_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.otherText}, #{item.quId}, '1', #{item.quItemId}) + + + + + insert into dw_an_fillblank + (id, belong_answer_id, belong_id, answer, qu_id, visibility) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.answerValue}, #{item.quId}, '1') + + + + + insert into dw_an_answer + (id, belong_answer_id, belong_id, answer, qu_id, visibility) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.answerValue}, #{item.quId}, '1') + + + + + insert into dw_an_checkbox + (id, belong_answer_id, belong_id, other_text, qu_id, visibility, qu_item_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.otherText}, #{item.quId}, '1', #{item.quItemId}) + + + + + insert into dw_an_enumqu + (id, belong_answer_id, belong_id, answer, qu_id, visibility, enum_item) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.answerValue}, #{item.quId}, '1', #{item.quItemNum}) + + + + + insert into dw_an_order + (id, belong_answer_id, belong_id, ordery_num, qu_id, visibility, qu_row_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.orderNumValue}, #{item.quId}, '1', #{item.rowId}) + + + + + insert into dw_an_chen_radio + (id, belong_answer_id, belong_id, qu_col_id, qu_id, visibility, qu_row_id) + values + + (#{item.id}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.colId}, #{item.quId}, '1', #{item.rowId}) + + + + + insert into dw_an_chen_fbk + (id, answer_value, belong_answer_id, belong_id, qu_col_id, qu_id, visibility, qu_row_id) + values + + (#{item.id}, #{item.answerValue}, #{item.surveyAnswerId}, #{item.surveyId}, #{item.colId}, #{item.quId}, '1', #{item.rowId}) + + + + + INSERT into dw_survey_answer + (id, survey_id, bg_an_date, end_an_date, complete_num, complete_item_num, data_source, handle_state, ip_addr, addr, city, is_complete, is_effective, + qu_num, total_time, create_id) + VALUES + (#{answerId}, #{id}, #{bgAnDate}, #{endAnDate}, #{completeNum}, #{completeItemNum}, '0', '1', #{ipAddr}, #{addr}, #{city}, #{isComplete}, #{isEffective}, + #{quNum}, #{totalTime}, #{createId}) + + + + + + + + UPDATE dw_survey_directory + + real_end_time = #{realEndTime}, + survey_state = '2', + end_type = '3', + + WHERE id = #{id} + + + + UPDATE dw_survey_directory + + real_end_time = #{realEndTime}, + survey_state = '2', + end_type = '1', + + WHERE id = #{id} + + + + UPDATE dw_survey_directory + + real_end_time = #{realEndTime}, + survey_state = '2', + end_type = '2', + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-adm/adm-survey/src/main/resources/reqmapping/mapping/survey.xml b/skyeye-adm/adm-survey/src/main/resources/reqmapping/mapping/survey.xml new file mode 100644 index 0000000..edcc70b --- /dev/null +++ b/skyeye-adm/adm-survey/src/main/resources/reqmapping/mapping/survey.xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-web/.gitignore b/skyeye-adm/adm-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-adm/adm-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-adm/adm-web/pom.xml b/skyeye-adm/adm-web/pom.xml new file mode 100644 index 0000000..1e7d33e --- /dev/null +++ b/skyeye-adm/adm-web/pom.xml @@ -0,0 +1,97 @@ + + + + skyeye-adm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + adm-web + + + 8 + 8 + + + + + + com.skyeye + adm-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + true + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-adm/adm-web/src/main/java/com/AdmApplication.java b/skyeye-adm/adm-web/src/main/java/com/AdmApplication.java new file mode 100644 index 0000000..d50cbd1 --- /dev/null +++ b/skyeye-adm/adm-web/src/main/java/com/AdmApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class AdmApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(AdmApplication.class, args); + } + +} diff --git a/skyeye-adm/adm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-adm/adm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..049e97f --- /dev/null +++ b/skyeye-adm/adm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-adm/adm-web/src/main/resources/banner.txt b/skyeye-adm/adm-web/src/main/resources/banner.txt new file mode 100644 index 0000000..8f59551 --- /dev/null +++ b/skyeye-adm/adm-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev adm-web.jar >> /opt/service/project/nohup-adm.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-adm/adm-web/src/main/resources/bootstrap.yml b/skyeye-adm/adm-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..4e13627 --- /dev/null +++ b/skyeye-adm/adm-web/src/main/resources/bootstrap.yml @@ -0,0 +1,70 @@ +server: + port: 8103 + +spring: + application: + name: skyeye-adm-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # 考勤相关的服务 + skyeye-checkwork: skyeye-checkwork-${spring.profiles.active} + +topic: + # 资产生成条形码的消息 + asset-generate-barcode: ASSET_GENERATE_BARCODE + # 收件箱邮件获取的topic + mail-access-inbox-service: MAIL_ACCESS_INBOX_SERVICE + # 已发送邮件获取的TOPIC + mail-access-sended-service: MAIL_ACCESS_SENDED_SERVICE + # 已删除邮件获取的topic + mail-access-delete-service: MAIL_ACCESS_DELETE_SERVICE + # 草稿箱邮件获取的topic + mail-access-drafts-service: MAIL_ACCESS_DRAFTS_SERVICE + # 邮件发送的topic + complex-mail-delivery-service: COMPLEX_MAIL_DELIVERY_SERVICE + # 保存草稿同步的topic + mail-drafts-save-service: MAIL_DRAFTS_SAVE_SERVICE + # 草稿编辑同步的topic + mail-drafts-edit-service: MAIL_DRAFTS_EDIT_SERVICE + # 草稿箱邮件发送的topic + mail-drafts-send-service: MAIL_DRAFTS_SEND_SERVICE + # 笔记输出为压缩包的topic + output-notes-is-zip-service: OUTPUT_NOTES_IS_ZIP_SERVICE + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-adm/adm-web/src/main/resources/jvm调优参数配置 b/skyeye-adm/adm-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-adm/adm-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-adm/adm-web/src/main/resources/log4j.properties b/skyeye-adm/adm-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-adm/adm-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-adm/pom.xml b/skyeye-adm/pom.xml new file mode 100644 index 0000000..0652f81 --- /dev/null +++ b/skyeye-adm/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + pom + + adm-common + adm-pro + adm-web + adm-survey + adm-ehr + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-adm + 1.0-SNAPSHOT + + + + + + org.apache.solr + solr-solrj + + + + + \ No newline at end of file diff --git a/skyeye-ai/.gitignore b/skyeye-ai/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-ai/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ai/ai-common/.gitignore b/skyeye-ai/ai-common/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-ai/ai-common/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ai/ai-common/pom.xml b/skyeye-ai/ai-common/pom.xml new file mode 100644 index 0000000..41dc20e --- /dev/null +++ b/skyeye-ai/ai-common/pom.xml @@ -0,0 +1,29 @@ + + + + skyeye-ai + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ai-common + + + UTF-8 + + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-ai/ai-common/src/main/java/com/skyeye/executor/ExecutorConfig.java b/skyeye-ai/ai-common/src/main/java/com/skyeye/executor/ExecutorConfig.java new file mode 100644 index 0000000..bc86f60 --- /dev/null +++ b/skyeye-ai/ai-common/src/main/java/com/skyeye/executor/ExecutorConfig.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.executor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +/** + * @ClassName: ExecutorConfig + * @Description: 异步任务配置类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 22:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@ManagedResource +public class ExecutorConfig { + + @Bean(name = "messageStreamExecutor") + public Executor getDetailsAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(5); + executor.setQueueCapacity(1000000); + executor.setThreadNamePrefix("messageStreamExecutor-"); + executor.initialize(); + return executor; + } +} diff --git a/skyeye-ai/ai-pro/.gitignore b/skyeye-ai/ai-pro/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-ai/ai-pro/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ai/ai-pro/pom.xml b/skyeye-ai/ai-pro/pom.xml new file mode 100644 index 0000000..7fdf996 --- /dev/null +++ b/skyeye-ai/ai-pro/pom.xml @@ -0,0 +1,103 @@ + + + + skyeye-ai + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ai-pro + + + UTF-8 + + 0.9.5.2 + 1.0.25 + + + + + + + com.skyeye + ai-common + 1.0-SNAPSHOT + + + + org.apache.commons + commons-dbcp2 + 2.1.1 + + + + com.jayway.jsonpath + json-path + 2.8.0 + + + + + com.mchange + c3p0 + ${c3p0.version} + + + com.alibaba + druid + ${druid.version} + + + + com.baidubce + qianfan + 0.1.1 + + + + io.github.briqt + xunfei-spark4j + 1.2.0 + + + + + + + com.alibaba + dashscope-sdk-java + 2.14.4 + + + + + + cn.bigmodel.openapi + oapi-java-sdk + release-V4-2.0.0 + + + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + com.squareup.okhttp3 + okhttp-sse + 4.9.3 + + + + org.springframework.boot + spring-boot-starter-webflux + 3.3.4 + + + + + \ No newline at end of file diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/AiConfiguration.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/AiConfiguration.java new file mode 100644 index 0000000..9e75094 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/AiConfiguration.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ai.core.config; + +import com.skyeye.ai.core.factory.AiFactory; +import com.skyeye.ai.core.factory.AiFactoryImpl; +import io.github.briqt.spark4j.SparkClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: AiConfiguration + * @Description: AI配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@EnableConfigurationProperties(SkyeyeAiProperties.class) +public class AiConfiguration { + + @Bean + public AiFactory aiClientFactory() { + return new AiFactoryImpl(); + } + +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/SkyeyeAiProperties.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/SkyeyeAiProperties.java new file mode 100644 index 0000000..0d5f399 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/config/SkyeyeAiProperties.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ai.core.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @ClassName: SkyeyeAiProperties + * @Description: Skyeye AI 配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 18:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ConfigurationProperties(prefix = "spring.ai") +public class SkyeyeAiProperties { + + private QianfanProperties qianfan; + + private XunfeiProperties xunfei; + + private DeepseekProperties deepSeek; + + private TongyiProperties tongYi; + + private ZhupuProperties zhiPu; + + @Data + public static class QianfanProperties { + private String apiKey; + private String secretKey; + } + + @Data + public static class XunfeiProperties { + private String appId; + private String apiKey; + private String secretKey; + } + + @Data + public static class DeepseekProperties { + private String apiKey; + private String secretKey = "DEEP_SEEK"; + private String url; + } + + @Data + public static class TongyiProperties { + private String apiKey; + private String secretKey = "TONG_YI"; + private String message; + } + + @Data + public static class ZhupuProperties { + private String apiKey; + private String secretKey; + private String url; + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/enums/AiPlatformEnum.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/enums/AiPlatformEnum.java new file mode 100644 index 0000000..ce5a16d --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/enums/AiPlatformEnum.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ai.core.enums; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.exception.CustomException; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AiPlatformEnum + * @Description: AI 模型平台 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 11:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AiPlatformEnum implements SkyeyeEnumClass { + + YI_YAN("YiYan", "文心一言", "百度", true, false), + XUN_FEI("XunFei", "讯飞星火", "讯飞", true, false), + DEEP_SEEK("DeepSeek","DeepSeek","豆包", true, false), + TONG_YI("TongYi","通义千问","阿里", true, false), + ZHI_PU("ZhiPu","智普","智普AI", true, false),; + + private String key; + + private String value; + + private String remark; + + private Boolean show; + + private Boolean isDefault; + + public static AiPlatformEnum getName(String key) { + for (AiPlatformEnum bean : AiPlatformEnum.values()) { + if (StrUtil.equals(key, bean.getKey())) { + return bean; + } + } + throw new CustomException("非法的AI平台状态"); + } + + public static AiPlatformEnum getValue(String value) { + for (AiPlatformEnum bean : AiPlatformEnum.values()) { + if (StrUtil.equals(value, bean.getValue())) { + return bean; + } + } + throw new CustomException("非法的AI平台状态"); + } + +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactory.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactory.java new file mode 100644 index 0000000..44f16d6 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ai.core.factory; + +import com.skyeye.ai.core.enums.AiPlatformEnum; + +/** + * @ClassName: AiFactory + * @Description: AI Model 模型工厂的接口类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 11:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AiFactory { + + /** + * 基于指定配置,获得 ChatModel 对象 + *

+ * 如果不存在,则进行创建 + * + * @param platform 平台 + * @param apiKey API KEY + * @param url API URL + * @return ChatModel 对象 + */ + Object getOrCreateChatModel(AiPlatformEnum platform, String apiKey, String secretKey, String url); + + /** + * 基于默认配置,获得 ChatModel 对象 + *

+ * 默认配置,指的是在 application.yaml 配置文件中的 spring.ai 相关的配置 + * + * @param platform 平台 + * @return ChatModel 对象 + */ + Object getDefaultChatModel(AiPlatformEnum platform); + + /** + * 基于默认配置,获得 ImageModel 对象 + *

+ * 默认配置,指的是在 application.yaml 配置文件中的 spring.ai 相关的配置 + * + * @param platform 平台 + * @return ImageModel 对象 + */ + Object getDefaultImageModel(AiPlatformEnum platform); + + /** + * 基于指定配置,获得 ImageModel 对象 + *

+ * 如果不存在,则进行创建 + * + * @param platform 平台 + * @param apiKey API KEY + * @param url API URL + * @return ImageModel 对象 + */ + Object getOrCreateImageModel(AiPlatformEnum platform, String apiKey, String url); + +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactoryImpl.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactoryImpl.java new file mode 100644 index 0000000..2e8acac --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/ai/core/factory/AiFactoryImpl.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ai.core.factory; + +import cn.hutool.core.lang.Singleton; +import cn.hutool.core.lang.func.Func0; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.alibaba.dashscope.aigc.generation.Generation; +import com.baidubce.qianfan.Qianfan; +import com.baidubce.qianfan.core.auth.Auth; +import com.skyeye.ai.core.config.SkyeyeAiProperties; +import com.skyeye.ai.core.enums.AiPlatformEnum; +import com.skyeye.exception.CustomException; +import com.zhipu.oapi.ClientV4; +import io.github.briqt.spark4j.SparkClient; +import org.springframework.beans.factory.annotation.Autowired; + + +/** + * @ClassName: AiFactoryImpl + * @Description: AI Model 模型工厂的实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 14:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class AiFactoryImpl implements AiFactory { + + @Autowired + private SkyeyeAiProperties skyeyeAiProperties; + + @Override + public Object getOrCreateChatModel(AiPlatformEnum platform, String apiKey, String secretKey, String url) { + String cacheKey = buildClientCacheKey(platform, apiKey, url); + return Singleton.get(cacheKey, (Func0) () -> { + switch (platform) { + case YI_YAN: + return buildYiYanChatModel(apiKey, secretKey); + case XUN_FEI: + return buildXunFeiClient( + skyeyeAiProperties.getXunfei().getAppId(),apiKey,secretKey); + case DEEP_SEEK: + // todo deepseek AI + return null; + case TONG_YI: + return buildTongYiChatClient(); + case ZHI_PU: + // todo ZhiPu AI + return buildZhiPuChatClient(skyeyeAiProperties.getZhiPu().getApiKey(), + skyeyeAiProperties.getZhiPu().getSecretKey()); + default: + throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); + } + }); + } + + @Override + public Object getDefaultChatModel(AiPlatformEnum platform) { + switch (platform) { + case YI_YAN: + return getOrCreateChatModel(platform, + skyeyeAiProperties.getQianfan().getApiKey(), + skyeyeAiProperties.getQianfan().getSecretKey(), + null); + case XUN_FEI: + return getOrCreateChatModel(platform, + skyeyeAiProperties.getXunfei().getApiKey(), + skyeyeAiProperties.getXunfei().getSecretKey(), + null); + case DEEP_SEEK: + return getOrCreateChatModel(platform, + skyeyeAiProperties.getDeepSeek().getApiKey(), + skyeyeAiProperties.getDeepSeek().getSecretKey(), + skyeyeAiProperties.getDeepSeek().getUrl()); + case TONG_YI: + return getOrCreateChatModel(platform, + skyeyeAiProperties.getTongYi().getApiKey(), + skyeyeAiProperties.getTongYi().getSecretKey(), + null); + case ZHI_PU: + return getOrCreateChatModel(platform, + skyeyeAiProperties.getZhiPu().getApiKey(), + skyeyeAiProperties.getZhiPu().getSecretKey(), + skyeyeAiProperties.getZhiPu().getUrl()); + default: + return null; + } +// return getOrCreateChatModel(platform, skyeyeAiProperties.getQianfan().getApiKey(), skyeyeAiProperties.getQianfan().getSecretKey(), null); + } + + @Override + public Object getDefaultImageModel(AiPlatformEnum platform) { + switch (platform) { + case YI_YAN: +// return SpringUtil.getBean(Qianfan.class); + default: + throw new CustomException(StrUtil.format("未知平台({})", platform)); + } + } + + @Override + public Object getOrCreateImageModel(AiPlatformEnum platform, String apiKey, String url) { + switch (platform) { + case YI_YAN: + default: + throw new CustomException(StrUtil.format("未知平台({})", platform)); + } + } + + private static String buildClientCacheKey(Object... params) { + if (ArrayUtil.isEmpty(params)) { + throw new CustomException("请指定参数"); + } + return StrUtil.format("{}", ArrayUtil.join(params, "_")); + } + + // ========== 各种创建 spring-ai 客户端的方法 ========== + + private static Qianfan buildYiYanChatModel(String apiKey, String secretKey) { + Qianfan qianFanApi = new Qianfan(Auth.TYPE_OAUTH, apiKey, secretKey); + return qianFanApi; + } + + private static SparkClient buildXunFeiClient(String appId, String apiKey, String secretKey) { + SparkClient xunFeiApi = new SparkClient(); + xunFeiApi.appid = appId; + xunFeiApi.apiKey = apiKey; + xunFeiApi.apiSecret = secretKey; + return xunFeiApi; + } + + + private static Generation buildTongYiChatClient() { + return new Generation(); + } + + private static ClientV4 buildZhiPuChatClient(String apiKey,String secretKey) { + return new ClientV4.Builder(apiKey,secretKey).build(); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/aiStreamModle/SparkListener.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/aiStreamModle/SparkListener.java new file mode 100644 index 0000000..1c92845 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/aiStreamModle/SparkListener.java @@ -0,0 +1,63 @@ +package com.skyeye.aiStreamModle; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.github.briqt.spark4j.constant.SparkApiVersion; +import io.github.briqt.spark4j.listener.SparkConsoleListener; +import io.github.briqt.spark4j.model.SparkMessage; +import io.github.briqt.spark4j.model.request.SparkRequest; +import io.github.briqt.spark4j.model.response.SparkResponse; +import io.github.briqt.spark4j.model.response.SparkResponseUsage; +import io.github.briqt.spark4j.model.response.SparkTextUsage; +import okhttp3.WebSocket; + +import java.util.List; + +/** + * @ClassName: SparkConsoleListener + * @Description: AI流式处理类 + * @author: skyeye云系列--lqy + * @date: 2024/10/20 22:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class SparkListener extends SparkConsoleListener { + + private final StringBuilder stringBuilder = new StringBuilder(); + + public SparkListener() { + super(); + } + + @Override + public void onMessage(String content, SparkResponseUsage usage, Integer status, SparkRequest sparkRequest, SparkResponse sparkResponse, WebSocket webSocket) { + this.stringBuilder.append(content); + if (0 == status) { + List messages = sparkRequest.getPayload().getMessage().getText(); + + try { + SparkApiVersion apiVersion = sparkRequest.getApiVersion(); + System.out.println("请求地址:" + apiVersion.getUrl() + " 版本:" + apiVersion.getVersion()); + System.out.println("\n提问:" + this.objectMapper.writeValueAsString(messages)); + } catch (JsonProcessingException var10) { + JsonProcessingException e = var10; + throw new RuntimeException(e); + } + + System.out.println("\n收到回答:\n"); + } + + try { + System.out.println("--content:" + content + " --完整响应:" + this.objectMapper.writeValueAsString(sparkResponse)); + } catch (JsonProcessingException var9) { + JsonProcessingException e = var9; + throw new RuntimeException(e); + } + + if (2 == status) { + System.out.println("\n完整回答:" + this.stringBuilder); + SparkTextUsage textUsage = usage.getText(); + System.out.println("\n回答结束;提问tokens:" + textUsage.getPromptTokens() + ",回答tokens:" + textUsage.getCompletionTokens() + ",总消耗tokens:" + textUsage.getTotalTokens()); + } + + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/controller/ChatController.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/controller/ChatController.java new file mode 100644 index 0000000..ece218b --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/controller/ChatController.java @@ -0,0 +1,65 @@ +package com.skyeye.chat.controller; + + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.chat.service.ChatService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ChatController + * @Description: 聊天记录控制层 + * @author: skyeye云系列--lqy + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "聊天记录管理", tags = "聊天记录管理", modelName = "聊天记录管理") +public class ChatController { + + @Autowired + private ChatService chatService; + + @ApiOperation(id = "sendChatMessage", value = "发送消息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "content", name = "content", value = "消息", required = "required"), + @ApiImplicitParam(id = "apiKeyId", name = "apiKeyId", value = "AI配置id", required = "required") + }) + @RequestMapping("/post/ChatController/sendChatMessage") + public void sendChatMessage(InputObject inputObject, OutputObject outputObject) { + chatService.sendChatMessage(inputObject, outputObject); + } + + @ApiOperation(id = "queryPageMessageList", value = "分页查询聊天记录", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ChatController/queryPageMessageList") + public void queryPageMessageList(InputObject inputObject, OutputObject outputObject) { + chatService.queryPageMessageList(inputObject, outputObject); + } + + @ApiOperation(id = "deleteChatMessageByIds", value = "批量删除聊天记录", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/ChatController/deleteChatMessageByIds") + public void deleteChatMessageByIds(InputObject inputObject, OutputObject outputObject) { + chatService.deleteByIds(inputObject, outputObject); + } + + + @ApiOperation(id = "deleteAllByApiKeyId", value = "根据apiKeyId一键删除记录", method = "POST", allUse = "2") + @ApiImplicitParams( + @ApiImplicitParam(id = "apiKeyId", name = "apiKeyId", value = "ai配置id", required = "required") + ) + @RequestMapping("/post/ChatController/deleteAllByApiKeyId") + public void deleteAllByApiKeyId(InputObject inputObject, OutputObject outputObject) { + chatService.deleteAllByApiKeyId(inputObject, outputObject); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/dao/ChatDao.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/dao/ChatDao.java new file mode 100644 index 0000000..e978bb0 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/dao/ChatDao.java @@ -0,0 +1,15 @@ +package com.skyeye.chat.dao; + +import com.skyeye.chat.entity.Chat; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ChatDao + * @Description: 聊天记录数据层 + * @author: skyeye云系列--lqy + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ChatDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/entity/Chat.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/entity/Chat.java new file mode 100644 index 0000000..25de744 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/entity/Chat.java @@ -0,0 +1,49 @@ +package com.skyeye.chat.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.key.entity.AiApiKey; +import lombok.Data; + +/** + * @ClassName: Chat + * @Description: 聊天记录实体层 + * @author: skyeye云系列--lqy + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_ai_chat") +@ApiModel(value = "聊天记录实体类") +public class Chat extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("message") + @ApiModelProperty(value = "问题", required = "required") + private String message; + + @TableField("content") + @ApiModelProperty(value = "回答的问题") + private String content; + + @TableField("platform") + @ApiModelProperty(value = "平台",required = "required") + private String platform; + + @TableField("api_key_id") + @ApiModelProperty(value = "API配置id",required = "required") + private String apiKeyId; + + @TableField(exist = false) + @Property("AI配置") + private AiApiKey apiKeyMation; +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/ChatService.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/ChatService.java new file mode 100644 index 0000000..a666e91 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/ChatService.java @@ -0,0 +1,24 @@ +package com.skyeye.chat.service; + + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.chat.entity.Chat; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ChatService + * @Description: 聊天记录接口层 + * @author: skyeye云系列--lqy + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ChatService extends SkyeyeBusinessService { + + void sendChatMessage(InputObject inputObject, OutputObject outputObject); + + void queryPageMessageList(InputObject inputObject, OutputObject outputObject); + + void deleteAllByApiKeyId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/impl/ChatServiceImpl.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/impl/ChatServiceImpl.java new file mode 100644 index 0000000..31fbcef --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/chat/service/impl/ChatServiceImpl.java @@ -0,0 +1,369 @@ +package com.skyeye.chat.service.impl; + + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.dashscope.aigc.generation.Generation; +import com.alibaba.dashscope.aigc.generation.GenerationOutput; +import com.alibaba.dashscope.aigc.generation.GenerationParam; +import com.alibaba.dashscope.aigc.generation.GenerationResult; +import com.alibaba.dashscope.common.Message; +import com.alibaba.dashscope.common.Role; +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import com.baidubce.qianfan.Qianfan; +import com.baidubce.qianfan.core.builder.ChatBuilder; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.ai.core.config.SkyeyeAiProperties; +import com.skyeye.ai.core.enums.AiPlatformEnum; +import com.skyeye.ai.core.factory.AiFactory; +import com.skyeye.aiStreamModle.SparkListener; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.chat.dao.ChatDao; +import com.skyeye.chat.entity.Chat; +import com.skyeye.chat.service.ChatService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.key.entity.AiApiKey; +import com.skyeye.key.service.AiApiKeyService; +import com.skyeye.role.service.RoleService; +import com.skyeye.websocket.AiMessageWebSocket; +import io.github.briqt.spark4j.SparkClient; +import io.github.briqt.spark4j.constant.SparkApiVersion; +import io.github.briqt.spark4j.model.SparkMessage; +import io.github.briqt.spark4j.model.request.SparkRequest; +import io.github.briqt.spark4j.model.response.SparkResponse; +import io.github.briqt.spark4j.model.response.SparkResponseUsage; +import io.reactivex.Flowable; +import okhttp3.WebSocket; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.concurrent.Executor; + +/** + * @ClassName: ChatServiceImpl + * @Description: 聊天记录接口实现层 + * @author: skyeye云系列--lqy + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ChatServiceImpl extends SkyeyeBusinessServiceImpl implements ChatService { + + @Autowired + private AiFactory aiFactory; + + @Autowired + private AiApiKeyService aiApiKeyService; + + @Autowired + private SkyeyeAiProperties skyeyeAiProperties; + + @Autowired + private RoleService roleService; + + @Autowired + private ChatService chatService; + + @Autowired + private Executor messageStreamExecutor; + + @Autowired + private AiMessageWebSocket aiMessageWebSocket; + + + @Override + @Transactional + public void sendChatMessage(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String content = params.get("content").toString(); + String apiKeyId = params.get("apiKeyId").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + Chat chat = new Chat(); + AiApiKey aiApiKey = aiApiKeyService.selectById(apiKeyId); + String platform = aiApiKey.getPlatform(); + // 获取到具有的ai模型 + AiPlatformEnum aiModel = AiPlatformEnum.getValue(platform); + // 获取role实例 + com.skyeye.role.entity.Role role = roleService.selectById(aiApiKey.getRoleId()); + // 创建AI实例 + chat.setMessage(content); + chat.setPlatform(platform); + chat.setApiKeyId(apiKeyId); + String id =createEntity(chat, userId); + switch (aiModel) { + case YI_YAN: + QianFanResponse(content, userId, apiKeyId, id); + break; + case XUN_FEI: + XunFeiResponse(content,userId,apiKeyId,id); + break; + case TONG_YI: + try { + TongYiResponse(content,userId,apiKeyId,id); + break; + } catch (Exception e) { + e.printStackTrace(); + } + break; + } + aiApiKey.setRoleMation(role); + chat.setApiKeyMation(aiApiKey); + + outputObject.setBean(chat); + outputObject.setreturnCode(CommonNumConstants.NUM_ZERO); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private void QianFanResponse(String message, String userId, String apiKeyId, String chatId) { + // 开启异步请求 + messageStreamExecutor.execute(() -> { + Qianfan qianfan = (Qianfan) aiFactory.getDefaultChatModel(AiPlatformEnum.YI_YAN); + ChatBuilder model = qianfan.chatCompletion() + .model("ERNIE-Speed-8K"); + // 获取聊天记录 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getApiKeyId), apiKeyId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Chat::getCreateTime)); + PageHelper.startPage(1, 10); + List chatList = chatService.list(queryWrapper); + + chatList.forEach(chat -> { + if (StrUtil.isNotEmpty(chat.getMessage()) && StrUtil.isNotEmpty(chat.getContent())) { + model.addMessage("user", chat.getMessage()) + .addMessage("assistant", chat.getContent()); + } + }); + model.addMessage("user", message); + model.executeStream() + .forEachRemaining(chunk -> { + String key = String.format(Locale.ROOT, "chat:%s", chatId); + List chunkMessage = new ArrayList<>(); + if (jedisClientService.exists(key)) { + chunkMessage = JSONUtil.toList(jedisClientService.get(key), null); + } + chunkMessage.add(chunk.getResult()); + if (chunk.getEnd()) { + jedisClientService.del(key); + String content = Joiner.on("").join(chunkMessage); + // 修改回复内容 + Chat chat = chatService.selectById(chatId); + chat.setContent(content); + chatService.updateEntity(chat, userId); + } else { + jedisClientService.set(key, JSONUtil.toJsonStr(chunkMessage)); + } + Map messageMap = new HashMap<>(); + messageMap.put("message", chunk.getResult()); + messageMap.put("end", chunk.getEnd()); + messageMap.put("orderBy", chunk.getSentenceId()); + aiMessageWebSocket.sendMessageTo(JSONUtil.toJsonStr(messageMap), userId); + }); + }); + + } + + private void XunFeiResponse(String message,String userId,String apiKeyId,String chatId) { + messageStreamExecutor.execute(() -> { + List messageList = new ArrayList<>(); + // 获取聊天记录 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getApiKeyId), apiKeyId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Chat::getCreateTime)); + PageHelper.startPage(1, 10); + List chatList = chatService.list(queryWrapper); + chatList.forEach(chat -> { + if (StrUtil.isNotEmpty(chat.getMessage()) && StrUtil.isNotEmpty(chat.getContent())) { + messageList.add(SparkMessage.userContent(chat.getMessage())); + messageList.add(SparkMessage.systemContent(chat.getContent())); + } + }); + messageList.add(SparkMessage.userContent(message)); + + SparkClient sparkClient = (SparkClient) aiFactory.getDefaultChatModel(AiPlatformEnum.XUN_FEI); + // 构造请求 + SparkRequest sparkRequest = SparkRequest.builder() + .messages(messageList) + .maxTokens(2048) + .temperature(0.5) + .apiVersion(SparkApiVersion.V3_5) + .build(); + // 封装聊天信息 + sparkClient.chatStream(sparkRequest,new SparkListener(){ + @Override + public void onMessage(String content, SparkResponseUsage usage, Integer status, SparkRequest sparkRequest, SparkResponse sparkResponse, WebSocket webSocket) { + + try { + JSONObject jsonObject = new JSONObject(this.objectMapper.writeValueAsString(sparkResponse)); + // 获取payload对象 + JSONObject payload = jsonObject.getJSONObject("payload"); + // 获取choices对象 + JSONObject choices = payload.getJSONObject("choices"); + String key = String.format(Locale.ROOT, "chat:%s", chatId); + List chunkMessage = new ArrayList<>(); + if (jedisClientService.exists(key)) { + chunkMessage = JSONUtil.toList(jedisClientService.get(key), null); + } + chunkMessage.add(content); + if (status == 2) { + jedisClientService.del(key); + String totalMessage = Joiner.on("").join(chunkMessage); + // 修改回复内容 + Chat chat = chatService.selectById(chatId); + chat.setContent(totalMessage); + chatService.updateEntity(chat, userId); + } else { + jedisClientService.set(key, JSONUtil.toJsonStr(chunkMessage)); + } + Map messageMap = new HashMap<>(); + messageMap.put("message",content); + messageMap.put("end", status == 2); + messageMap.put("orderBy",choices.get("seq")); + aiMessageWebSocket.sendMessageTo(JSONUtil.toJsonStr(messageMap), userId); + } catch (JsonProcessingException var9) { + JsonProcessingException e = var9; + throw new RuntimeException(e); + } + } + }); + }); + } + + private void TongYiResponse(String message,String userId,String apiKeyId,String chatId) throws NoApiKeyException, InputRequiredException { + // 开启异步请求: + messageStreamExecutor.execute(() -> { + List messages = new ArrayList<>(); + Message question = Message.builder().role(Role.USER.getValue()).content(message).build(); + Generation generation = (Generation) aiFactory.getDefaultChatModel(AiPlatformEnum.TONG_YI); + // 获取聊天记录 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getApiKeyId), apiKeyId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Chat::getCreateTime)); + PageHelper.startPage(1, 10); + List chatList = chatService.list(queryWrapper); + chatList.forEach(chat -> { + if (StrUtil.isNotEmpty(chat.getMessage()) && StrUtil.isNotEmpty(chat.getContent())) { + Message userMsg = Message.builder().role(Role.USER.getValue()).content(chat.getMessage()).build(); + Message assistantMsg = Message.builder().role(Role.SYSTEM.getValue()).content(chat.getContent()).build(); + messages.add(userMsg); + messages.add(assistantMsg); + } + }); + messages.add(question); + GenerationParam param = GenerationParam.builder() + //指定用于对话的通义千问模型名 + .model("qwen-turbo") + .messages(messages) + .resultFormat(GenerationParam.ResultFormat.MESSAGE) + //生成过程中核采样方法概率阈值,例如,取值为0.8时,仅保留概率加起来大于等于0.8的最可能token的最小集合作为候选集。 + // 取值范围为(0,1.0),取值越大,生成的随机性越高;取值越低,生成的确定性越高。 + .topP(0.8) + //阿里云控制台DASHSCOPE获取的api-key + .apiKey(skyeyeAiProperties.getTongYi().getApiKey()) + //启用互联网搜索,模型会将搜索结果作为文本生成过程中的参考信息,但模型会基于其内部逻辑“自行判断”是否使用互联网搜索结果。 + .enableSearch(true) + .incrementalOutput(true) + .build(); + Flowable result; + try { + result = generation.streamCall(param); + } catch (NoApiKeyException e) { + throw new RuntimeException(e); + } catch (InputRequiredException e) { + throw new RuntimeException(e); + } + result.blockingForEach(chunk -> { + System.out.println(JSONUtil.toJsonStr(chunk)); + String key = String.format(Locale.ROOT, "chat:%s", chatId); + List chunkMessage = new ArrayList<>(); + if (jedisClientService.exists(key)) { + chunkMessage = JSONUtil.toList(jedisClientService.get(key), null); + } + Boolean end = false; + List choiceList = chunk.getOutput().getChoices(); + GenerationOutput.Choice choice = choiceList.stream().findFirst().orElse(null); + if (ObjectUtil.isEmpty(choice)){ + end = true; + chunkMessage.add(StrUtil.EMPTY); + } else { + if (choice.getFinishReason().equals("stop")) { + end = true; + } + chunkMessage.add(choice.getMessage().getContent()); + } + if (end) { + jedisClientService.del(key); + String content = Joiner.on("").join(chunkMessage); + // 修改回复内容 + Chat chat = chatService.selectById(chatId); + chat.setContent(content); + chatService.updateEntity(chat, userId); + } else { + jedisClientService.set(key, JSONUtil.toJsonStr(chunkMessage)); + } + Map messageMap = new HashMap<>(); + messageMap.put("message", chunkMessage.get(chunkMessage.size() - 1)); + messageMap.put("end", end); + messageMap.put("orderBy", chunkMessage.size() - 1); + aiMessageWebSocket.sendMessageTo(JSONUtil.toJsonStr(messageMap), userId); + }); + }); + } + + + @Override + public void queryPageMessageList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String apiKeyId = commonPageInfo.getHolderId(); + if (StrUtil.isEmpty(apiKeyId)) { + throw new CustomException("apiKeyId不能为空"); + } + + AiApiKey aiApiKey = aiApiKeyService.selectById(apiKeyId); + com.skyeye.role.entity.Role role = roleService.selectById(aiApiKey.getRoleId()); + aiApiKey.setRoleMation(role); + + String userId = InputObject.getLogParamsStatic().get("id").toString(); + Page page = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getApiKeyId), apiKeyId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Chat::getCreateTime)); + List chatList = list(queryWrapper); + + for (Chat chat : chatList) { + chat.setApiKeyMation(aiApiKey); + } + outputObject.setBeans(chatList); + outputObject.settotal(page.getTotal()); + } + + @Override + public void deleteAllByApiKeyId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String apiKeyId = params.get("apiKeyId").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getApiKeyId), apiKeyId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Chat::getCreateId), userId); + remove(queryWrapper); + } + +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/controller/AiApiKeyController.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/controller/AiApiKeyController.java new file mode 100644 index 0000000..53cd6b3 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/controller/AiApiKeyController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.key.controller; + +import com.skyeye.key.entity.AiApiKey; +import com.skyeye.key.service.AiApiKeyService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai配置控制类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "API配置", tags = "API配置", modelName = "API配置") +public class AiApiKeyController { + + @Autowired + private AiApiKeyService aiApiKeyService; + + /** + * 新增/编辑API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAiApiKey", value = "新增/编辑API配置", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AiApiKey.class) + @RequestMapping("/post/aiApiKeyController/writeAiApiKey") + public void writeAiApiKey(InputObject inputObject, OutputObject outputObject) { + aiApiKeyService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 分页查询API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAiApiKey", value = "分页查询API配置", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/aiApiKeyController/queryAiApiKey") + public void queryAiApiKey(InputObject inputObject, OutputObject outputObject) { + aiApiKeyService.queryPageList(inputObject, outputObject); + } + + /** + * 批量删除API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAiApiKeyByIds", value = "批量删除API配置", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/aiApiKeyController/deleteAiApiKeyByIds") + public void deleteAiApiKeyByIds(InputObject inputObject, OutputObject outputObject) { + aiApiKeyService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectAiApiKeyById", value = "根据id获取API配置", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/aiApiKeyController/selectAiApiKeyById") + public void selectAiApiKeyById(InputObject inputObject, OutputObject outputObject) { + aiApiKeyService.selectById(inputObject, outputObject); + } + + /** + * 获取全部API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAiApiKeyList", value = "获取广告位管理信息", method = "POST", allUse = "0") + @RequestMapping("/post/aiApiKeyController/queryAiApiKeyList") + public void queryAiApiKeyList(InputObject inputObject, OutputObject outputObject) { + aiApiKeyService.queryList(inputObject, outputObject); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/dao/AiApiKeyDao.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/dao/AiApiKeyDao.java new file mode 100644 index 0000000..82b31ed --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/dao/AiApiKeyDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.key.dao; + + +import com.skyeye.key.entity.AiApiKey; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai配置数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AiApiKeyDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/entity/AiApiKey.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/entity/AiApiKey.java new file mode 100644 index 0000000..5de36ce --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/entity/AiApiKey.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.key.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.role.entity.Role; +import lombok.Data; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai配置实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "skyeye_ai_api_key") +@ApiModel("API配置") +public class AiApiKey extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "`remark`") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "`api_key`") + @ApiModelProperty(value = "密钥") + private String apiKey; + + @TableField(value = "`secret_key`") + @ApiModelProperty(value = "secretKey") + private String secretKey; + + @TableField(value = "`enabled`") + @ApiModelProperty(value = "状态",required = "required") + private String enabled; + + @TableField(value = "`platform`") + @ApiModelProperty(value = "ai平台",required = "required") + private String platform; + + @TableField(value = "`url`") + @ApiModelProperty(value = "API 地址") + private String url; + + @TableField(value = "`role_id`") + @ApiModelProperty(value = "角色id") + private String roleId; + + @TableField(exist = false) + @Property("AI角色") + private Role roleMation; +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/AiApiKeyService.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/AiApiKeyService.java new file mode 100644 index 0000000..32f1283 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/AiApiKeyService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.key.service; + +import com.skyeye.key.entity.AiApiKey; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai配置服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AiApiKeyService extends SkyeyeBusinessService { +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/impl/AiApiKeyServiceImpl.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/impl/AiApiKeyServiceImpl.java new file mode 100644 index 0000000..6bcbb23 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/key/service/impl/AiApiKeyServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.key.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.key.dao.AiApiKeyDao; +import com.skyeye.key.entity.AiApiKey; +import com.skyeye.key.service.AiApiKeyService; +import com.skyeye.role.entity.Role; +import com.skyeye.role.service.RoleService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai配置服务类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "API配置", groupName = "API配置") +public class AiApiKeyServiceImpl extends SkyeyeBusinessServiceImpl implements AiApiKeyService { + + @Autowired + private RoleService roleService; + + /** + * 重写新增编辑前置条件API配置 + */ + @Override + public void validatorEntity(AiApiKey aiApiKey) { + super.validatorEntity(aiApiKey); + //判断RoleId是否存在 + if (StrUtil.isNotEmpty(aiApiKey.getRoleId())) { + Role role = roleService.selectById(aiApiKey.getRoleId()); + //判断RoleId是否为空,如果为空,则抛出异常 + if (role.getId() == null) { + throw new CustomException("角色不存在: " + aiApiKey.getRoleId()); + } + } + } + + /** + * 获取全部API配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/controller/MessageController.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/controller/MessageController.java new file mode 100644 index 0000000..c44d52c --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/controller/MessageController.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.message.controller; + +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.message.service.MessageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @ClassName: MessageController + * @Description: 消息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "消息管理", tags = "消息管理", modelName = "消息管理") +public class MessageController { + + @Autowired + private MessageService messageService; + + /* @ApiOperation(id = "sendMessage", value = "发送消息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "message", name = "message", value = "消息", required = "required")}) + @RequestMapping("/post/MessageController/sendMessage") + public void sendMessage(InputObject inputObject, OutputObject outputObject) { + messageService.sendMessage(inputObject, outputObject); + }*/ + + @ApiOperation(id = "sendMessage", value = "发送消息(段式)一次性返回,响应较慢", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "content", name = "content", value = "消息", required = "required")}) + @RequestMapping("/post/MessageController/sendMessage") + public void sendMessage(InputObject inputObject, OutputObject outputObject) { + messageService.sendMessage(inputObject, outputObject); + } + + @ApiOperation(id = "sendMessageStream", value = "发送消息(流式)流式返回,响应较快", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "content", name = "content", value = "消息", required = "required")}) + @RequestMapping("/post/MessageController/sendMessageStream") + public void sendMessageStream(InputObject inputObject, OutputObject outputObject) { + messageService.sendMessageStream(inputObject, outputObject); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/MessageService.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/MessageService.java new file mode 100644 index 0000000..991fa46 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/MessageService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.message.service; + +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @ClassName: MessageService + * @Description: 消息服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 17:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MessageService { + + void sendMessage(InputObject inputObject,OutputObject outputObject); + + void sendMessageStream(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/impl/MessageServiceImpl.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/impl/MessageServiceImpl.java new file mode 100644 index 0000000..2392f6e --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/message/service/impl/MessageServiceImpl.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.message.service.impl; + +import cn.hutool.json.JSONUtil; +import com.baidubce.qianfan.Qianfan; +import com.baidubce.qianfan.core.StreamIterator; +import com.baidubce.qianfan.core.builder.ChatBuilder; +import com.baidubce.qianfan.model.completion.CompletionResponse; +import com.skyeye.ai.core.config.SkyeyeAiProperties; +import com.skyeye.ai.core.enums.AiPlatformEnum; +import com.skyeye.ai.core.factory.AiFactory; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.message.service.MessageService; +import com.skyeye.websocket.AiMessageWebSocket; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * @ClassName: MessageServiceImpl + * @Description: 消息服务实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/5 17:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "消息管理", groupName = "消息管理") +public class MessageServiceImpl implements MessageService { + + @Autowired + private AiFactory aiFactory; + + @Autowired + private SkyeyeAiProperties skyeyeAiProperties; + + @Autowired + private Executor messageStreamExecutor; + + @Autowired + private AiMessageWebSocket aiMessageWebSocket; + + @Override + public void sendMessage(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String content = params.get("content").toString(); + Qianfan qianfan = (Qianfan) aiFactory.getDefaultChatModel(AiPlatformEnum.YI_YAN); + ChatBuilder bulder = qianfan.chatCompletion() + //你要使用的大模型款式,最好和我一样,其他的很有可能是收费的 + .model("ERNIE-Speed-8K") + .addMessage("user", content); + bulder.addMessage("user", content);//你的问题 +// ChatResponse response = bulder.execute(); +// outputObject.setBean(response); +// outputObject.settotal(CommonNumConstants.NUM_ONE) + try (StreamIterator response = qianfan + .completion() + .model("CodeLlama-7b-Instruct") + .prompt(content) + .executeStream()) { + while (response.hasNext()) { +// outputObject.setBean(response.next().getResult()); + System.out.println(response.next().getResult()); + } + } + } + + @Override + public void sendMessageStream(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String content = params.get("content").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + messageStreamExecutor.execute(() -> { + // 使用安全认证AK/SK鉴权参数,安全认证Access Key替换your_iam_ak,Secret Key替换your_iam_sk + Qianfan qianfan = (Qianfan) aiFactory.getDefaultChatModel(AiPlatformEnum.YI_YAN); + + qianfan.chatCompletion() + .model("ERNIE-Speed-8K") + .addMessage("user", content) + // 启用流式返回 + .executeStream() + .forEachRemaining(chunk -> { + Map messageMap = new HashMap<>(); + messageMap.put("message", chunk.getResult()); + messageMap.put("end", chunk.getEnd()); + messageMap.put("orderBy", chunk.getSentenceId()); + aiMessageWebSocket.sendMessageTo(JSONUtil.toJsonStr(messageMap), userId); + }); + }); + } +} + diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/controller/RoleController.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/controller/RoleController.java new file mode 100644 index 0000000..2422707 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/controller/RoleController.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.controller; + +import com.skyeye.role.entity.Role; +import com.skyeye.role.service.RoleService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai角色控制类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "AI角色", tags = "AI角色", modelName = "AI角色") +public class RoleController{ + + @Autowired + private RoleService roleService; + + /** + * 新增/编辑AI角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRole", value = "新增/编辑AI角色", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Role.class) + @RequestMapping("/post/roleController/writeRole") + public void writeRole(InputObject inputObject, OutputObject outputObject) { + roleService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 分页查询AI角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRole", value = "分页查询AI角色", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/roleController/queryRole") + public void queryRole(InputObject inputObject, OutputObject outputObject) { + roleService.queryPageList(inputObject, outputObject); + } + + /** + * 批量删除AI角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteRoleByIds", value = "批量删除AI角色", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/roleController/deleteRoleByIds") + public void deleteRoleByIds(InputObject inputObject, OutputObject outputObject) { + roleService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取AI角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectRoleById", value = "根据id获取AI角色", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/roleController/selectRoleById") + public void selectRoleById(InputObject inputObject, OutputObject outputObject) { + roleService.selectById(inputObject, outputObject); + } + + /** + * 获取全部Ai角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRoleList", value = "获取广告位管理信息", method = "POST", allUse = "0") + @RequestMapping("/post/roleController/queryRoleList") + public void queryRoleList(InputObject inputObject, OutputObject outputObject) { + roleService.queryList(inputObject, outputObject); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/dao/RoleDao.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/dao/RoleDao.java new file mode 100644 index 0000000..36a1be3 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/dao/RoleDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.dao; + +import com.skyeye.role.entity.Role; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai角色数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RoleDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/entity/Role.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/entity/Role.java new file mode 100644 index 0000000..b45d977 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/entity/Role.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.key.entity.AiApiKey; +import lombok.Data; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai角色实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "skyeye_ai_role") +@ApiModel("AI角色") +public class Role extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "角色名称", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "`remark`") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "`logo`") + @ApiModelProperty(value = "角色logo") + private String logo; +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/RoleService.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/RoleService.java new file mode 100644 index 0000000..deba799 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/RoleService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.service; + +import com.skyeye.role.entity.Role; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +import java.util.List; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai角色服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RoleService extends SkyeyeBusinessService { + List queryRoleList(String id); +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/impl/RoleServiceImpl.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..ac20fa4 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/role/service/impl/RoleServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.role.dao.RoleDao; +import com.skyeye.role.entity.Role; +import com.skyeye.role.service.RoleService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: ai角色服务类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/8 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "AI角色", groupName = "AI角色") +public class RoleServiceImpl extends SkyeyeBusinessServiceImpl implements RoleService { + + /** + * 分页查询AI角色信息 + * @param commonPageInfo + * @return + */ + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String keyword = commonPageInfo.getKeyword(); + if (StrUtil.isNotEmpty(keyword)) { + queryWrapper.like(MybatisPlusUtil.toColumns(Role::getName), keyword); + } + return queryWrapper; + } + + /** + * 获取全部AI角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + @Override + public List queryRoleList(String id){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Role::getId), id); + return list(queryWrapper); + } +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/AiMessageWebSocket.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/AiMessageWebSocket.java new file mode 100644 index 0000000..4e89ad0 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/AiMessageWebSocket.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.websocket; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.util.ToolUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @ClassName: AiMessageWebSocket + * @Description: AI消息WebSocket + * @author: skyeye云系列--卫志强 + * @date: 2020年11月14日 下午9:36:38 + * @Copyright: 2020 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Component +@ServerEndpoint("/aiMessageWebSocket/{userId}") +public class AiMessageWebSocket { + + private static final Logger LOGGER = LoggerFactory.getLogger(AiMessageWebSocket.class); + + /** + * 在线人数 + */ + public static int onlineNumber = 0; + + /** + * 以用户的姓名为key,WebSocket为对象保存起来 + */ + private static Map clients = new ConcurrentHashMap(); + /** + * 会话 + */ + private Session session; + /** + * 用户id + */ + private String userId; + + /** + * 建立连接 + * + * @param session + */ + @OnOpen + public void onOpen(@PathParam("userId") String userId, Session session) { + if (clients.containsKey(userId)) { + return; + } + onlineNumber++; + LOGGER.info("现在来连接的客户id: {}, 用户名: {}", session.getId(), userId); + this.userId = userId; + this.session = session; + LOGGER.info("有新连接加入! 当前在线人数: {}", onlineNumber); + + + // 把自己的信息加入到map当中去 + clients.put(userId, this); + } + + @OnError + public void onError(Session session, Throwable error) { + LOGGER.warn("服务端发生了错误: {}", error.getMessage()); + } + + /** + * 连接关闭 + */ + @OnClose + public void onClose() { + if (!ToolUtil.isBlank(userId) && clients.containsKey(userId)) { + onlineNumber--; + clients.remove(userId); + LOGGER.info("有连接关闭! 当前在线人数" + onlineNumber); + } + } + + /** + * 收到客户端的消息 + * + * @param message 消息 + * @param session 会话 + */ + @OnMessage + public void onMessage(String message, Session session) { + try { + LOGGER.info("来自客户端消息: {}, 客户端的id是: {}", message, session.getId()); + JSONObject jsonObject = JSONUtil.toBean(message, null); + + } catch (Exception e) { + LOGGER.warn("发生了错误了: {}", e); + } + } + + /** + * 发送给指定用户消息 + * + * @param message + * @param userId + */ + public void sendMessageTo(String message, String userId) { + AiMessageWebSocket item = clients.get(userId); + if (item != null) { + item.session.getAsyncRemote().sendText(message); + } + } + + /** + * 获取当前在线的用户id + * + * @return + */ + public static Set getOnlineUserId() { + return clients.keySet(); + } + + public static synchronized int getOnlineCount() { + return onlineNumber; + } + + /** + * 获取当前的session* + * + * + */ + public synchronized Session getSession() { + return this.session; + } + +} diff --git a/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/WebSocketConfig.java b/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/WebSocketConfig.java new file mode 100644 index 0000000..5382583 --- /dev/null +++ b/skyeye-ai/ai-pro/src/main/java/com/skyeye/websocket/WebSocketConfig.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.websocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/skyeye-ai/ai-web/.gitignore b/skyeye-ai/ai-web/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-ai/ai-web/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ai/ai-web/pom.xml b/skyeye-ai/ai-web/pom.xml new file mode 100644 index 0000000..271863d --- /dev/null +++ b/skyeye-ai/ai-web/pom.xml @@ -0,0 +1,91 @@ + + + + skyeye-ai + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ai-web + + + UTF-8 + + + + + + com.skyeye + ai-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-ai/ai-web/src/main/java/com/skyeye/SkyAiApplication.java b/skyeye-ai/ai-web/src/main/java/com/skyeye/SkyAiApplication.java new file mode 100644 index 0000000..b3e6d4e --- /dev/null +++ b/skyeye-ai/ai-web/src/main/java/com/skyeye/SkyAiApplication.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class SkyAiApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyAiApplication.class, args); + } + +} diff --git a/skyeye-ai/ai-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-ai/ai-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..561a9bf --- /dev/null +++ b/skyeye-ai/ai-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-ai/ai-web/src/main/resources/banner.txt b/skyeye-ai/ai-web/src/main/resources/banner.txt new file mode 100644 index 0000000..e1b7251 --- /dev/null +++ b/skyeye-ai/ai-web/src/main/resources/banner.txt @@ -0,0 +1,34 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 +*/ \ No newline at end of file diff --git a/skyeye-ai/ai-web/src/main/resources/bootstrap.yml b/skyeye-ai/ai-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..fce950e --- /dev/null +++ b/skyeye-ai/ai-web/src/main/resources/bootstrap.yml @@ -0,0 +1,62 @@ +server: + port: 8120 + +spring: + application: + name: skyeye-ai-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: true # 是否动态刷新,默认为false + ai: + qianfan: # 文心一言 https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v1 + apiKey: EVdFG9fbFMmwtjQ57Efwftox + secretKey: XJ8jcR6jK06S5BCrPRYFoWqqlqbwyCXx + xunfei: # 讯飞星火 https://xinghuo.xfyun.cn/sparkapi + appId: e7777701 + apiKey: 6bb0647ad9508d0519c4e406d939e856 + secretKey: MGQ2YWExYjcyOTM3NDc1NDk0MDlkOWVi + deepseek: + apiKey: sk-63b02a6b78d4417aaa21353eab86cd9f + url: https://api.deepseek.com + tongyi: + apiKey: sk-f26299b6cda34370abfc2b5b1bb2699d + zhipu: + apiKey: 933c75485db6abbcb5182bce914e3ec1 + secretKey: DBobhCDndViaDtWH + url: https://open.bigmodel.cn/api/paas/ + + +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL diff --git a/skyeye-ai/ai-web/src/main/resources/jvm调优参数配置 b/skyeye-ai/ai-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-ai/ai-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-ai/ai-web/src/main/resources/log4j.properties b/skyeye-ai/ai-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-ai/ai-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-ai/pom.xml b/skyeye-ai/pom.xml new file mode 100644 index 0000000..86665e4 --- /dev/null +++ b/skyeye-ai/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-ai + pom + 1.0-SNAPSHOT + + + ai-web + ai-pro + ai-common + + + + + + huaweicloud + huawei + https://mirrors.huaweicloud.com/repository/maven/ + + + aliyunmaven + aliyun + https://maven.aliyun.com/repository/public + + + + \ No newline at end of file diff --git a/skyeye-auto/.gitignore b/skyeye-auto/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-auto/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-auto/auto-common/.gitignore b/skyeye-auto/auto-common/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-auto/auto-common/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-auto/auto-common/pom.xml b/skyeye-auto/auto-common/pom.xml new file mode 100644 index 0000000..bfe257d --- /dev/null +++ b/skyeye-auto/auto-common/pom.xml @@ -0,0 +1,31 @@ + + + + skyeye-auto + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + auto-common + + + 8 + 8 + UTF-8 + + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-common/src/main/java/com/skyeye/util/AutoConstants.java b/skyeye-auto/auto-common/src/main/java/com/skyeye/util/AutoConstants.java new file mode 100644 index 0000000..a9805ea --- /dev/null +++ b/skyeye-auto/auto-common/src/main/java/com/skyeye/util/AutoConstants.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoConstants + * @Description: 自动化常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class AutoConstants { + + /** + * 数据源类型 + */ + public enum DataBaseMation { + MYSQL("MySQL", "com.mysql.jdbc.Driver", "com.skyeye.sql.query.impl.MySqlQueryer"), + SQLSERVER("SQLServer", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "com.skyeye.sql.query.impl.SqlServerQueryer"), + ORACLE("Oracle", "oracle.jdbc.driver.OracleDriver", "com.skyeye.sql.query.impl.OracleQueryer"); + + private String type; + private String driverClass; + private String queryerClass; + + DataBaseMation(String type, String driverClass, String queryerClass) { + this.type = type; + this.driverClass = driverClass; + this.queryerClass = queryerClass; + } + + public static List> getDataBaseMationList() { + List> beans = new ArrayList<>(); + for (DataBaseMation item : DataBaseMation.values()) { + Map bean = new HashMap<>(); + bean.put("id", item.getType()); + bean.put("name", item.getType()); + bean.put("driverClass", item.getDriverClass()); + beans.add(bean); + } + return beans; + } + + public static String getDricerClassByType(String type) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getType().equals(type)) { + return bean.getDriverClass(); + } + } + return null; + } + + public static String getTypeByDricerClass(String driverClass) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getDriverClass().equals(driverClass)) { + return bean.getType(); + } + } + return null; + } + + public static String getQueryerClassByType(String type) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getType().equals(type)) { + return bean.getQueryerClass(); + } + } + return null; + } + + public String getType() { + return type; + } + + public String getDriverClass() { + return driverClass; + } + + public String getQueryerClass() { + return queryerClass; + } + } + + /** + * 连接池类型 + */ + public enum PoolMation { + C3P0("C3P0", "c3p0", "com.skyeye.sql.dbpool.impl.C3p0DataSourcePool", "{\"initialPoolSize\":3,\"minPoolSize\":1,\"maxPoolSize\":10,\"maxStatements\":50,\"maxIdleTime\":1000,\"acquireIncrement\":3,\"acquireRetryAttempts\":30,\"idleConnectionTestPeriod\":60,\"breakAfterAcquireFailure\":false,\"testConnectionOnCheckout\":false}"), + DBCP2("DBCP2", "dbcp2", "com.skyeye.sql.dbpool.impl.DBCP2DataSourcePool", "{\"initialSize\":3,\"maxIdle\":20,\"minIdle\":1,\"logAbandoned\":true,\"removeAbandoned\":true,\"removeAbandonedTimeout\":180,\"maxWait\":1000}"), + DRUID("DRUID", "druid", "com.skyeye.sql.dbpool.impl.DruidDataSourcePool", "{\"initialSize\":3,\"maxActive\":20,\"minIdle\":1,\"maxWait\":60000,\"timeBetweenEvictionRunsMillis\":60000,\"minEvictableIdleTimeMillis\":300000,\"testWhileIdle\":true,\"testOnBorrow\":false,\"testOnReturn\":false,\"maxOpenPreparedStatements\":20,\"removeAbandoned\":true,\"removeAbandonedTimeout\":1800,\"logAbandoned\":true}"), + NODBPOOL("无连接池", "noDbPool", "com.skyeye.sql.dbpool.impl.NoDataSourcePool", "{}"); + + private String title; + private String type; + private String poolClass; + private String options; + + PoolMation(String title, String type, String poolClass, String options) { + this.title = title; + this.type = type; + this.poolClass = poolClass; + this.options = options; + } + + public static List> getPoolMationList() { + List> beans = new ArrayList<>(); + for (PoolMation item : PoolMation.values()) { + Map bean = new HashMap<>(); + bean.put("id", item.getType()); + bean.put("name", item.getTitle()); + bean.put("options", item.getOptions()); + beans.add(bean); + } + return beans; + } + + public static String getPoolClassByType(String type) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getType().equals(type)) { + return bean.getPoolClass(); + } + } + return null; + } + + public static String getTitleByPoolClass(String poolClass) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getPoolClass().equals(poolClass)) { + return bean.getTitle(); + } + } + return null; + } + + public static String getTypeByPoolClass(String poolClass) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getPoolClass().equals(poolClass)) { + return bean.getType(); + } + } + return null; + } + + public static String getOptionsByType(String type) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getType().equals(type)) { + return bean.getOptions(); + } + } + return null; + } + + public String getType() { + return type; + } + + public String getPoolClass() { + return poolClass; + } + + public String getOptions() { + return options; + } + + public String getTitle() { + return title; + } + } + +} diff --git a/skyeye-auto/auto-pro/.gitignore b/skyeye-auto/auto-pro/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-auto/auto-pro/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-auto/auto-pro/pom.xml b/skyeye-auto/auto-pro/pom.xml new file mode 100644 index 0000000..9a45fc4 --- /dev/null +++ b/skyeye-auto/auto-pro/pom.xml @@ -0,0 +1,58 @@ + + + + skyeye-auto + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + auto-pro + + + 8 + 8 + UTF-8 + + 0.9.5.2 + 1.0.25 + + + + + + + com.skyeye + auto-common + 1.0-SNAPSHOT + + + + org.apache.commons + commons-dbcp2 + 2.1.1 + + + + com.jayway.jsonpath + json-path + 2.8.0 + + + + + com.mchange + c3p0 + ${c3p0.version} + + + com.alibaba + druid + ${druid.version} + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/classenum/AutoApiAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/classenum/AutoApiAuthEnum.java new file mode 100644 index 0000000..22fc692 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/classenum/AutoApiAuthEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoApiAuthEnum + * @Description: 接口权限枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoApiAuthEnum implements SkyeyeEnumClass { + + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/controller/AutoApiController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/controller/AutoApiController.java new file mode 100644 index 0000000..c4524b9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/controller/AutoApiController.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.api.entity.AutoApi; +import com.skyeye.api.entity.AutoApiQueryDo; +import com.skyeye.api.service.AutoApiService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoApiController + * @Description: 接口管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "接口管理", tags = "接口管理", modelName = "接口管理") +public class AutoApiController { + + @Autowired + private AutoApiService autoApiService; + + /** + * 获取接口信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoApiList", value = "获取接口信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoApiQueryDo.class) + @RequestMapping("/post/AutoApiController/queryAutoApiList") + public void queryAutoApiList(InputObject inputObject, OutputObject outputObject) { + autoApiService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoApi", value = "新增/编辑接口信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoApi.class) + @RequestMapping("/post/AutoApiController/writeAutoApi") + public void writeAutoApi(InputObject inputObject, OutputObject outputObject) { + autoApiService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoApiById", value = "根据ID删除接口信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoApiController/deleteAutoApiById") + public void deleteAutoApiById(InputObject inputObject, OutputObject outputObject) { + autoApiService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoApiById", value = "根据id查询接口信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoApiController/queryAutoApiById") + public void queryAutoApiById(InputObject inputObject, OutputObject outputObject) { + autoApiService.selectById(inputObject, outputObject); + } + + /** + * 接口测试 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "apiTest", value = "接口测试", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoApi.class) + @RequestMapping("/post/AutoApiController/apiTest") + public void apiTest(InputObject inputObject, OutputObject outputObject) { + autoApiService.apiTest(inputObject, outputObject); + } + + /** + * 根据ID测试接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "apiTestById", value = "根据ID测试接口信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoApiController/apiTestById") + public void apiTestById(InputObject inputObject, OutputObject outputObject) { + autoApiService.apiTestById(inputObject, outputObject); + } +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/dao/AutoApiDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/dao/AutoApiDao.java new file mode 100644 index 0000000..d742374 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/dao/AutoApiDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.dao; + +import com.skyeye.api.entity.AutoApi; +import com.skyeye.api.entity.AutoApiQueryDo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoApiDao + * @Description: 接口管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoApiDao extends SkyeyeBaseMapper { + List> queryAutoApiList(AutoApiQueryDo commonPageInfo); + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApi.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApi.java new file mode 100644 index 0000000..de46778 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApi.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.microservice.entity.AutoMicroservice; +import com.skyeye.module.entity.AutoModule; +import com.skyeye.server.entity.AutoServer; +import lombok.Data; + +/** + * @ClassName: AutoApi + * @Description: 接口管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "auto:api", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName("auto_api") +@ApiModel(value = "接口实体类") +public class AutoApi extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("address") + @ApiModelProperty(value = "接口地址", required = "required") + private String address; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("environment_id") + @ApiModelProperty(value = "环境id", required = "required") + private String environmentId; + + @TableField(exist = false) + @Property(value = "环境信息") + private AutoEnvironment environmentMation; + + @TableField("server_id") + @ApiModelProperty(value = "服务id", required = "required") + private String serverId; + + @TableField(exist = false) + @Property(value = "服务信息") + private AutoServer serverMation; + + @TableField("microservice_id") + @ApiModelProperty(value = "微服务id", required = "required") + private String microserviceId; + + @TableField(exist = false) + @Property(value = "微服务信息") + private AutoMicroservice microserviceMation; + + @TableField("request_way") + @ApiModelProperty(value = "请求方式", required = "required") + private String requestWay; + + @TableField("input_example") + @ApiModelProperty(value = "入参示例") + private String inputExample; + + @TableField("output_example") + @ApiModelProperty(value = "出参示例") + private String outputExample; + + @TableField("module_id") + @ApiModelProperty(value = "所属模块id") + private String moduleId; + + @TableField(exist = false) + @Property(value = "模块信息") + private AutoModule moduleMation; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApiQueryDo.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApiQueryDo.java new file mode 100644 index 0000000..62fffa8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/entity/AutoApiQueryDo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: AutoApiQueryDo + * @Description: API列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("api列表查询条件实体类") +public class AutoApiQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "模块id") + private String moduleId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/AutoApiService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/AutoApiService.java new file mode 100644 index 0000000..41ae5b9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/AutoApiService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.service; + +import com.skyeye.api.entity.AutoApi; +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.history.entity.AutoHistoryStepApi; + +import java.util.Map; + +/** + * @ClassName: AutoApiService + * @Description: 接口管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoApiService extends SkyeyeTeamAuthService { + + void apiTest(InputObject inputObject, OutputObject outputObject); + + void apiTestById(InputObject inputObject, OutputObject outputObject); + + Map apiTest(String id); + + Map apiTest(AutoApi autoApi, AutoHistoryStepApi autoHistoryStepApi); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/impl/AutoApiServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/impl/AutoApiServiceImpl.java new file mode 100644 index 0000000..ee04dd1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/api/service/impl/AutoApiServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.api.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.api.classenum.AutoApiAuthEnum; +import com.skyeye.api.dao.AutoApiDao; +import com.skyeye.api.entity.AutoApi; +import com.skyeye.api.entity.AutoApiQueryDo; +import com.skyeye.api.service.AutoApiService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.HttpRequestUtil; +import com.skyeye.environment.service.AutoEnvironmentService; +import com.skyeye.exception.CustomException; +import com.skyeye.history.entity.AutoHistoryStepApi; +import com.skyeye.microservice.entity.AutoMicroservice; +import com.skyeye.microservice.service.AutoMicroserviceService; +import com.skyeye.module.service.AutoModuleService; +import com.skyeye.server.entity.AutoServer; +import com.skyeye.server.service.AutoServerService; +import com.skyeye.variable.classenum.AutoVariableType; +import com.skyeye.variable.service.AutoVariableService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: AutoApiServiceImpl + * @Description: 接口管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "接口管理", groupName = "接口管理", teamAuth = true) +public class AutoApiServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoApiService { + + @Autowired + private AutoMicroserviceService autoMicroserviceService; + + @Autowired + private AutoModuleService autoModuleService; + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + @Autowired + private AutoServerService autoServerService; + + @Autowired + private AutoVariableService autoVariableService; + + @Override + public Class getAuthEnumClass() { + return AutoApiAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoApiAuthEnum.ADD.getKey(), AutoApiAuthEnum.EDIT.getKey(), AutoApiAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + AutoApiQueryDo commonPageInfo = inputObject.getParams(AutoApiQueryDo.class); + List> beans = skyeyeBaseMapper.queryAutoApiList(commonPageInfo); + autoModuleService.setMationForMap(beans, "moduleId", "moduleMation"); + autoEnvironmentService.setMationForMap(beans, "environmentId", "environmentMation"); + autoServerService.setMationForMap(beans, "serverId", "serverMation"); + autoMicroserviceService.setMationForMap(beans, "microserviceId", "microserviceMation"); + return beans; + } + + @Override + public void apiTest(InputObject inputObject, OutputObject outputObject) { + AutoApi autoApi = inputObject.getParams(AutoApi.class); + Map result = apiTest(autoApi, null); + outputObject.setBean(result); + } + + @Override + public void apiTestById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Map result = apiTest(id); + outputObject.setBean(result); + } + + @Override + public Map apiTest(String id) { + AutoApi autoApi = selectById(id); + return apiTest(autoApi, null); + } + + @Override + public Map apiTest(AutoApi autoApi, AutoHistoryStepApi autoHistoryStepApi) { + AutoServer autoServer = autoServerService.selectById(autoApi.getServerId()); + if (ObjectUtil.isEmpty(autoServer) || StrUtil.isEmpty(autoServer.getId())) { + throw new CustomException("服务信息不存在。"); + } + AutoMicroservice autoMicroservice = autoMicroserviceService.selectById(autoApi.getMicroserviceId()); + if (ObjectUtil.isEmpty(autoMicroservice) || StrUtil.isEmpty(autoMicroservice.getId())) { + throw new CustomException("微服务信息不存在。"); + } + // 获取请求地址 + String httpUrl = String.format(Locale.ROOT, "http://%s:%s/%s%s", autoServer.getIp(), autoMicroservice.getPort(), + autoMicroservice.getPath(), autoApi.getAddress()); + // 构造参数 + Map requestHeaderKey2Value = autoVariableService.getAutoVariable(AutoVariableType.GLOBAL_HEADER.getKey(), autoApi.getEnvironmentId()); + // 发送请求 + String startTime = DateUtil.getPointTime(DateUtil.YYYY_MM_DD_HH_MM_SS_SSS); + String responseData = HttpRequestUtil.getDataByRequest(httpUrl, autoApi.getRequestWay(), requestHeaderKey2Value, autoApi.getInputExample()); + String endTime = DateUtil.getPointTime(DateUtil.YYYY_MM_DD_HH_MM_SS_SSS); + if (ObjectUtil.isNotEmpty(autoHistoryStepApi)) { + // 设置请求历史信息 + autoHistoryStepApi.setUrl(httpUrl); + autoHistoryStepApi.setMethod(autoApi.getRequestWay()); + autoHistoryStepApi.setHeader(JSONUtil.toJsonStr(requestHeaderKey2Value)); + autoHistoryStepApi.setInputValue(autoApi.getInputExample()); + autoHistoryStepApi.setOutputValue(responseData); + autoHistoryStepApi.setExecuteStartTime(startTime); + autoHistoryStepApi.setExecuteEndTime(endTime); + autoHistoryStepApi.setExecuteTime(String.valueOf(DateUtil.getDistanceMillisecondHMS(startTime, endTime, DateUtil.YYYY_MM_DD_HH_MM_SS_SSS))); + } + Map reqObj = JSONUtil.toBean(responseData, null); + return reqObj; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugAuthEnum.java new file mode 100644 index 0000000..08d7a9a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: BugAuthEnum + * @Description: buy单权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum BugAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugNecessaryToPresent.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugNecessaryToPresent.java new file mode 100644 index 0000000..082ad81 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugNecessaryToPresent.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: BugNecessaryToPresent + * @Description: 必现类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/19 15:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum BugNecessaryToPresent implements SkyeyeEnumClass { + + MUST_APPEAR(1, "必现", true, true), + NON_ESSENTIAL_OCCURRENCE(2, "非必现", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugState.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugState.java new file mode 100644 index 0000000..8bbd167 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/classenum/BugState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: BugState + * @Description: bug单状态 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum BugState implements SkyeyeEnumClass { + + UNRESOLVED("unresolved", "未解决", true, true), + TO_BE_RETURNED("toBeReturned", "待回归", true, false), + RESOLVED("resolved", "已解决", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/controller/AutoBugController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/controller/AutoBugController.java new file mode 100644 index 0000000..a8eeef1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/controller/AutoBugController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.bug.entity.AutoBug; +import com.skyeye.bug.entity.AutoBugQueryDo; +import com.skyeye.bug.service.AutoBugService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoBugController + * @Description: bug管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "bug管理", tags = "bug管理", modelName = "bug管理") +public class AutoBugController { + + @Autowired + private AutoBugService autoBugService; + + /** + * 获取bug列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoBugList", value = "获取bug列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoBugQueryDo.class) + @RequestMapping("/post/AutoBugController/queryAutoBugList") + public void queryAutoBugList(InputObject inputObject, OutputObject outputObject) { + autoBugService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑bug + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoBug", value = "新增/编辑bug", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoBug.class) + @RequestMapping("/post/AutoBugController/writeAutoBug") + public void writeAutoBug(InputObject inputObject, OutputObject outputObject) { + autoBugService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除bug信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoBugById", value = "删除bug信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoBugController/deleteAutoBugById") + public void deleteAutoBugById(InputObject inputObject, OutputObject outputObject) { + autoBugService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询bug信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoBugById", value = "根据id查询bug信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoBugController/queryAutoBugById") + public void queryAutoBugById(InputObject inputObject, OutputObject outputObject) { + autoBugService.selectById(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/dao/AutoBugDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/dao/AutoBugDao.java new file mode 100644 index 0000000..fa8936b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/dao/AutoBugDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.dao; + +import com.skyeye.bug.entity.AutoBug; +import com.skyeye.bug.entity.AutoBugQueryDo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoBugDao + * @Description: bug管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoBugDao extends SkyeyeBaseMapper { + + List> queryAutoBugList(AutoBugQueryDo pageInfo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBug.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBug.java new file mode 100644 index 0000000..1067f9b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBug.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.module.entity.AutoModule; +import com.skyeye.version.entity.AutoVersion; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: AutoBug + * @Description: bug管理---objectId就是项目id + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "auto:bug", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "auto_bug", autoResultMap = true) +@ApiModel("bug管理") +public class AutoBug extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("no") + @Property(value = "单据编号") + private String no; + + @TableField("content") + @ApiModelProperty(value = "bug内容", required = "required") + private String content; + + @TableField("state") + @ApiModelProperty(value = "状态,参考#BugState", required = "required") + private String state; + + @TableField("version_id") + @ApiModelProperty(value = "版本id", required = "required") + private String versionId; + + @TableField(exist = false) + @Property(value = "环境信息") + private AutoVersion versionMation; + + @TableField("environment_id") + @ApiModelProperty(value = "环境id", required = "required") + private String environmentId; + + @TableField(exist = false) + @Property(value = "环境信息") + private AutoEnvironment environmentMation; + + @TableField("handle_id") + @ApiModelProperty(value = "处理人id") + private String handleId; + + @TableField(exist = false) + @Property(value = "处理人信息") + private Map handleMation; + + @TableField("module_id") + @ApiModelProperty(value = "模块id", required = "required") + private String moduleId; + + @TableField(exist = false) + @Property(value = "模块信息") + private AutoModule moduleMation; + + @TableField("necessary_to_present") + @ApiModelProperty(value = "必现类型,参考#BugNecessaryToPresent", required = "required") + private String necessaryToPresent; + + @TableField("bug_reason") + @ApiModelProperty(value = "bug的原因") + private String bugReason; + + @TableField("bug_reason_type") + @ApiModelProperty(value = "bug原因的类型,参考数据字典") + private String bugReasonType; + + @TableField("terminal_occurrence") + @ApiModelProperty(value = "bug出现的终端,参考数据字典") + private String terminalOccurrence; + + @TableField("severity") + @ApiModelProperty(value = "严重性,参考数据字典") + private String severity; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBugQueryDo.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBugQueryDo.java new file mode 100644 index 0000000..bf46f78 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/entity/AutoBugQueryDo.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: AutoBugQueryDo + * @Description: bug列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("bug列表查询条件实体类") +public class AutoBugQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "模块id") + private String moduleId; + + @ApiModelProperty(value = "版本id") + private String versionId; + + @ApiModelProperty(value = "环境id") + private String environmentId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/AutoBugService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/AutoBugService.java new file mode 100644 index 0000000..a764c72 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/AutoBugService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.bug.entity.AutoBug; + +/** + * @ClassName: AutoBugService + * @Description: bug管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoBugService extends SkyeyeTeamAuthService { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/impl/AutoBugServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/impl/AutoBugServiceImpl.java new file mode 100644 index 0000000..744f5c0 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/bug/service/impl/AutoBugServiceImpl.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bug.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.bug.classenum.BugAuthEnum; +import com.skyeye.bug.dao.AutoBugDao; +import com.skyeye.bug.entity.AutoBug; +import com.skyeye.bug.entity.AutoBugQueryDo; +import com.skyeye.bug.service.AutoBugService; +import com.skyeye.common.object.InputObject; +import com.skyeye.environment.service.AutoEnvironmentService; +import com.skyeye.module.service.AutoModuleService; +import com.skyeye.version.service.AutoVersionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoBugServiceImpl + * @Description: bug管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/18 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "bug管理", groupName = "bug管理", teamAuth = true) +public class AutoBugServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoBugService { + + @Autowired + private AutoModuleService autoModuleService; + + @Autowired + private AutoVersionService autoVersionService; + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + @Override + public Class getAuthEnumClass() { + return BugAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(BugAuthEnum.ADD.getKey(), BugAuthEnum.EDIT.getKey(), BugAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + AutoBugQueryDo pageInfo = inputObject.getParams(AutoBugQueryDo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryAutoBugList(pageInfo); + autoModuleService.setMationForMap(beans, "moduleId", "moduleMation"); + autoVersionService.setMationForMap(beans, "versionId", "versionMation"); + autoEnvironmentService.setMationForMap(beans, "environmentId", "environmentMation"); + iAuthUserService.setMationForMap(beans, "handleId", "handleMation"); + return beans; + } + + @Override + public void createPrepose(AutoBug entity) { + Map business = BeanUtil.beanToMap(entity); + String no = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + entity.setNo(no); + } + + @Override + public AutoBug selectById(String id) { + AutoBug autoBug = super.selectById(id); + // 设置模块信息 + autoModuleService.setDataMation(autoBug, AutoBug::getModuleId); + // 设置处理人信息 + iAuthUserService.setDataMation(autoBug, AutoBug::getHandleId); + return autoBug; + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/classenum/AutoDataBaseAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/classenum/AutoDataBaseAuthEnum.java new file mode 100644 index 0000000..1f10053 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/classenum/AutoDataBaseAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.database.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoDataBaseAuthEnum + * @Description: 项目模块权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoDataBaseAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/controller/AutoDataBaseController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/controller/AutoDataBaseController.java new file mode 100644 index 0000000..6e66933 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/controller/AutoDataBaseController.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.database.entity.AutoDataBase; +import com.skyeye.database.service.AutoDataBaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoDataBaseController + * @Description: 数据库管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "数据库管理", tags = "数据库管理", modelName = "数据库管理") +public class AutoDataBaseController { + + @Autowired + private AutoDataBaseService autoDataBaseService; + + /** + * 获取数据库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoDataBaseList", value = "获取数据库列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoDataBaseController/queryAutoDataBaseList") + public void queryAutoDataBaseList(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑数据库信 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoDataBase", value = "新增/编辑数据库信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoDataBase.class) + @RequestMapping("/post/AutoDataBaseController/writeAutoDataBase") + public void writeAutoDataBase(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除数据库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoDataBaseById", value = "根据id删除数据库信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoDataBaseController/deleteAutoDataBaseById") + public void deleteAutoDataBaseById(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询数据库配置信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoDataBaseById", value = "根据id查询数据库配置信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoDataBaseController/queryAutoDataBaseById") + public void queryAutoDataBaseById(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.selectById(inputObject, outputObject); + } + + /** + * 获取所有数据库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllAutoDataBaseList", value = "获取所有数据库列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key", required = "required")}) + @RequestMapping("/post/AutoDataBaseController/queryAllAutoDataBaseList") + public void queryAllAutoDataBaseList(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.queryAllAutoDataBaseList(inputObject, outputObject); + } + + /** + * 测试数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "testAutoDbConnection", value = "测试数据源", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "driverClass", name = "driverClass", value = "数据源驱动类", required = "required"), + @ApiImplicitParam(id = "url", name = "url", value = "数据源连接字符串", required = "required"), + @ApiImplicitParam(id = "user", name = "user", value = "用户名", required = "required"), + @ApiImplicitParam(id = "pass", name = "pass", value = "密码")}) + @RequestMapping("/post/AutoDataBaseController/testAutoDbConnection") + public void testAutoDbConnection(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.testAutoDbConnection(inputObject, outputObject); + } + + /** + * 获取数据库类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoDataBaseTypeList", value = "获取数据库类型", method = "GET", allUse = "2") + @RequestMapping("/post/AutoDataBaseController/queryAutoDataBaseTypeList") + public void queryAutoDataBaseTypeList(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.queryAutoDataBaseTypeList(inputObject, outputObject); + } + + /** + * 获取连接池类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoPoolTypeList", value = "获取连接池类型", method = "GET", allUse = "2") + @RequestMapping("/post/AutoDataBaseController/queryAutoPoolTypeList") + public void queryAutoPoolTypeList(InputObject inputObject, OutputObject outputObject) { + autoDataBaseService.queryAutoPoolTypeList(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/dao/AutoDataBaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/dao/AutoDataBaseDao.java new file mode 100644 index 0000000..13b53ec --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/dao/AutoDataBaseDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.database.entity.AutoDataBase; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportDataBaseDao + * @Description: 数据库数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoDataBaseDao extends SkyeyeBaseMapper { + + List> getAutoDataBaseList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/entity/AutoDataBase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/entity/AutoDataBase.java new file mode 100644 index 0000000..7ae64df --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/entity/AutoDataBase.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.database.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DataBase + * @Description: 数据库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "auto:database") +@TableName(value = "auto_database", autoResultMap = true) +@ApiModel("数据库实体类") +public class AutoDataBase extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField(value = "jdbc_url") + @ApiModelProperty(value = "数据源连接字符串(JDBC)", required = "required") + private String jdbcUrl; + + @TableField(value = "user") + @ApiModelProperty(value = "数据源登录用户名", required = "required") + private String user; + + @TableField(value = "password") + @ApiModelProperty(value = "数据源登录密码") + private String password; + + @TableField(exist = false) + @ApiModelProperty(value = "数据类型", required = "required") + private String dataType; + + @TableField(value = "queryer_class") + @Property(value = "获取报表引擎查询器类名") + private String queryerClass; + + @TableField(value = "driver_class") + @Property(value = "数据源驱动类") + private String driverClass; + + @TableField(exist = false) + @ApiModelProperty(value = "报表引擎查询器使用的数据源连接池类型", required = "required") + private String poolClassType; + + @TableField(value = "pool_class") + @Property(value = "报表引擎查询器使用的数据源连接池类名") + private String poolClass; + + @TableField(exist = false) + @Property(value = "报表引擎查询器使用的数据源连接池名称") + private String poolClassName; + + @TableField(value = "options", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "数据源配置选项(JSON格式)") + private List> options; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/AutoDataBaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/AutoDataBaseService.java new file mode 100644 index 0000000..28a63da --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/AutoDataBaseService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.database.entity.AutoDataBase; +import com.skyeye.sql.entity.AutoDataSource; + +/** + * @ClassName: AutoDataBaseService + * @Description: 数据库管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoDataBaseService extends SkyeyeTeamAuthService { + + /** + * 获取数据库对象 + * + * @param dataBaseId 数据库id + * @return + */ + AutoDataSource getReportDataSource(String dataBaseId); + + void queryAllAutoDataBaseList(InputObject inputObject, OutputObject outputObject); + + void testAutoDbConnection(InputObject inputObject, OutputObject outputObject); + + void queryAutoDataBaseTypeList(InputObject inputObject, OutputObject outputObject); + + void queryAutoPoolTypeList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/impl/AutoDataBaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/impl/AutoDataBaseServiceImpl.java new file mode 100644 index 0000000..011f142 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/database/service/impl/AutoDataBaseServiceImpl.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.database.classenum.AutoDataBaseAuthEnum; +import com.skyeye.database.dao.AutoDataBaseDao; +import com.skyeye.database.entity.AutoDataBase; +import com.skyeye.database.service.AutoDataBaseService; +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.util.AutoConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoDataBaseServiceImpl + * @Description: 数据库管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "数据库管理", groupName = "数据库管理", teamAuth = true) +public class AutoDataBaseServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoDataBaseService { + + private static Logger logger = LoggerFactory.getLogger(AutoDataBaseServiceImpl.class); + + @Override + public Class getAuthEnumClass() { + return AutoDataBaseAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoDataBaseAuthEnum.ADD.getKey(), AutoDataBaseAuthEnum.EDIT.getKey(), AutoDataBaseAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.getAutoDataBaseList(commonPageInfo); + beans.forEach(bean -> { + String driverClass = bean.get("driverClass").toString(); + String poolClass = bean.get("poolClass").toString(); + bean.put("dataType", AutoConstants.DataBaseMation.getTypeByDricerClass(driverClass)); + bean.put("poolClassName", AutoConstants.PoolMation.getTitleByPoolClass(poolClass)); + }); + return beans; + } + + @Override + public void validatorEntity(AutoDataBase entity) { + super.validatorEntity(entity); + entity.setDriverClass(AutoConstants.DataBaseMation.getDricerClassByType(entity.getDataType())); + entity.setQueryerClass(AutoConstants.DataBaseMation.getQueryerClassByType(entity.getDataType())); + entity.setPoolClass(AutoConstants.PoolMation.getPoolClassByType(entity.getPoolClassType())); + } + + @Override + public AutoDataBase selectById(String id) { + AutoDataBase dataBase = super.selectById(id); + dataBase.setDataType(AutoConstants.DataBaseMation.getTypeByDricerClass(dataBase.getDriverClass())); + dataBase.setPoolClassType(AutoConstants.PoolMation.getTypeByPoolClass(dataBase.getPoolClass())); + return dataBase; + } + + /** + * 获取数据库对象 + * + * @param dataBaseId 数据库id + * @return + */ + @Override + public AutoDataSource getReportDataSource(String dataBaseId) { + // 获取数据源信息 + AutoDataBase dataBase = selectById(dataBaseId); + Map options = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataBase.getOptions())) { + dataBase.getOptions().stream().forEach(bean -> { + options.put(bean.get("configurationItem").toString(), bean.get("configurationValue").toString()); + }); + } + return new AutoDataSource( + dataBaseId, + dataBase.getDriverClass(), + dataBase.getJdbcUrl(), dataBase.getUser(), dataBase.getPassword(), + dataBase.getQueryerClass(), + dataBase.getPoolClass(), + options); + } + + @Override + public void queryAllAutoDataBaseList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoDataBase::getObjectKey), objectKey); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoDataBase::getObjectId), objectId); + List result = list(queryWrapper); + + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + + @Override + public void testAutoDbConnection(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String driverClass = params.get("driverClass").toString(); + String url = params.get("url").toString(); + String user = params.get("user").toString(); + String pass = params.containsKey("pass") ? params.get("pass").toString() : ""; + connectionDataBase(driverClass, url, user, pass, outputObject); + } + + /** + * 连接数据源 + * + * @param driverClass 数据源驱动类 + * @param url 数据源连接字符串 + * @param user 用户名 + * @param password 密码 + * @param outputObject 出参以及提示信息的返回值对象 + * @return + */ + private boolean connectionDataBase(final String driverClass, final String url, final String user, final String password, OutputObject outputObject) { + Connection conn = null; + try { + Class.forName(driverClass); + conn = DriverManager.getConnection(url, user, password); + return true; + } catch (final Exception e) { + if (outputObject != null) { + outputObject.setreturnMessage(e.getMessage()); + } + return false; + } finally { + this.releaseConnection(conn); + } + } + + /** + * 释放数据源 + * + * @param conn + */ + private void releaseConnection(final Connection conn) { + if (conn != null) { + try { + conn.close(); + } catch (final SQLException ex) { + logger.warn("测试数据库连接后释放资源失败", ex); + } + } + } + + @Override + public void queryAutoDataBaseTypeList(InputObject inputObject, OutputObject outputObject) { + List> beans = AutoConstants.DataBaseMation.getDataBaseMationList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void queryAutoPoolTypeList(InputObject inputObject, OutputObject outputObject) { + List> beans = AutoConstants.PoolMation.getPoolMationList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandAuthEnum.java new file mode 100644 index 0000000..1e13ae2 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandAuthEnum.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.demand.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoDemandAuthEnum + * @Description: 接口权限枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoDemandAuthEnum implements SkyeyeEnumClass { + + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandStateEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandStateEnum.java new file mode 100644 index 0000000..f5bb4df --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/classenum/AutoDemandStateEnum.java @@ -0,0 +1,42 @@ + +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.demand.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoDemandStateEnum + * @Description: 需求表状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoDemandStateEnum implements SkyeyeEnumClass { + + WAIT_RESEARCH("waitResearch", "待研发", true, false), + RESEARCH("research", "研发中", true, false), + WAIT_TEST("waitTest", "待测试", true, false), + FINISH("finish", "已完成", true, false), + INVALID("invalid", "作废", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} + + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/controller/AutoDemandController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/controller/AutoDemandController.java new file mode 100644 index 0000000..e54b13b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/controller/AutoDemandController.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.demand.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.demand.entity.AutoDemand; +import com.skyeye.demand.entity.AutoDemandQueryDo; +import com.skyeye.demand.service.AutoDemandService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoDemandController + * @Description: 需求表控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "需求管理", tags = "需求管理", modelName = "需求管理") +public class AutoDemandController { + + @Autowired + private AutoDemandService autoDemandService; + + /** + * 获取需求表列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoDemandList", value = "获取需求表列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoDemandQueryDo.class) + @RequestMapping("/post/AutoDemandController/queryAutoDemandList") + public void queryAutoDemandList(InputObject inputObject, OutputObject outputObject) { + autoDemandService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑需求表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoDemand", value = "新增/编辑需求表信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoDemand.class) + @RequestMapping("/post/AutoDemandController/writeAutoDemand") + public void writeAutoDemand(InputObject inputObject, OutputObject outputObject) { + autoDemandService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除需求表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoDemandById", value = "根据id删除需求表信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoDemandController/deleteAutoDemandById") + public void deleteAutoDemandById(InputObject inputObject, OutputObject outputObject) { + autoDemandService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询需求表配置信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoDemandById", value = "根据id查询需求表配置信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoDemandController/queryAutoDemandById") + public void queryAutoDemandById(InputObject inputObject, OutputObject outputObject) { + autoDemandService.selectById(inputObject, outputObject); + } + + /** + * 更新需求状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateStateAutoDemandById", value = "更新需求状态", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/UserController/updateStateAutoDemandById") + public void updateStateAutoDemandById(InputObject inputObject, OutputObject outputObject) { + autoDemandService.updateStateAutoDemandById(inputObject, outputObject); + } + + /** + * 作废需求 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidAutoDemandById", value = "作废需求", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/UserController/invalidAutoDemandById") + public void invalidAutoDemandById(InputObject inputObject, OutputObject outputObject) { + autoDemandService.invalidAutoDemandById(inputObject, outputObject); + } + + + + + +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/dao/AutoDemandDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/dao/AutoDemandDao.java new file mode 100644 index 0000000..353602e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/dao/AutoDemandDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.demand.dao; + +import com.skyeye.demand.entity.AutoDemand; +import com.skyeye.demand.entity.AutoDemandQueryDo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoDemandDao + * @Description: 需求类交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoDemandDao extends SkyeyeBaseMapper { + + List> queryAutoDemandList(AutoDemandQueryDo pageInfo); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemand.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemand.java new file mode 100644 index 0000000..98c17fd --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemand.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.demand.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.module.entity.AutoModule; +import com.skyeye.version.entity.AutoVersion; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: AutoDemand + * @Description: 需求表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "auto:demand", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "auto_demand", autoResultMap = true) +@ApiModel("需求表实体类") +public class AutoDemand extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty("编号,主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField(value = "no") + @Property(value = "单据编号") + private String no; + + @TableField(value = "content") + @ApiModelProperty(value = "需求内容") + private String content; + + @TableField(value = "state") + @ApiModelProperty(value = "状态,参考#AutoDemandStateEnum") + private String state; + + @TableField(value = "version_id") + @ApiModelProperty(value = "版本id", required = "required") + private String versionId; + + @TableField(exist = false) + @Property(value = "版本信息") + private AutoVersion versionMation; + + @TableField(value = "module_id") + @ApiModelProperty(value = "模块id", required = "required") + private String moduleId; + + @TableField(exist = false) + @Property(value = "模块信息") + private AutoModule moduleMation; + + @TableField("handle_id") + @ApiModelProperty(value = "处理人id") + private String handleId; + + @TableField(exist = false) + @Property(value = "处理人信息") + private Map handleMation; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} + + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemandQueryDo.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemandQueryDo.java new file mode 100644 index 0000000..10042f4 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/entity/AutoDemandQueryDo.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.demand.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: AutoDemandQueryDo + * @Description: 需求列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("需求列表查询条件实体类") +public class AutoDemandQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "模块id") + private String moduleId; + + @ApiModelProperty(value = "版本id") + private String versionId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/AutoDemandService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/AutoDemandService.java new file mode 100644 index 0000000..c96cdde --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/AutoDemandService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.demand.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.demand.entity.AutoDemand; + +/** + * @ClassName: AutoDemandService + * @Description: 需求类服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoDemandService extends SkyeyeTeamAuthService { + + + void updateStateAutoDemandById(InputObject inputObject, OutputObject outputObject); + + void invalidAutoDemandById(InputObject inputObject, OutputObject outputObject); + + + +} + + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/impl/AutoDemandServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/impl/AutoDemandServiceImpl.java new file mode 100644 index 0000000..7717802 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/demand/service/impl/AutoDemandServiceImpl.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.demand.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.demand.classenum.AutoDemandAuthEnum; +import com.skyeye.demand.classenum.AutoDemandStateEnum; +import com.skyeye.demand.dao.AutoDemandDao; +import com.skyeye.demand.entity.AutoDemand; +import com.skyeye.demand.entity.AutoDemandQueryDo; +import com.skyeye.demand.service.AutoDemandService; +import com.skyeye.exception.CustomException; +import com.skyeye.module.service.AutoModuleService; +import com.skyeye.version.service.AutoVersionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoDemandServiceImpl + * @Description: 需求表服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "需求管理", groupName = "需求管理", teamAuth = true) +public class AutoDemandServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoDemandService { + + @Autowired + private AutoVersionService autoVersionService; + + @Autowired + private AutoModuleService autoModuleService; + + @Autowired + private AutoDemandService autoDemandService; + + @Override + public Class getAuthEnumClass() { + return AutoDemandAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoDemandAuthEnum.ADD.getKey(), AutoDemandAuthEnum.EDIT.getKey(), AutoDemandAuthEnum.DELETE.getKey()); + } + + @Override + public void createPrepose(AutoDemand autoDemand) { + Map business = BeanUtil.beanToMap(autoDemand); + String no = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + autoDemand.setNo(no); + autoDemand.setState("waitResearch"); //设置默认值 + } + + + @Override + public void deletePreExecution(AutoDemand autoDemand) { + String state = autoDemand.getState(); + if (state.equals(AutoDemandStateEnum.INVALID.getKey()) || state.equals(AutoDemandStateEnum.FINISH.getKey())) { + throw new CustomException("已完成或已作废,不可删除"); + } + } + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoDemand::getObjectId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + AutoDemandQueryDo pageInfo = inputObject.getParams(AutoDemandQueryDo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryAutoDemandList(pageInfo); + autoVersionService.setMationForMap(beans, "versionId", "versionMation"); + autoModuleService.setMationForMap(beans, "moduleId", "moduleMation"); + iAuthUserService.setMationForMap(beans, "handleId", "handleMation"); + return beans; + } + + @Override + public AutoDemand selectById(String id) { + AutoDemand autoDemand = super.selectById(id); + autoVersionService.setDataMation(autoDemand, AutoDemand::getVersionId); + autoModuleService.setDataMation(autoDemand, AutoDemand::getModuleId); + iAuthUserService.setDataMation(autoDemand, AutoDemand::getHandleId); + return autoDemand; + } + + + @Override + public void updateStateAutoDemandById(InputObject inputObject, OutputObject outputObject) { + String id=inputObject.getParams().get("id").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + AutoDemand autoDemand = this.selectById(id); + String state = autoDemand.getState(); + if (state.equals(AutoDemandStateEnum.INVALID.getKey()) || state.equals(AutoDemandStateEnum.FINISH.getKey())) { + throw new CustomException("已完成或已作废,不可修改"); + }else if(state.equals(AutoDemandStateEnum.WAIT_RESEARCH.getKey())){ + autoDemand.setState(AutoDemandStateEnum.RESEARCH.getKey()); + }else if(state.equals(AutoDemandStateEnum.RESEARCH.getKey())){ + autoDemand.setState(AutoDemandStateEnum.WAIT_TEST.getKey()); + }else if(state.equals(AutoDemandStateEnum.WAIT_TEST.getKey())){ + autoDemand.setState(AutoDemandStateEnum.FINISH.getKey());} + else throw new CustomException("false"); + autoDemandService.updateEntity(autoDemand, userId); + this.refreshCache(id); + outputObject.setBean(autoDemand); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void invalidAutoDemandById(InputObject inputObject,OutputObject outputObject){ + String id=inputObject.getParams().get("id").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + AutoDemand autoDemand = this.selectById(id); + String state = autoDemand.getState(); + if (state.equals(AutoDemandStateEnum.INVALID.getKey()) || state.equals(AutoDemandStateEnum.FINISH.getKey())) { + throw new CustomException("已完成或已作废,不可修改"); + }else if(state.equals(AutoDemandStateEnum.WAIT_RESEARCH.getKey())||state.equals(AutoDemandStateEnum.RESEARCH.getKey())||state.equals(AutoDemandStateEnum.WAIT_TEST.getKey())){ + autoDemand.setState(AutoDemandStateEnum.INVALID.getKey()); + } + else throw new CustomException("false"); + autoDemandService.updateEntity(autoDemand, userId); + this.refreshCache(id); + outputObject.setBean(autoDemand); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/classenum/AutoEnvironmentAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/classenum/AutoEnvironmentAuthEnum.java new file mode 100644 index 0000000..96f8db0 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/classenum/AutoEnvironmentAuthEnum.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoEnvironmentAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/controller/AutoEnvironmentController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/controller/AutoEnvironmentController.java new file mode 100644 index 0000000..20e62cc --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/controller/AutoEnvironmentController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.environment.service.AutoEnvironmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoEnvironmentController + * @Description: 环境管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "环境管理", tags = "环境管理", modelName = "环境管理") +public class AutoEnvironmentController { + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + /** + * 获取环境信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoEnvironmentList", value = "获取环境信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoEnvironmentController/queryAutoEnvironmentList") + public void queryAutoEnvironmentList(InputObject inputObject, OutputObject outputObject) { + autoEnvironmentService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改环境信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoEnvironment", value = "新增/编辑环境信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoEnvironment.class) + @RequestMapping("/post/AutoEnvironmentController/writeAutoEnvironment") + public void writeAutoEnvironment(InputObject inputObject, OutputObject outputObject) { + autoEnvironmentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除环境信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoEnvironmentById", value = "根据ID删除环境信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoEnvironmentController/deleteAutoEnvironmentById") + public void deleteAutoEnvironmentById(InputObject inputObject, OutputObject outputObject) { + autoEnvironmentService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有环境信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllAutoEnvironmentList", value = "获取所有环境信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key", required = "required")}) + @RequestMapping("/post/AutoEnvironmentController/queryAllAutoEnvironmentList") + public void queryAllAutoEnvironmentList(InputObject inputObject, OutputObject outputObject) { + autoEnvironmentService.queryAllAutoEnvironmentList(inputObject, outputObject); + } +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/dao/AutoEnvironmentDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/dao/AutoEnvironmentDao.java new file mode 100644 index 0000000..efb6b88 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/dao/AutoEnvironmentDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoEnvironmentDao + * @Description: 环境管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoEnvironmentDao extends SkyeyeBaseMapper { + List> queryAutoEnvironmentList(CommonPageInfo commonPageInfo); + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/entity/AutoEnvironment.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/entity/AutoEnvironment.java new file mode 100644 index 0000000..27e2592 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/entity/AutoEnvironment.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: AutoEnvironment + * @Description: 环境管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "name"}) +@RedisCacheField(name = "auto:environment", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "auto_environment", autoResultMap = true) +@ApiModel("环境实体类") +public class AutoEnvironment extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("type") + @ApiModelProperty(value = "环境类型", required = "required") + private String type; + +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/AutoEnvironmentService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/AutoEnvironmentService.java new file mode 100644 index 0000000..3c95219 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/AutoEnvironmentService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.environment.entity.AutoEnvironment; + +/** + * @ClassName: AutoEnvironmentService + * @Description: 环境管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoEnvironmentService extends SkyeyeTeamAuthService { + + void queryAllAutoEnvironmentList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/impl/AutoEnvironmentServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/impl/AutoEnvironmentServiceImpl.java new file mode 100644 index 0000000..d99fd65 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/environment/service/impl/AutoEnvironmentServiceImpl.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.environment.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.environment.classenum.AutoEnvironmentAuthEnum; +import com.skyeye.environment.dao.AutoEnvironmentDao; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.environment.service.AutoEnvironmentService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoEnvironmentServiceImpl + * @Description: 环境管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "环境管理", groupName = "环境管理", teamAuth = true) +public class AutoEnvironmentServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoEnvironmentService { + + @Override + public Class getAuthEnumClass() { + return AutoEnvironmentAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoEnvironmentAuthEnum.ADD.getKey(), AutoEnvironmentAuthEnum.EDIT.getKey(), AutoEnvironmentAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoEnvironmentList(commonPageInfo); + return beans; + } + + @Override + public void queryAllAutoEnvironmentList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoEnvironment::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoEnvironment::getObjectKey), objectKey); + List result = list(queryWrapper); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/classenum/AutoHistoryCaseExecuteResult.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/classenum/AutoHistoryCaseExecuteResult.java new file mode 100644 index 0000000..0ab3a66 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/classenum/AutoHistoryCaseExecuteResult.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoHistoryCaseExecuteResult + * @Description: 执行结果枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoHistoryCaseExecuteResult implements SkyeyeEnumClass { + + IN_PROGRESS(1, "执行中", true, false), + EXECUTION_SUCCESSFUL(2, "执行成功", true, false), + EXECUTION_FAILED(3, "执行失败", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/controller/AutoHistoryCaseController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/controller/AutoHistoryCaseController.java new file mode 100644 index 0000000..199cd43 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/controller/AutoHistoryCaseController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.history.service.AutoHistoryCaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoHistoryCaseController + * @Description: 用例执行历史控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用例执行历史", tags = "用例执行历史", modelName = "用例执行历史") +public class AutoHistoryCaseController { + + @Autowired + private AutoHistoryCaseService autoHistoryCaseService; + + /** + * 获取用例执行历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoCaseHistoryList", value = "获取用例执行历史列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoHistoryCaseController/queryAutoCaseHistoryList") + public void queryAutoCaseHistoryList(InputObject inputObject, OutputObject outputObject) { + autoHistoryCaseService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id查询执行历史详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoCaseHistoryById", value = "根据id查询执行历史详情信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id。", required = "required")}) + @RequestMapping("/post/AutoHistoryCaseController/queryAutoCaseHistoryById") + public void queryAutoCaseHistoryById(InputObject inputObject, OutputObject outputObject) { + autoHistoryCaseService.selectById(inputObject, outputObject); + } + + /** + * 根据id强制结束执行信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "finishAutoCaseHistoryById", value = "根据id强制结束执行信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id。", required = "required")}) + @RequestMapping("/post/AutoHistoryCaseController/finishAutoCaseHistoryById") + public void finishAutoCaseHistoryById(InputObject inputObject, OutputObject outputObject) { + autoHistoryCaseService.finishAutoCaseHistoryById(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryCaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryCaseDao.java new file mode 100644 index 0000000..304721f --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryCaseDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryCase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryCaseDao + * @Description: 用例执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryCaseDao extends SkyeyeBaseMapper { + + List> queryAutoCaseHistoryList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepApiDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepApiDao.java new file mode 100644 index 0000000..7271ff9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepApiDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryStepApi; + +/** + * @ClassName: AutoHistoryStepApiDao + * @Description: API执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 22:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepApiDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepAssertDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepAssertDao.java new file mode 100644 index 0000000..870047a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepAssertDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryStepAssert; + +/** + * @ClassName: AutoHistoryStepAssertDao + * @Description: 断言执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepAssertDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepCaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepCaseDao.java new file mode 100644 index 0000000..4b5a42c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepCaseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryStepCase; + +/** + * @ClassName: AutoHistoryStepCaseDao + * @Description: 步骤为用例的执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 9:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepCaseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDao.java new file mode 100644 index 0000000..208bb54 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryStep; + +/** + * @ClassName: AutoHistoryStepDao + * @Description: 步骤执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDatabaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDatabaseDao.java new file mode 100644 index 0000000..b658f69 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/dao/AutoHistoryStepDatabaseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.history.entity.AutoHistoryStepDatabase; + +/** + * @ClassName: AutoHistoryStepDatabaseDao + * @Description: 数据库执行历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepDatabaseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryCase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryCase.java new file mode 100644 index 0000000..32402e8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryCase.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AutoHistoryCase + * @Description: 用例执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "auto:history:case") +@TableName(value = "auto_history_case") +@ApiModel(value = "用例执行历史实体类") +public class AutoHistoryCase extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @Property(value = "名称") + private String name; + + @TableField("module_id") + @Property(value = "模块id") + private String moduleId; + + @TableField("result_key") + @Property(value = "结果的key") + private String resultKey; + + @TableField("case_id") + @Property(value = "用例id") + private String caseId; + + @TableField("execute_start_time") + @Property(value = "执行开始时间") + private String executeStartTime; + + @TableField("execute_end_time") + @Property(value = "执行结束时间") + private String executeEndTime; + + @TableField("execute_time") + @Property(value = "执行耗时 毫秒") + private String executeTime; + + @TableField("execute_result") + @Property(value = "执行结果,参考#AutoHistoryCaseExecuteResult") + private Integer executeResult; + + @TableField(exist = false) + @Property(value = "步骤信息") + private List stepList; + + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStep.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStep.java new file mode 100644 index 0000000..79047a0 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStep.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AutoHistoryStep + * @Description: 步骤执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_history_step") +@ApiModel(value = "步骤执行历史实体类") +public class AutoHistoryStep extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @Property(value = "名称") + private String name; + + @TableField("history_case_id") + @Property(value = "用例id") + private String historyCaseId; + + @TableField("order_by") + @Property(value = "顺序") + private Integer orderBy; + + @TableField("type") + @Property(value = "步骤类型,参考#AutoStepTypeEnum") + private Integer type; + + @TableField("result_key") + @Property(value = "结果的key") + private String resultKey; + + @TableField("execute_result") + @Property(value = "执行结果,参考#AutoHistoryCaseExecuteResult") + private Integer executeResult; + + @TableField(exist = false) + @Property(value = "断言") + private List autoHistoryStepAssertList; + + @TableField(exist = false) + @Property(value = "API") + private AutoHistoryStepApi autoHistoryStepApi; + + @TableField(exist = false) + @Property(value = "用例") + private AutoHistoryStepCase autoHistoryStepCase; + + @TableField(exist = false) + @Property(value = "数据库") + private AutoHistoryStepDatabase autoHistoryStepDatabase; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepApi.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepApi.java new file mode 100644 index 0000000..4f705a6 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepApi.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoHistoryStepApi + * @Description: API执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_history_step_api") +@ApiModel(value = "API执行历史实体类") +public class AutoHistoryStepApi extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "history_step_id") + @Property(value = "历史步骤id") + private String historyStepId; + + @TableField(value = "url") + @Property(value = "接口请求url地址") + private String url; + + @TableField(value = "method") + @Property(value = "请求方式") + private String method; + + @TableField(value = "header") + @Property(value = "请求头") + private String header; + + @TableField("input_value") + @Property(value = "入参") + private String inputValue; + + @TableField("output_value") + @Property(value = "出参") + private String outputValue; + + @TableField("execute_start_time") + @Property(value = "请求开始时间") + private String executeStartTime; + + @TableField("execute_end_time") + @Property(value = "请求结束时间") + private String executeEndTime; + + @TableField("execute_time") + @Property(value = "请求耗时 毫秒") + private String executeTime; + + @TableField("history_case_id") + @Property(value = "用例id") + private String historyCaseId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepAssert.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepAssert.java new file mode 100644 index 0000000..b2b1859 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepAssert.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoHistoryStepAssert + * @Description: 断言执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_history_assert") +@ApiModel(value = "断言执行历史实体类") +public class AutoHistoryStepAssert extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "history_step_id") + @Property(value = "历史步骤id") + private String historyStepId; + + @TableField("`key`") + @Property(value = "断言的取值参数") + private String key; + + @TableField("operator") + @Property(value = "操作符") + private String operator; + + @TableField("value_from") + @Property(value = "值的数据来源,参考#AutoValueFromTypeEnum") + private Integer valueFrom; + + @TableField("value") + @Property(value = "断言对比得值") + private String value; + + @TableField("real_value") + @Property(value = "真实值") + private String realValue; + + @TableField("order_by") + @Property(value = "排序") + private Integer orderBy; + + @TableField("history_case_id") + @Property(value = "用例id") + private String historyCaseId; + + @TableField("execute_result") + @Property(value = "执行结果,参考#AutoHistoryCaseExecuteResult") + private Integer executeResult; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepCase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepCase.java new file mode 100644 index 0000000..d316c47 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepCase.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoHistoryStepApi + * @Description: 步骤为用例的执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_history_step_case") +@ApiModel(value = "步骤为用例的执行历史实体类") +public class AutoHistoryStepCase extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "history_step_id") + @Property(value = "历史步骤id") + private String historyStepId; + + @TableField(value = "execute_case_id") + @Property(value = "执行的用例id") + private String executeCaseId; + + @TableField("input_value") + @Property(value = "入参") + private String inputValue; + + @TableField("output_value") + @Property(value = "出参") + private String outputValue; + + @TableField("history_case_id") + @Property(value = "用例id") + private String historyCaseId; + + @TableField("execute_result") + @Property(value = "执行结果,参考#AutoHistoryCaseExecuteResult") + private Integer executeResult; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepDatabase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepDatabase.java new file mode 100644 index 0000000..6f08bdb --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/entity/AutoHistoryStepDatabase.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoHistoryStepDatabase + * @Description: 数据库执行历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_history_database") +@ApiModel(value = "数据库执行历史实体类") +public class AutoHistoryStepDatabase extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "history_step_id") + @Property(value = "历史步骤id") + private String historyStepId; + + @TableField(value = "database_id") + @Property(value = "数据库id") + private String databaseId; + + @TableField(value = "sql_content") + @Property(value = "sql脚本") + private String sqlContent; + + @TableField("output_value") + @Property(value = "出参") + private String outputValue; + + @TableField("history_case_id") + @Property(value = "用例id") + private String historyCaseId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryCaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryCaseService.java new file mode 100644 index 0000000..a5bae45 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryCaseService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.history.entity.AutoHistoryCase; + +/** + * @ClassName: AutoHistoryCaseService + * @Description: 用例执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryCaseService extends SkyeyeBusinessService { + + /** + * 判断指定用例是否在执行中 + * + * @param caseId + * @return true:存在执行中的用例,false:不存在执行中的用例 + */ + Boolean checkUserCaseRuning(String caseId); + + void finishAutoCaseHistoryById(InputObject inputObject, OutputObject outputObject); + + void finishAutoCaseHistoryById(String id, Integer result); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepApiService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepApiService.java new file mode 100644 index 0000000..24dda1b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepApiService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStepApi; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryStepApiService + * @Description: API执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 22:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepApiService extends SkyeyeBusinessService { + + void saveList(String objectId, List list); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepAssertService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepAssertService.java new file mode 100644 index 0000000..90e84c8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepAssertService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStepAssert; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryStepAssertService + * @Description: 断言执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepAssertService extends SkyeyeBusinessService { + + void saveList(String objectId, List list); + + void deleteByObjectId(String objectId); + + Map> selectByObjectId(String objectId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepCaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepCaseService.java new file mode 100644 index 0000000..77ba9e9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepCaseService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStepCase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryStepCaseService + * @Description: 步骤为用例的执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 9:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepCaseService extends SkyeyeBusinessService { + + void saveList(String objectId, List list); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepDatabaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepDatabaseService.java new file mode 100644 index 0000000..3dd0f25 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepDatabaseService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStepDatabase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryStepDatabaseService + * @Description: 数据库执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepDatabaseService extends SkyeyeBusinessService { + + void saveList(String objectId, List list); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepService.java new file mode 100644 index 0000000..05aa210 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/AutoHistoryStepService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStep; + +import java.util.List; + +/** + * @ClassName: AutoHistoryStepService + * @Description: 步骤执行历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoHistoryStepService extends SkyeyeBusinessService { + + List queryAutoStepListByCaseId(String historyCaseId); + + void deleteByObjectId(String objectId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryCaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryCaseServiceImpl.java new file mode 100644 index 0000000..14967c7 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryCaseServiceImpl.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.classenum.AutoHistoryCaseExecuteResult; +import com.skyeye.history.dao.AutoHistoryCaseDao; +import com.skyeye.history.entity.AutoHistoryCase; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.history.service.AutoHistoryCaseService; +import com.skyeye.history.service.AutoHistoryStepService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoHistoryCaseServiceImpl + * @Description: 用例执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用例执行历史管理", groupName = "用例执行历史管理") +public class AutoHistoryCaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryCaseService { + + @Autowired + private AutoHistoryStepService autoHistoryStepService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoCaseHistoryList(commonPageInfo); + return beans; + } + + @Override + public void createPrepose(AutoHistoryCase entity) { + entity.setExecuteResult(AutoHistoryCaseExecuteResult.IN_PROGRESS.getKey()); + entity.setExecuteStartTime(DateUtil.getPointTime(DateUtil.YYYY_MM_DD_HH_MM_SS_SSS)); + } + + @Override + public void updatePostpose(AutoHistoryCase autoHistoryCase, String userId) { + List autoHistoryStepList = autoHistoryCase.getStepList(); + autoHistoryStepList.forEach(autoStep -> { + autoStep.setHistoryCaseId(autoHistoryCase.getId()); + }); + autoHistoryStepService.createEntity(autoHistoryCase.getStepList(), userId); + } + + public AutoHistoryCase getDataFromDb(String id) { + AutoHistoryCase autoHistoryCase = super.getDataFromDb(id); + autoHistoryCase.setStepList(autoHistoryStepService.queryAutoStepListByCaseId(id)); + return autoHistoryCase; + } + + @Override + public void deletePostpose(String objectId) { + autoHistoryStepService.deleteByObjectId(objectId); + } + + @Override + public Boolean checkUserCaseRuning(String caseId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryCase::getCaseId), caseId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryCase::getExecuteResult), AutoHistoryCaseExecuteResult.IN_PROGRESS.getKey()); + List autoHistoryCases = list(queryWrapper); + if (CollectionUtil.isEmpty(autoHistoryCases)) { + return false; + } + return true; + } + + @Override + public void finishAutoCaseHistoryById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + finishAutoCaseHistoryById(id, AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey()); + } + + @Override + public void finishAutoCaseHistoryById(String id, Integer result) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(AutoHistoryCase::getExecuteResult), result); + String endTime = DateUtil.getPointTime(DateUtil.YYYY_MM_DD_HH_MM_SS_SSS); + AutoHistoryCase autoHistoryCase = selectById(id); + updateWrapper.set(MybatisPlusUtil.toColumns(AutoHistoryCase::getExecuteEndTime), endTime); + updateWrapper.set(MybatisPlusUtil.toColumns(AutoHistoryCase::getExecuteTime), String.valueOf(DateUtil.getDistanceMillisecondHMS(autoHistoryCase.getExecuteStartTime(), endTime, DateUtil.YYYY_MM_DD_HH_MM_SS_SSS))); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepApiServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepApiServiceImpl.java new file mode 100644 index 0000000..9410c5b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepApiServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.dao.AutoHistoryStepApiDao; +import com.skyeye.history.entity.AutoHistoryStepApi; +import com.skyeye.history.service.AutoHistoryStepApiService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoHistoryStepApiServiceImpl + * @Description: API执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 22:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "API执行历史管理", groupName = "API执行历史管理", manageShow = false) +public class AutoHistoryStepApiServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryStepApiService { + + @Override + public void saveList(String objectId, List list) { + if (CollectionUtil.isNotEmpty(list)) { + for (AutoHistoryStepApi apis : list) { + apis.setHistoryCaseId(objectId); + } + createEntity(list, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepApi::getHistoryCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepApi::getHistoryCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(AutoHistoryStepApi::getHistoryStepId, Function.identity(), (v1, v2) -> v1)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepAssertServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepAssertServiceImpl.java new file mode 100644 index 0000000..47534ac --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepAssertServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.dao.AutoHistoryStepAssertDao; +import com.skyeye.history.entity.AutoHistoryStepAssert; +import com.skyeye.history.service.AutoHistoryStepAssertService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoHistoryStepAssertServiceImpl + * @Description: 断言执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "断言执行历史管理", groupName = "断言执行历史管理", manageShow = false) +public class AutoHistoryStepAssertServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryStepAssertService { + + @Override + public void saveList(String objectId, List list) { + if (CollectionUtil.isNotEmpty(list)) { + for (AutoHistoryStepAssert historyStepAssert : list) { + historyStepAssert.setHistoryCaseId(objectId); + } + createEntity(list, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepAssert::getHistoryCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map> selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepAssert::getHistoryCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.groupingBy(AutoHistoryStepAssert::getHistoryStepId)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepCaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepCaseServiceImpl.java new file mode 100644 index 0000000..4f7100c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepCaseServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.dao.AutoHistoryStepCaseDao; +import com.skyeye.history.entity.AutoHistoryStepCase; +import com.skyeye.history.service.AutoHistoryStepCaseService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoHistoryStepCaseServiceImpl + * @Description: 步骤为用例的执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 9:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "步骤为用例的执行历史管理", groupName = "步骤为用例的执行历史管理", manageShow = false) +public class AutoHistoryStepCaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryStepCaseService { + + @Override + public void saveList(String objectId, List list) { + if (CollectionUtil.isNotEmpty(list)) { + for (AutoHistoryStepCase autoHistoryStepCase : list) { + autoHistoryStepCase.setHistoryCaseId(objectId); + } + createEntity(list, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepCase::getHistoryCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepCase::getHistoryCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(AutoHistoryStepCase::getHistoryStepId, Function.identity(), (v1, v2) -> v1)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepDatabaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepDatabaseServiceImpl.java new file mode 100644 index 0000000..b035456 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepDatabaseServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.dao.AutoHistoryStepDatabaseDao; +import com.skyeye.history.entity.AutoHistoryStepDatabase; +import com.skyeye.history.service.AutoHistoryStepDatabaseService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoHistoryStepDatabaseServiceImpl + * @Description: 数据库执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/17 8:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "数据库执行历史管理", groupName = "数据库执行历史管理", manageShow = false) +public class AutoHistoryStepDatabaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryStepDatabaseService { + + @Override + public void saveList(String objectId, List list) { + if (CollectionUtil.isNotEmpty(list)) { + for (AutoHistoryStepDatabase historyStepDatabase : list) { + historyStepDatabase.setHistoryCaseId(objectId); + } + createEntity(list, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepDatabase::getHistoryCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStepDatabase::getHistoryCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(AutoHistoryStepDatabase::getHistoryStepId, Function.identity(), (v1, v2) -> v1)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepServiceImpl.java new file mode 100644 index 0000000..c881682 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/history/service/impl/AutoHistoryStepServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.history.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.history.dao.AutoHistoryStepDao; +import com.skyeye.history.entity.*; +import com.skyeye.history.service.*; +import com.skyeye.usercase.classenum.AutoStepTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoHistoryStepServiceImpl + * @Description: 步骤执行历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "步骤执行历史管理", groupName = "步骤执行历史管理", manageShow = false) +public class AutoHistoryStepServiceImpl extends SkyeyeBusinessServiceImpl implements AutoHistoryStepService { + + @Autowired + private AutoHistoryStepApiService autoHistoryStepApiService; + + @Autowired + private AutoHistoryStepAssertService autoHistoryStepAssertService; + + @Autowired + private AutoHistoryStepDatabaseService autoHistoryStepDatabaseService; + + @Autowired + private AutoHistoryStepCaseService autoHistoryStepCaseService; + + @Override + public void writePostpose(List autoStepList, String userId) { + if (CollectionUtil.isEmpty(autoStepList)) { + return; + } + Map> listMap = autoStepList.stream() + .collect(Collectors.groupingBy(AutoHistoryStep::getType)); + List autoHistoryStepAsserts = new ArrayList<>(); + List autoHistoryStepApis = new ArrayList<>(); + List autoHistoryStepCases = new ArrayList<>(); + List autoHistoryStepDatabases = new ArrayList<>(); + listMap.forEach((key, value) -> { + if (key.equals(AutoStepTypeEnum.STEP.getKey())) { + value.forEach(step -> { + step.getAutoHistoryStepApi().setHistoryStepId(step.getId()); + autoHistoryStepApis.add(step.getAutoHistoryStepApi()); + }); + } else if (key.equals(AutoStepTypeEnum.CASE.getKey())) { + value.forEach(step -> { + step.getAutoHistoryStepCase().setHistoryStepId(step.getId()); + autoHistoryStepCases.add(step.getAutoHistoryStepCase()); + }); + } else if (key.equals(AutoStepTypeEnum.DATABASE.getKey())) { + value.forEach(step -> { + step.getAutoHistoryStepDatabase().setHistoryStepId(step.getId()); + autoHistoryStepDatabases.add(step.getAutoHistoryStepDatabase()); + }); + } + value.forEach(bean -> { + // 断言 + if (CollectionUtil.isNotEmpty(bean.getAutoHistoryStepAssertList())) { + bean.getAutoHistoryStepAssertList().forEach(item -> { + item.setHistoryStepId(bean.getId()); + }); + autoHistoryStepAsserts.addAll(bean.getAutoHistoryStepAssertList()); + } + }); + }); + + String historyCaseId = autoStepList.stream().findFirst().orElse(new AutoHistoryStep()).getHistoryCaseId(); + autoHistoryStepApiService.saveList(historyCaseId, autoHistoryStepApis); + autoHistoryStepCaseService.saveList(historyCaseId, autoHistoryStepCases); + autoHistoryStepDatabaseService.saveList(historyCaseId, autoHistoryStepDatabases); + autoHistoryStepAssertService.saveList(historyCaseId, autoHistoryStepAsserts); + } + + @Override + public List queryAutoStepListByCaseId(String historyCaseId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStep::getHistoryCaseId), historyCaseId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(AutoHistoryStep::getOrderBy)); + List autoHistoryStepList = list(queryWrapper); + + Map autoHistoryStepApiMap = autoHistoryStepApiService.selectByObjectId(historyCaseId); + Map autoHistoryStepCaseMap = autoHistoryStepCaseService.selectByObjectId(historyCaseId); + Map autoHistoryStepDatabaseMap = autoHistoryStepDatabaseService.selectByObjectId(historyCaseId); + Map> autoHistoryStepAssertMap = autoHistoryStepAssertService.selectByObjectId(historyCaseId); + autoHistoryStepList.forEach(autoHistoryStep -> { + if (autoHistoryStep.getType().equals(AutoStepTypeEnum.STEP.getKey())) { + autoHistoryStep.setAutoHistoryStepApi(autoHistoryStepApiMap.get(autoHistoryStep.getId())); + } else if (autoHistoryStep.getType().equals(AutoStepTypeEnum.CASE.getKey())) { + autoHistoryStep.setAutoHistoryStepCase(autoHistoryStepCaseMap.get(autoHistoryStep.getId())); + } else if (autoHistoryStep.getType().equals(AutoStepTypeEnum.DATABASE.getKey())) { + autoHistoryStep.setAutoHistoryStepDatabase(autoHistoryStepDatabaseMap.get(autoHistoryStep.getId())); + } + // 断言 + autoHistoryStep.setAutoHistoryStepAssertList(autoHistoryStepAssertMap.get(autoHistoryStep.getId())); + }); + return autoHistoryStepList; + } + + @Override + public void deleteByObjectId(String objectId) { + autoHistoryStepApiService.deleteByObjectId(objectId); + autoHistoryStepCaseService.deleteByObjectId(objectId); + autoHistoryStepDatabaseService.deleteByObjectId(objectId); + autoHistoryStepAssertService.deleteByObjectId(objectId); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoHistoryStep::getHistoryCaseId), objectId); + remove(queryWrapper); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/classenum/AutoMicroserviceAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/classenum/AutoMicroserviceAuthEnum.java new file mode 100644 index 0000000..949f091 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/classenum/AutoMicroserviceAuthEnum.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoMicroserviceAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/controller/AutoMicroserviceController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/controller/AutoMicroserviceController.java new file mode 100644 index 0000000..856e3a3 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/controller/AutoMicroserviceController.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.microservice.entity.AutoMicroservice; +import com.skyeye.microservice.service.AutoMicroserviceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoMicroserviceController + * @Description: 微服务管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "微服务管理", tags = "微服务管理", modelName = "微服务管理") +public class AutoMicroserviceController { + + @Autowired + private AutoMicroserviceService autoMicroserviceService; + + /** + * 获取微服务信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoMicroserviceList", value = "获取微服务信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoMicroserviceController/queryAutoMicroserviceList") + public void queryAutoMicroserviceList(InputObject inputObject, OutputObject outputObject) { + autoMicroserviceService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改微服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoMicroservice", value = "新增/编辑微服务信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoMicroservice.class) + @RequestMapping("/post/AutoMicroserviceController/writeAutoMicroservice") + public void writeAutoMicroservice(InputObject inputObject, OutputObject outputObject) { + autoMicroserviceService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除微服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoMicroserviceById", value = "根据ID删除微服务信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoMicroserviceController/deleteAutoMicroserviceById") + public void deleteAutoMicroserviceById(InputObject inputObject, OutputObject outputObject) { + autoMicroserviceService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取微服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoMicroserviceById", value = "根据id获取微服务信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoMicroserviceController/queryAutoMicroserviceById") + public void queryAutoMicroserviceById(InputObject inputObject, OutputObject outputObject) { + autoMicroserviceService.selectById(inputObject, outputObject); + } + + /** + * 根据服务器id获取微服务列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoMicroserviceListByServerId", value = "根据服务器id获取微服务列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "serverId", name = "serverId", value = "服务器id", required = "required")}) + @RequestMapping("/post/AutoMicroserviceController/queryAutoMicroserviceListByServerId") + public void queryAutoMicroserviceListByServerId(InputObject inputObject, OutputObject outputObject) { + autoMicroserviceService.queryAutoMicroserviceListByServerId(inputObject, outputObject); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/dao/AutoMicroserviceDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/dao/AutoMicroserviceDao.java new file mode 100644 index 0000000..0bb4d76 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/dao/AutoMicroserviceDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.microservice.entity.AutoMicroservice; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoMicroserviceDao + * @Description: 微服务管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoMicroserviceDao extends SkyeyeBaseMapper { + + List> queryAutoMicroserviceList(CommonPageInfo commonPageInfo); + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/entity/AutoMicroservice.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/entity/AutoMicroservice.java new file mode 100644 index 0000000..dc80381 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/entity/AutoMicroservice.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.environment.entity.AutoEnvironment; +import com.skyeye.server.entity.AutoServer; +import lombok.Data; + +/** + * @ClassName: AutoMicroservice + * @Description: 微服务实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField({"serverId", "port"}) +@RedisCacheField(name = "auto:microservice", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "auto_microservice", autoResultMap = true) +@ApiModel(value = "微服务实体类") +public class AutoMicroservice extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("protocol") + @ApiModelProperty(value = "协议", required = "required") + private String protocol; + + @TableField("port") + @ApiModelProperty(value = "访问端口", required = "required") + private String port; + + @TableField("path") + @ApiModelProperty(value = "基础路径") + private String path; + + @TableField("environment_id") + @ApiModelProperty(value = "环境id", required = "required") + private String environmentId; + + @TableField(exist = false) + @Property(value = "环境信息") + private AutoEnvironment environmentMation; + + @TableField("server_id") + @ApiModelProperty(value = "服务id", required = "required") + private String serverId; + + @TableField(exist = false) + @Property(value = "服务信息") + private AutoServer serverMation; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/AutoMicroserviceService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/AutoMicroserviceService.java new file mode 100644 index 0000000..98d48c4 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/AutoMicroserviceService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.microservice.entity.AutoMicroservice; + +/** + * @ClassName: AutoMicroserviceService + * @Description: 微服务管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoMicroserviceService extends SkyeyeTeamAuthService { + void queryAutoMicroserviceListByServerId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/impl/AutoMicroserviceServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/impl/AutoMicroserviceServiceImpl.java new file mode 100644 index 0000000..0ebbf24 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/microservice/service/impl/AutoMicroserviceServiceImpl.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.microservice.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.environment.service.AutoEnvironmentService; +import com.skyeye.microservice.classenum.AutoMicroserviceAuthEnum; +import com.skyeye.microservice.dao.AutoMicroserviceDao; +import com.skyeye.microservice.entity.AutoMicroservice; +import com.skyeye.microservice.service.AutoMicroserviceService; +import com.skyeye.server.service.AutoServerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoMicroserviceServiceImpl + * @Description: 微服务管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "微服务管理", groupName = "微服务管理", teamAuth = true) +public class AutoMicroserviceServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoMicroserviceService { + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + @Autowired + private AutoServerService autoServerService; + + @Override + public Class getAuthEnumClass() { + return AutoMicroserviceAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoMicroserviceAuthEnum.ADD.getKey(), AutoMicroserviceAuthEnum.EDIT.getKey(), AutoMicroserviceAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoMicroserviceList(commonPageInfo); + autoEnvironmentService.setMationForMap(beans, "environmentId", "environmentMation"); + autoServerService.setMationForMap(beans, "serverId", "serverMation"); + return beans; + } + + @Override + public AutoMicroservice selectById(String id) { + AutoMicroservice microservice = super.selectById(id); + autoEnvironmentService.setDataMation(microservice, AutoMicroservice::getEnvironmentId); + autoServerService.setDataMation(microservice, AutoMicroservice::getServerId); + return microservice; + } + + @Override + public List selectByIds(String... ids) { + List autoMicroservices = super.selectByIds(ids); + autoEnvironmentService.setDataMation(autoMicroservices, AutoMicroservice::getEnvironmentId); + autoServerService.setDataMation(autoMicroservices, AutoMicroservice::getServerId); + return autoMicroservices; + } + + @Override + public void queryAutoMicroserviceListByServerId(InputObject inputObject, OutputObject outputObject) { + String serverId = inputObject.getParams().get("serverId").toString(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoMicroservice::getServerId), serverId); + List result = list(queryWrapper); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/classenum/ModuleAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/classenum/ModuleAuthEnum.java new file mode 100644 index 0000000..fd44faf --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/classenum/ModuleAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ModuleAuthEnum + * @Description: 项目模块权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ModuleAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/controller/AutoModuleController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/controller/AutoModuleController.java new file mode 100644 index 0000000..629e401 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/controller/AutoModuleController.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.module.entity.AutoModule; +import com.skyeye.module.service.AutoModuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoModuleController + * @Description: 项目模块管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/19 8:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "项目模块管理", tags = "项目模块管理", modelName = "项目模块管理") +public class AutoModuleController { + + @Autowired + private AutoModuleService autoModuleService; + + /** + * 获取模块信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoModuleList", value = "获取模块信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoModuleController/queryAutoModuleList") + public void queryAutoModuleList(InputObject inputObject, OutputObject outputObject) { + autoModuleService.queryPageList(inputObject, outputObject); + } + + /** + * 一次性获取所有的模块为树结构 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoModuleForTree", value = "一次性获取所有的模块为树结构", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key", required = "required")}) + @RequestMapping("/post/AutoModuleController/queryAutoModuleForTree") + public void queryAutoModuleForTree(InputObject inputObject, OutputObject outputObject) { + autoModuleService.queryAutoModuleForTree(inputObject, outputObject); + } + + /** + * 新增/编辑项目模块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoModule", value = "新增/编辑项目模块", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoModule.class) + @RequestMapping("/post/AutoModuleController/writeAutoModule") + public void writeAutoModule(InputObject inputObject, OutputObject outputObject) { + autoModuleService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除项目模块信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoModuleById", value = "删除项目模块信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoModuleController/deleteAutoModuleById") + public void deleteAutoModuleById(InputObject inputObject, OutputObject outputObject) { + autoModuleService.deleteById(inputObject, outputObject); + } + + /** + * 获取模块一级列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFirstAutoModuleList", value = "获取模块一级列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key")}) + @RequestMapping("/post/AutoModuleController/queryFirstAutoModuleList") + public void queryFirstAutoModuleList(InputObject inputObject, OutputObject outputObject) { + autoModuleService.queryFirstAutoModuleList(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/dao/AutoModuleDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/dao/AutoModuleDao.java new file mode 100644 index 0000000..a41224c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/dao/AutoModuleDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.module.entity.AutoModule; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoModuleDao + * @Description: 项目模块管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/19 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoModuleDao extends SkyeyeBaseMapper { + + List> queryAutoModuleList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/entity/AutoModule.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/entity/AutoModule.java new file mode 100644 index 0000000..eb72fb5 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/entity/AutoModule.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: AutoModule + * @Description: 项目模块管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/19 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "auto:module", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "auto_module", autoResultMap = true) +@ApiModel("项目模块管理") +public class AutoModule extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("parent_id") + @ApiModelProperty(value = "所属父id", defaultValue = "0") + private String parentId; + + @TableField(exist = false) + @Property(value = "所属父节点") + private AutoModule parentMation; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/AutoModuleService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/AutoModuleService.java new file mode 100644 index 0000000..01d6337 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/AutoModuleService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.module.entity.AutoModule; + +/** + * @ClassName: AutoModuleService + * @Description: 项目模块管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/19 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoModuleService extends SkyeyeTeamAuthService { + + void queryAutoModuleForTree(InputObject inputObject, OutputObject outputObject); + + void queryFirstAutoModuleList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/impl/AutoModuleServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/impl/AutoModuleServiceImpl.java new file mode 100644 index 0000000..159adcc --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/module/service/impl/AutoModuleServiceImpl.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.module.service.impl; + +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.module.classenum.ModuleAuthEnum; +import com.skyeye.module.dao.AutoModuleDao; +import com.skyeye.module.entity.AutoModule; +import com.skyeye.module.service.AutoModuleService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoModuleServiceImpl + * @Description: 项目模块管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/19 8:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "项目模块管理", groupName = "项目模块管理", teamAuth = true) +public class AutoModuleServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoModuleService { + + @Override + public Class getAuthEnumClass() { + return ModuleAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(ModuleAuthEnum.ADD.getKey(), ModuleAuthEnum.EDIT.getKey(), ModuleAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoModuleList(commonPageInfo); + setMationForMap(beans, "parentId", "parentMation"); + return beans; + } + + @Override + public void queryAutoModuleForTree(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoModule::getObjectKey), objectKey); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoModule::getObjectId), objectId); + List result = list(queryWrapper); + // 转为树 + List> treeNodes = TreeUtil.build(result, String.valueOf(CommonNumConstants.NUM_ZERO), new TreeNodeConfig(), + (treeNode, tree) -> { + tree.setId(treeNode.getId()); + tree.setParentId(treeNode.getParentId()); + tree.setName(treeNode.getName()); + tree.putExtra("isParent", true); + }); + outputObject.setBeans(treeNodes); + outputObject.settotal(treeNodes.size()); + } + + @Override + public void queryFirstAutoModuleList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoModule::getObjectKey), objectKey); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoModule::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoModule::getParentId), CommonNumConstants.NUM_ZERO); + List result = list(queryWrapper); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/mq/job/impl/ExecuteCaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/mq/job/impl/ExecuteCaseServiceImpl.java new file mode 100644 index 0000000..766ac3e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/mq/job/impl/ExecuteCaseServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.history.entity.AutoHistoryCase; +import com.skyeye.usercase.entity.AutoCase; +import com.skyeye.usercase.service.AutoCaseService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @ClassName: ExecuteCaseServiceImpl + * @Description: 执行用例的异步任务 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/18 20:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.usercase-execute-service}", + consumerGroup = "${topic.usercase-execute-service}", + selectorExpression = "${spring.profiles.active}") +public class ExecuteCaseServiceImpl implements RocketMQListener { + + @Autowired + private AutoCaseService autoCaseService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, StrUtil.EMPTY); + AutoHistoryCase autoHistoryCase = JSONUtil.toBean(map.get("autoHistoryCaseStr").toString(), AutoHistoryCase.class); + AutoCase autoCase = JSONUtil.toBean(map.get("autoCaseStr").toString(), AutoCase.class); + autoCaseService.updateHistoryCase(autoCase, true, autoHistoryCase); + // 任务完成 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, StrUtil.EMPTY); + } catch (Exception e) { + // 任务失败 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, StrUtil.EMPTY); + } + } + + private void updateJobMation(String jobId, String status, String responseBody) { + JobMateUpdateMation jobMateUpdateMation = new JobMateUpdateMation(); + jobMateUpdateMation.setJobId(jobId); + jobMateUpdateMation.setStatus(status); + jobMateUpdateMation.setResponseBody(responseBody); + iJobMateMationService.comMQJobMation(jobMateUpdateMation); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/classenum/AutoProductState.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/classenum/AutoProductState.java new file mode 100644 index 0000000..b66a81e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/classenum/AutoProductState.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoProductState implements SkyeyeEnumClass { + NEW("new", "新建", true, false), + PROGRESS("progress", "进行中", true, false), + COMPLETE("complete", "完成", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/controller/AutoProductController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/controller/AutoProductController.java new file mode 100644 index 0000000..97e77a0 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/controller/AutoProductController.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.product.entity.AutoProduct; +import com.skyeye.product.service.AutoProductService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoProductController + * @Description: 产品管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "产品管理", tags = "产品管理", modelName = "产品管理") +public class AutoProductController { + + @Autowired + private AutoProductService autoProductService; + + /** + * 获取产品信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoProductList", value = "获取产品信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoProductController/queryAutoProductList") + public void queryAutoProductList(InputObject inputObject, OutputObject outputObject) { + autoProductService.queryPageList(inputObject, outputObject); + } + + /** + * 获取所有产品信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllAutoProductList", value = "获取所有产品信息列表", method = "GET", allUse = "2") + @RequestMapping("/post/AutoProductController/queryAllAutoProductList") + public void queryAllAutoProductList(InputObject inputObject, OutputObject outputObject) { + autoProductService.queryAllAutoProductList(inputObject, outputObject); + } + + /** + * 添加或修改产品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoProduct", value = "新增/编辑产品信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AutoProduct.class) + @RequestMapping("/post/AutoProductController/writeAutoProduct") + public void writeAutoProduct(InputObject inputObject, OutputObject outputObject) { + autoProductService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除产品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoProductById", value = "根据ID删除产品信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoProductController/deleteAutoProductById") + public void deleteAutoProductById(InputObject inputObject, OutputObject outputObject) { + autoProductService.deleteById(inputObject, outputObject); + } + + /** + * 修改产品为进行中 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editAutoProductToProgressById", value = "修改产品为进行中", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoProductController/editAutoProductToProgressById") + public void editAutoProductToProgressById(InputObject inputObject, OutputObject outputObject) { + autoProductService.editAutoProductToProgressById(inputObject, outputObject); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/dao/AutoProductDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/dao/AutoProductDao.java new file mode 100644 index 0000000..d2e3f12 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/dao/AutoProductDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.product.entity.AutoProduct; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoProductDao + * @Description: 产品管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoProductDao extends SkyeyeBaseMapper { + List> queryAutoProductList(CommonPageInfo commonPageInfo); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/entity/AutoProduct.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/entity/AutoProduct.java new file mode 100644 index 0000000..9e3b179 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/entity/AutoProduct.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: AutoProduct + * @Description: 产品管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "auto:product", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName("auto_product") +@ApiModel(value = "产品实体类") +public class AutoProduct extends BaseGeneralInfo { + + @TableField("state") + @Property(value = "状态,参考#AutoProductState") + private String state; + + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/AutoProductService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/AutoProductService.java new file mode 100644 index 0000000..0e2764c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/AutoProductService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.product.entity.AutoProduct; + +/** + * @ClassName: AutoProductService + * @Description: 产品管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoProductService extends SkyeyeBusinessService { + void queryAllAutoProductList(InputObject inputObject, OutputObject outputObject); + + void editAutoProductToProgressById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/impl/AutoProductServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/impl/AutoProductServiceImpl.java new file mode 100644 index 0000000..37da407 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/product/service/impl/AutoProductServiceImpl.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.product.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.product.classenum.AutoProductState; +import com.skyeye.product.dao.AutoProductDao; +import com.skyeye.product.entity.AutoProduct; +import com.skyeye.product.service.AutoProductService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoProductServiceImpl + * @Description: 产品管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "产品管理", groupName = "产品管理") +public class AutoProductServiceImpl extends SkyeyeBusinessServiceImpl implements AutoProductService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoProductList(commonPageInfo); + return beans; + } + + @Override + public void createPrepose(AutoProduct entity) { + entity.setState(AutoProductState.NEW.getKey()); + } + + @Override + public void queryAllAutoProductList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoProduct::getState), AutoProductState.PROGRESS.getKey()); + List autoProductList = list(queryWrapper); + outputObject.setBeans(autoProductList); + outputObject.settotal(autoProductList.size()); + } + + @Override + public void editAutoProductToProgressById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(AutoProduct::getState), AutoProductState.PROGRESS.getKey()); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/classenum/AutoProjectState.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/classenum/AutoProjectState.java new file mode 100644 index 0000000..aa92f96 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/classenum/AutoProjectState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoProjectState + * @Description: 项目状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoProjectState implements SkyeyeEnumClass { + + GET("get", "新建", true, true), + PROGRESS("progress", "进行中", true, false), + END("end", "结束", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/controller/AutoProjectController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/controller/AutoProjectController.java new file mode 100644 index 0000000..ef413b6 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/controller/AutoProjectController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.project.entity.AutoProject; +import com.skyeye.project.entity.AutoProjectQueryDo; +import com.skyeye.project.service.AutoProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoProjectController + * @Description: 项目管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "项目管理", tags = "项目管理", modelName = "项目管理") +public class AutoProjectController { + + @Autowired + private AutoProjectService autoProjectService; + + /** + * 获取项目管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoProjectList", value = "获取项目管理列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AutoProjectQueryDo.class) + @RequestMapping("/post/AutoProjectController/queryAutoProjectList") + public void queryAutoProjectList(InputObject inputObject, OutputObject outputObject) { + autoProjectService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoProject", value = "新增/编辑项目信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AutoProject.class) + @RequestMapping("/post/AutoProjectController/writeAutoProject") + public void writeAutoProject(InputObject inputObject, OutputObject outputObject) { + autoProjectService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoProjectById", value = "根据id删除项目信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoProjectController/deleteAutoProjectById") + public void deleteAutoProjectById(InputObject inputObject, OutputObject outputObject) { + autoProjectService.deleteById(inputObject, outputObject); + } + + /** + * 获取我负责的/我创建的所有项目列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllAutoProjectList", value = "获取我负责的/我创建的所有项目列表", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "type", name = "type", value = "类型", required = "required")}) + @RequestMapping("/post/AutoProjectController/queryAllAutoProjectList") + public void queryAllAutoProjectList(InputObject inputObject, OutputObject outputObject) { + autoProjectService.queryAllAutoProjectList(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/dao/AutoProjectDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/dao/AutoProjectDao.java new file mode 100644 index 0000000..58f8e5c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/dao/AutoProjectDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.project.entity.AutoProject; +import com.skyeye.project.entity.AutoProjectQueryDo; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoProjectDao + * @Description: 项目管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoProjectDao extends SkyeyeBaseMapper { + + List> queryAutoProjectList(AutoProjectQueryDo projectQueryDo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProject.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProject.java new file mode 100644 index 0000000..279d34f --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProject.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.product.entity.AutoProduct; +import lombok.Data; + +/** + * @ClassName: AutoProject + * @Description: 项目管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "auto:project", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "auto_project", autoResultMap = true) +@ApiModel("项目管理实体类") +public class AutoProject extends BaseGeneralInfo { + + @TableField("product_id") + @ApiModelProperty(value = "产品id", required = "required") + private String productId; + + @TableField(exist = false) + @Property("产品信息") + private AutoProduct productMation; + + @TableField("state") + @ApiModelProperty(value = "状态,参考#AutoProjectState", required = "required") + private String state; + + @TableField(value = "team_template_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "团队模板id") + private String teamTemplateId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProjectQueryDo.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProjectQueryDo.java new file mode 100644 index 0000000..9e707b5 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/entity/AutoProjectQueryDo.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: AutoProjectQueryDo + * @Description: 项目列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("项目列表查询条件实体类") +public class AutoProjectQueryDo extends CommonPageInfo implements Serializable { + + /** + * 团队模板id + */ + private List teamTemplateIds; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/AutoProjectService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/AutoProjectService.java new file mode 100644 index 0000000..4bfe932 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/AutoProjectService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.project.entity.AutoProject; + +/** + * @ClassName: AutoProjectService + * @Description: 项目管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoProjectService extends SkyeyeBusinessService { + void queryAllAutoProjectList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/impl/AutoProjectServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/impl/AutoProjectServiceImpl.java new file mode 100644 index 0000000..ab01caf --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/project/service/impl/AutoProjectServiceImpl.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.project.dao.AutoProjectDao; +import com.skyeye.project.entity.AutoProject; +import com.skyeye.project.entity.AutoProjectQueryDo; +import com.skyeye.project.service.AutoProjectService; +import com.skyeye.sdk.catalog.service.CatalogSdkService; +import com.skyeye.team.service.ITeamBusinessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoProjectServiceImpl + * @Description: 项目管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "项目管理", groupName = "项目管理") +public class AutoProjectServiceImpl extends SkyeyeBusinessServiceImpl implements AutoProjectService, CatalogSdkService { + + @Autowired + private ITeamBusinessService iTeamBusinessService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + AutoProjectQueryDo projectQueryDo = inputObject.getParams(AutoProjectQueryDo.class); + if (StrUtil.equals("myCharge", projectQueryDo.getType())) { + List teamTemplateIds = iTeamBusinessService.getMyTeamIds(); + if (CollectionUtil.isEmpty(teamTemplateIds)) { + // 查询是我负责的并且我没有在任何团队的时候,直接返回 + return new ArrayList<>(); + } + projectQueryDo.setTeamTemplateIds(teamTemplateIds); + } + String userId = inputObject.getLogParams().get("id").toString(); + projectQueryDo.setCreateId(userId); + List> beans = skyeyeBaseMapper.queryAutoProjectList(projectQueryDo); + return beans; + } + + @Override + public void createPostpose(AutoProject entity, String userId) { + // 创建团队信息 + iTeamBusinessService.createTeamBusiness(entity.getTeamTemplateId(), entity.getId(), getServiceClassName()); + } + + @Override + public void deletePostpose(String id) { + iTeamBusinessService.deleteTeamBusiness(id, getServiceClassName()); + } + + @Override + public void queryAllAutoProjectList(InputObject inputObject, OutputObject outputObject) { + String type = inputObject.getParams().get("type").toString(); + AutoProjectQueryDo projectQueryDo = new AutoProjectQueryDo(); + projectQueryDo.setType(type); + String userId = inputObject.getLogParams().get("id").toString(); + projectQueryDo.setCreateId(userId); + if (StrUtil.equals("myCharge", projectQueryDo.getType())) { + List teamTemplateIds = iTeamBusinessService.getMyTeamIds(); + if (CollectionUtil.isEmpty(teamTemplateIds)) { + // 查询是我负责的并且我没有在任何团队的时候,直接返回 + return; + } + projectQueryDo.setTeamTemplateIds(teamTemplateIds); + } + List> beans = skyeyeBaseMapper.queryAutoProjectList(projectQueryDo); + String serviceClassName = getServiceClassName(); + beans.forEach(bean -> { + bean.put("serviceClassName", serviceClassName); + }); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/classnum/AutoServerAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/classnum/AutoServerAuthEnum.java new file mode 100644 index 0000000..2d83559 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/classnum/AutoServerAuthEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.classnum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoServerAuthEnum + * @Description: 服务器权限枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoServerAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/controller/AutoServerController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/controller/AutoServerController.java new file mode 100644 index 0000000..aecbda9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/controller/AutoServerController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.AutoServer; +import com.skyeye.server.service.AutoServerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoServerController + * @Description: 服务器管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "服务器管理", tags = "服务器管理", modelName = "服务器管理") +public class AutoServerController { + + @Autowired + private AutoServerService autoServerService; + + /** + * 获取服务器信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoServerList", value = "获取服务器信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoServerController/queryAutoServerList") + public void queryAutoServerList(InputObject inputObject, OutputObject outputObject) { + autoServerService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改服务器信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoServer", value = "新增/编辑服务器信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoServer.class) + @RequestMapping("/post/AutoServerController/writeAutoServer") + public void writeAutoServer(InputObject inputObject, OutputObject outputObject) { + autoServerService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除服务器信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoServerById", value = "根据ID删除服务器信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoServerController/deleteAutoServerById") + public void deleteAutoServerById(InputObject inputObject, OutputObject outputObject) { + autoServerService.deleteById(inputObject, outputObject); + } + + /** + * 根据环境id获取服务器信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoServerListByEnvironmentId", value = "根据环境id获取服务器信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "environmentId", name = "environmentId", value = "环境id")}) + @RequestMapping("/post/AutoServerController/queryAutoServerListByEnvironmentId") + public void queryAutoServerListByEnvironmentId(InputObject inputObject, OutputObject outputObject) { + autoServerService.queryAutoServerListByEnvironmentId(inputObject, outputObject); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/dao/AutoServerDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/dao/AutoServerDao.java new file mode 100644 index 0000000..128514b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/dao/AutoServerDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.server.entity.AutoServer; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoServerDao + * @Description: 服务器管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoServerDao extends SkyeyeBaseMapper { + + List> queryAutoServerList(CommonPageInfo commonPageInfo); +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/entity/AutoServer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/entity/AutoServer.java new file mode 100644 index 0000000..fe1dfd6 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/entity/AutoServer.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.environment.entity.AutoEnvironment; +import lombok.Data; + +/** + * @ClassName: AutoServer + * @Description: 服务器管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField({"objectId", "ip"}) +@RedisCacheField(name = "auto:server", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "auto_server", autoResultMap = true) +@ApiModel(value = "服务器实体类") +public class AutoServer extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("ip") + @ApiModelProperty(value = "服务器ip", required = "required") + private String ip; + + @TableField("cpu") + @ApiModelProperty(value = "服务器cpu") + private String cpu; + + @TableField("disk") + @ApiModelProperty(value = "服务器磁盘") + private String disk; + + @TableField("mem") + @ApiModelProperty(value = "服务器分配信息") + private String mem; + + @TableField("environment_id") + @ApiModelProperty(value = "环境id", required = "required") + private String environmentId; + + @TableField(exist = false) + @Property(value = "环境信息") + private AutoEnvironment environmentMation; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/AutoServerService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/AutoServerService.java new file mode 100644 index 0000000..09cbbd1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/AutoServerService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.AutoServer; + +/** + * @ClassName: AutoServerService + * @Description: 服务器管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoServerService extends SkyeyeTeamAuthService { + + void queryAutoServerListByEnvironmentId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/impl/AutoServerServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/impl/AutoServerServiceImpl.java new file mode 100644 index 0000000..267745a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/server/service/impl/AutoServerServiceImpl.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.environment.service.AutoEnvironmentService; +import com.skyeye.server.classnum.AutoServerAuthEnum; +import com.skyeye.server.dao.AutoServerDao; +import com.skyeye.server.entity.AutoServer; +import com.skyeye.server.service.AutoServerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoServerServiceImpl + * @Description: 服务器管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "服务器管理", groupName = "服务器管理", teamAuth = true) +public class AutoServerServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoServerService { + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + @Override + public Class getAuthEnumClass() { + return AutoServerAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoServerAuthEnum.ADD.getKey(), AutoServerAuthEnum.EDIT.getKey(), AutoServerAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoServerList(commonPageInfo); + autoEnvironmentService.setMationForMap(beans, "environmentId", "environmentMation"); + return beans; + } + + @Override + public AutoServer selectById(String id) { + AutoServer autoServer = super.selectById(id); + autoEnvironmentService.setDataMation(autoServer, AutoServer::getEnvironmentId); + return autoServer; + } + + @Override + public List selectByIds(String... ids) { + List autoServers = super.selectByIds(ids); + autoEnvironmentService.setDataMation(autoServers, AutoServer::getEnvironmentId); + return autoServers; + } + + @Override + public void queryAutoServerListByEnvironmentId(InputObject inputObject, OutputObject outputObject) { + String environmentId = inputObject.getParams().get("environmentId").toString(); + if (StrUtil.isEmpty(environmentId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoServer::getEnvironmentId), environmentId); + List result = list(queryWrapper); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java new file mode 100644 index 0000000..0a5edb8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool; + +/** + * @ClassName: DataSourcePoolFactory + * @Description: 数据源连接池工厂 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DataSourcePoolFactory { + public static DataSourcePoolWrapper create(final String className) { + try { + return (DataSourcePoolWrapper) Class.forName(className).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + throw new RuntimeException("DataSourcePoolFactory Load Class Error", e); + } + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java new file mode 100644 index 0000000..9a4c0fd --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool; + +import com.skyeye.sql.entity.AutoDataSource; + +import javax.sql.DataSource; + +/** + * @ClassName: DataSourcePoolWrapper + * @Description: 数据源连接包装器 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DataSourcePoolWrapper { + + DataSource wrap(AutoDataSource rptDs); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java new file mode 100644 index 0000000..e9499bb --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.mchange.v2.c3p0.ComboPooledDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import com.skyeye.sql.entity.AutoDataSource; +import org.apache.commons.collections4.MapUtils; + +import javax.sql.DataSource; + +/** + * @ClassName: C3p0DataSourcePool + * @Description: c3p0数据源连接池包装类--参考http://www.mchange.com/projects/c3p0/#quickstart + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class C3p0DataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(AutoDataSource rptDs) { + try { + ComboPooledDataSource dataSource = new ComboPooledDataSource(); + dataSource.setDriverClass(rptDs.getDriverClass()); + dataSource.setJdbcUrl(rptDs.getJdbcUrl()); + dataSource.setUser(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialPoolSize(MapUtils.getInteger(rptDs.getOptions(), "initialPoolSize", 3)); + dataSource.setMinPoolSize(MapUtils.getInteger(rptDs.getOptions(), "minPoolSize", 1)); + dataSource.setMaxPoolSize(MapUtils.getInteger(rptDs.getOptions(), "maxPoolSize", 20)); + dataSource.setMaxStatements(MapUtils.getInteger(rptDs.getOptions(), "maxStatements", 50)); + dataSource.setMaxIdleTime(MapUtils.getInteger(rptDs.getOptions(), "maxIdleTime", 1800)); + dataSource.setAcquireIncrement(MapUtils.getInteger(rptDs.getOptions(), "acquireIncrement", 3)); + dataSource.setAcquireRetryAttempts(MapUtils.getInteger(rptDs.getOptions(), "acquireRetryAttempts", 30)); + dataSource.setIdleConnectionTestPeriod( + MapUtils.getInteger(rptDs.getOptions(), "idleConnectionTestPeriod", 60)); + dataSource.setBreakAfterAcquireFailure( + MapUtils.getBoolean(rptDs.getOptions(), "breakAfterAcquireFailure", false)); + dataSource.setTestConnectionOnCheckout( + MapUtils.getBoolean(rptDs.getOptions(), "testConnectionOnCheckout", false)); + return dataSource; + } catch (Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java new file mode 100644 index 0000000..969485f --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import com.skyeye.sql.entity.AutoDataSource; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.dbcp2.BasicDataSource; + +import javax.sql.DataSource; + +/** + * @ClassName: DBCP2DataSourcePool + * @Description: c3p0数据源连接池包装类---参考http://www.mchange.com/projects/c3p0/#quickstart + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DBCP2DataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(AutoDataSource rptDs) { + try { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(rptDs.getDriverClass()); + dataSource.setUrl(rptDs.getJdbcUrl()); + dataSource.setUsername(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialSize(MapUtils.getInteger(rptDs.getOptions(), "initialSize", 3)); + dataSource.setMaxIdle(MapUtils.getInteger(rptDs.getOptions(), "maxIdle", 20)); + dataSource.setMinIdle(MapUtils.getInteger(rptDs.getOptions(), "minIdle", 1)); + dataSource.setLogAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "logAbandoned", true)); + dataSource.setRemoveAbandonedTimeout( + MapUtils.getInteger(rptDs.getOptions(), "removeAbandonedTimeout", 180)); + dataSource.setMaxWaitMillis(MapUtils.getInteger(rptDs.getOptions(), "maxWait", 1000)); + return dataSource; + } catch (final Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java new file mode 100644 index 0000000..2534c19 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.alibaba.druid.pool.DruidDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import com.skyeye.sql.entity.AutoDataSource; +import org.apache.commons.collections4.MapUtils; + +import javax.sql.DataSource; + +/** + * @ClassName: DruidDataSourcePool + * @Description: Druid数据源连接池包装类--参考https://github.com/alibaba/druid/wiki + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DruidDataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(AutoDataSource rptDs) { + try { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setDriverClassName(rptDs.getDriverClass()); + dataSource.setUrl(rptDs.getJdbcUrl()); + dataSource.setUsername(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialSize(MapUtils.getInteger(rptDs.getOptions(), "initialSize", 3)); + dataSource.setMaxActive(MapUtils.getInteger(rptDs.getOptions(), "maxActive", 20)); + dataSource.setMinIdle(MapUtils.getInteger(rptDs.getOptions(), "minIdle", 1)); + dataSource.setMaxWait(MapUtils.getInteger(rptDs.getOptions(), "maxWait", 60000)); + dataSource.setTimeBetweenEvictionRunsMillis( + MapUtils.getInteger(rptDs.getOptions(), "timeBetweenEvictionRunsMillis", 60000)); + dataSource.setMinEvictableIdleTimeMillis( + MapUtils.getInteger(rptDs.getOptions(), "minEvictableIdleTimeMillis", 300000)); + dataSource.setTestWhileIdle(MapUtils.getBoolean(rptDs.getOptions(), "testWhileIdle", true)); + dataSource.setTestOnBorrow(MapUtils.getBoolean(rptDs.getOptions(), "testOnBorrow", false)); + dataSource.setTestOnReturn(MapUtils.getBoolean(rptDs.getOptions(), "testOnReturn", false)); + dataSource.setMaxOpenPreparedStatements( + MapUtils.getInteger(rptDs.getOptions(), "maxOpenPreparedStatements", 20)); + dataSource.setRemoveAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "removeAbandoned", true)); + dataSource.setRemoveAbandonedTimeout( + MapUtils.getInteger(rptDs.getOptions(), "removeAbandonedTimeout", 1800)); + dataSource.setLogAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "logAbandoned", true)); + return dataSource; + } catch (final Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java new file mode 100644 index 0000000..ef8f83c --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import com.skyeye.sql.entity.AutoDataSource; + +import javax.sql.DataSource; +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; + +/** + * @ClassName: NoDataSourcePool + * @Description: 无数据源连接池, 直接使用jdbc连接 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class NoDataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(AutoDataSource rptDs) { + return new NoDataSource(rptDs); + } + + private static class NoDataSource implements DataSource { + private AutoDataSource reportDataSource; + + public NoDataSource(AutoDataSource reportDataSource) { + this.reportDataSource = reportDataSource; + } + + @Override + public Connection getConnection() throws SQLException { + return DriverManager.getConnection( + this.reportDataSource.getJdbcUrl(), + this.reportDataSource.getUser(), + this.reportDataSource.getPassword()); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return null; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + @Override + public PrintWriter getLogWriter() throws SQLException { + return null; + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + + } + + @Override + public int getLoginTimeout() throws SQLException { + return 0; + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/AutoDataSource.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/AutoDataSource.java new file mode 100644 index 0000000..c4f37d7 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/AutoDataSource.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: AutoDataSource + * @Description: 自动化数据库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class AutoDataSource implements Serializable { + + /** + * 获取数据源唯一标识 + */ + private String uid; + + /** + * 获取报表引擎查询器类名(如:com.easytoolsoft.easyreport.engine.query.MySqlQueryer) + */ + private String queryerClass; + + /** + * 获取报表引擎查询器使用的数据源连接池类名(如:com.skyeye.sql.dbpool.impl.C3p0DataSourcePool) + */ + private String dbPoolClass; + + /** + * 获取数据源驱动类 + */ + private String driverClass; + + /** + * 获取数据源连接字符串(JDBC) + */ + private String jdbcUrl; + + /** + * 获取数据源登录用户名 + */ + private String user; + + /** + * 获取数据源登录密码 + */ + private String password; + + /** + * 获取数据源配置选项,如果没有配置选项则设置为默认选项 + */ + private Map options; + + public AutoDataSource(String uid, String driverClass, String jdbcUrl, String user, + String password, + String queryerClass, String dbPoolClass) { + this(uid, driverClass, jdbcUrl, user, password, queryerClass, dbPoolClass, new HashMap<>(3)); + } + + public AutoDataSource(String uid, String driverClass, String jdbcUrl, String user, + String password, + String queryerClass, String dbPoolClass, + Map options) { + this.uid = uid; + this.driverClass = driverClass; + this.jdbcUrl = jdbcUrl; + this.user = user; + this.password = password; + this.queryerClass = queryerClass; + this.dbPoolClass = dbPoolClass; + this.options = options; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnSortType.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnSortType.java new file mode 100644 index 0000000..2c3e186 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnSortType.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +/** + * @ClassName: ColumnSortType + * @Description: 报表列排序类型 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public enum ColumnSortType { + + /** + * 默认 + */ + DEFAULT(0), + + /** + * 数字优先升序 + */ + DIGIT_ASCENDING(1), + + /** + * 数字优先降序 + */ + DIGIT_DESCENDING(2), + + /** + * 字符优先升序 + */ + CHAR_ASCENDING(3), + + /** + * 字符优先降序 + */ + CHAR_DESCENDING(4); + + private int value; + + ColumnSortType(int value) { + this.value = value; + } + + public static ColumnSortType valueOf(int arg) { + for (ColumnSortType item : ColumnSortType.values()) { + if (item.getValue() == arg) { + return item; + } + } + return DEFAULT; + } + + public int getValue() { + return this.value; + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnType.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnType.java new file mode 100644 index 0000000..bee86bf --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ColumnType.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +/** + * @ClassName: ColumnType + * @Description: 报表列类型 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public enum ColumnType { + /** + * 布局列 + */ + LAYOUT(1), + + /** + * 维度列 + */ + DIMENSION(2), + + /** + * 统计列 + */ + STATISTICAL(3), + + /** + * 计算列 + */ + COMPUTED(4); + + private final int value; + + ColumnType(final int value) { + this.value = value; + } + + public static ColumnType valueOf(final int arg) { + for (ColumnType item : ColumnType.values()) { + if (item.getValue() == arg) { + return item; + } + } + return DIMENSION; + } + + public int getValue() { + return this.value; + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataCell.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataCell.java new file mode 100644 index 0000000..e2ab912 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataCell.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportMetaDataCell + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportMetaDataCell implements Serializable { + private ReportMetaDataColumn column; + private String name; + private Object value; + + public ReportMetaDataCell(ReportMetaDataColumn column, String name, Object value) { + this.column = column; + this.name = name; + this.value = value; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataColumn.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataColumn.java new file mode 100644 index 0000000..828b0bf --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataColumn.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportMetaDataColumn + * @Description: 报表元数据列类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportMetaDataColumn implements Serializable { + + /** + * 获取报表元数据列的顺序(从1开始) + */ + private int ordinal; + + /** + * 获取报表元数据列名 + */ + private String name; + + /** + * 获取报表元数据列---数据类型名称 + */ + private String dataType; + + /** + * 获取报表元数据计算列的计算表达式 + */ + private String expression; + + /** + * 获取报表元数据列的格式 .String.format(format,text) + */ + private String format; + + /** + * 获取元数据列备注 + */ + private String comment; + + /** + * 获取报表元数据列宽(单位:像素) + */ + private int width; + + /** + * 获取报表元数据列的精度(即保留多少位小数,默认浮点数为4位,百分比为2位,其他为0) + */ + private int decimals; + + /** + * 获取报表元数据列类型-列类型(1:布局列, 2:维度列,3:统计列, 4:计算列) + */ + private ColumnType type = ColumnType.DIMENSION; + + /** + * 设置列排序类型(0:默认,1:数字优先升序,2:数字优先降序,3:字符优先升序,4:字符优先降序) + */ + private ColumnSortType sortType = ColumnSortType.DEFAULT; + + /** + * 获取元数据列是否支持小计 + */ + private boolean isExtensions; + + /** + * 获取元数据列是否支持条件查询 + */ + private boolean isFootings; + + /** + * 获取元数据列是否支持百分比显示 + */ + private boolean isPercent; + + /** + * 获取配置列是否支持可选择显示 + */ + private boolean isOptional; + + /** + * 获取配置列中的统计列(含计算)是否支持在邮件中显示 + */ + private boolean isDisplayInMail; + + /** + * 获取元数据列是否隐藏 + */ + private boolean isHidden; + + public ReportMetaDataColumn() { + } + + public ReportMetaDataColumn(String name, ColumnType type) { + this.name = name; + this.type = type; + } + + public String getExpression() { + return this.expression == null ? "" : this.expression; + } + + public String getFormat() { + return this.format == null ? "" : this.format; + } + + public String getComment() { + return this.comment == null ? "" : this.comment; + } + + public ReportMetaDataColumn copyToNew(String name) { + return this.copyToNew(name, this.isPercent); + } + + public ReportMetaDataColumn copyToNew(String name, boolean isPercent) { + ReportMetaDataColumn column = new ReportMetaDataColumn(); + column.setName(name); + column.setPercent(isPercent); + column.setDataType(this.dataType); + column.setExtensions(this.isExtensions); + column.setFootings(this.isFootings); + column.setHidden(this.isHidden); + column.setSortType(ColumnSortType.valueOf(this.sortType.getValue())); + column.setType(ColumnType.valueOf(this.type.getValue())); + column.setWidth(this.width); + column.setDecimals(this.decimals); + column.setOptional(this.isOptional); + column.setDisplayInMail(this.isDisplayInMail); + column.setComment(this.comment); + return column; + } +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataRow.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataRow.java new file mode 100644 index 0000000..d143ca3 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportMetaDataRow.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportMetaDataRow + * @Description: 报表元数据行类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class ReportMetaDataRow { + private final Map cells = new HashMap<>(); + private final StringBuilder rowKeyBuilder = new StringBuilder(""); + + public ReportMetaDataRow() { + } + + public ReportMetaDataRow add(final ReportMetaDataCell cell) { + this.cells.put(cell.getName(), cell); + if (cell.getColumn().getType() != ColumnType.STATISTICAL) { + final Object cellValue = cell.getValue(); + this.rowKeyBuilder.append((cellValue == null) ? "" : cellValue.toString().trim()); + this.rowKeyBuilder.append("$"); + } + return this; + } + + public ReportMetaDataRow addAll(final List cells) { + cells.forEach(this::add); + return this; + } + + public Map getCells() { + return this.cells; + } + + public ReportMetaDataCell getCell(final String name) { + return this.cells.get(name); + } + + public Object getCellValue(final String name) { + final ReportMetaDataCell cell = this.cells.get(name); + return (cell == null) ? null : cell.getValue(); + } + + public String getRowKey() { + return this.rowKeyBuilder.toString(); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportQueryParamItem.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportQueryParamItem.java new file mode 100644 index 0000000..8e35d23 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/entity/ReportQueryParamItem.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportQueryParamItem + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportQueryParamItem implements Serializable { + + private String name; + private String text; + private boolean selected; + + public ReportQueryParamItem(String name, String text) { + this.name = name; + this.text = text; + } + + public ReportQueryParamItem(String name, String text, boolean selected) { + this(name, text); + this.selected = selected; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java new file mode 100644 index 0000000..1ecabe3 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query; + +import com.skyeye.exception.CustomException; +import com.skyeye.sql.entity.*; +import com.skyeye.sql.util.JdbcUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: AbstractQueryer + * @Description: 数据库查询父类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/30 0:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public abstract class AbstractQueryer { + protected Logger logger = LoggerFactory.getLogger(this.getClass()); + protected AutoDataSource dataSource; + + protected AbstractQueryer(AutoDataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * 获取sql查询出来的所有列 + * + * @param sqlText sql语句 + * @return + */ + public List parseMetaDataColumns(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + try { + this.logger.debug("Parse Report MetaDataColumns SQL:{},", sqlText); + // 创建连接 + conn = this.getJdbcConnection(); + // 创建通讯 + stmt = conn.createStatement(); + // 执行sql + rs = stmt.executeQuery(this.preprocessSqlText(sqlText)); + // 获取列 + List columns = getReportMetaDataColumns(rs); + return columns; + } catch (SQLException ex) { + throw new CustomException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + } + + private List getReportMetaDataColumns(ResultSet rs) throws SQLException { + // 获取结果 + ResultSetMetaData rsMataData = rs.getMetaData(); + int count = rsMataData.getColumnCount(); + List columns = new ArrayList<>(count); + for (int i = 1; i <= count; i++) { + ReportMetaDataColumn column = new ReportMetaDataColumn(); + column.setName(rsMataData.getColumnLabel(i)); + column.setDataType(rsMataData.getColumnTypeName(i)); + column.setWidth(rsMataData.getColumnDisplaySize(i)); + columns.add(column); + } + return columns; + } + + public List parseQueryParamItems(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + HashSet set = new HashSet<>(); + List rows = new ArrayList<>(); + + try { + this.logger.debug(sqlText); + conn = this.getJdbcConnection(); + stmt = conn.createStatement(); + rs = stmt.executeQuery(sqlText); + while (rs.next()) { + String name = rs.getString("name"); + String text = rs.getString("text"); + name = (name == null) ? "" : name.trim(); + text = (text == null) ? "" : text.trim(); + if (!set.contains(name)) { + set.add(name); + } + rows.add(new ReportQueryParamItem(name, text)); + } + } catch (SQLException ex) { + throw new RuntimeException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + set.clear(); + return rows; + } + + public List getMetaDataRows(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + try { + // 创建连接 + conn = this.getJdbcConnection(); + // 创建通讯 + stmt = conn.createStatement(); + // 执行sql + rs = stmt.executeQuery(sqlText); + return this.getMetaDataRows(rs, this.getSqlColumns(this.getReportMetaDataColumns(rs))); + } catch (Exception ex) { + logger.warn(String.format("SqlText:{},Msg is: ", sqlText, ex)); + throw new CustomException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + } + + protected List getMetaDataRows(ResultSet rs, List sqlColumns) + throws SQLException { + List rows = new ArrayList<>(); + + while (rs.next()) { + ReportMetaDataRow row = new ReportMetaDataRow(); + for (ReportMetaDataColumn column : sqlColumns) { + Object value = rs.getObject(column.getName()); + if (column.getDataType().contains("BINARY")) { + value = new String((byte[]) value); + } + row.add(new ReportMetaDataCell(column, column.getName(), value)); + } + rows.add(row); + } + return rows; + } + + protected List getSqlColumns(List metaDataColumns) { + return metaDataColumns.stream() + .filter(x -> x.getType() != ColumnType.COMPUTED) + .collect(Collectors.toList()); + } + + /** + * 预处理获取报表列集合的sql语句, + * 在这里可以拦截全表查询等sql, 因为如果表的数据量很大,将会产生过多的内存消耗,甚至性能问题 + * + * @param sqlText 原sql语句 + * @return 预处理后的sql语句 + */ + protected String preprocessSqlText(String sqlText) { + return sqlText; + } + + /** + * 获取当前报表查询器的JDBC Connection对象 + * + * @return Connection + */ + protected Connection getJdbcConnection() { + try { + Class.forName(this.dataSource.getDriverClass()); + return JdbcUtils.getDataSource(this.dataSource).getConnection(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/Queryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/Queryer.java new file mode 100644 index 0000000..5a2900a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/Queryer.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query; + +import com.skyeye.sql.entity.ReportMetaDataColumn; +import com.skyeye.sql.entity.ReportMetaDataRow; +import com.skyeye.sql.entity.ReportQueryParamItem; + +import java.util.List; + +/** + * @ClassName: Queryer + * @Description: 报表查询器接口 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface Queryer { + /** + * 从sql语句中解析出报表元数据列集合 + * + * @param sqlText sql语句 + * @return List[ReportMetaDataColumn] + */ + List parseMetaDataColumns(String sqlText); + + /** + * 从sql语句中解析出报表查询参数(如下拉列表参数)的列表项集合 + * + * @param sqlText sql语句 + * @return List[ReportQueryParamItem] + */ + List parseQueryParamItems(String sqlText); + + /** + * 获取报表原始数据行集合 + * + * @param sqlText sql语句 + * @return + */ + List getMetaDataRows(String sqlText); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java new file mode 100644 index 0000000..bbf3838 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.factory; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.Queryer; + +import java.lang.reflect.Constructor; + +/** + * @ClassName: QueryerFactory + * @Description: 报表查询器工厂方法类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class QueryerFactory { + + public static Queryer create(AutoDataSource dataSource) { + if (dataSource != null) { + try { + Class clazz = Class.forName(dataSource.getQueryerClass()); + Constructor constructor = clazz.getConstructor(AutoDataSource.class); + return (Queryer) constructor.newInstance(dataSource); + } catch (final Exception ex) { + throw new RuntimeException("create report engine queryer error", ex); + } + } + return null; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java new file mode 100644 index 0000000..17d2e5d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @ClassName: MySqlQueryer + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class MySqlQueryer extends AbstractQueryer implements Queryer { + + public MySqlQueryer(AutoDataSource dataSource) { + super(dataSource); + } + + @Override + protected String preprocessSqlText(String sqlText) { + sqlText = StringUtils.stripEnd(sqlText.trim(), ";"); + Pattern pattern = Pattern.compile("limit.*?$", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(sqlText); + if (matcher.find()) { + sqlText = matcher.replaceFirst(""); + } + return sqlText + " limit 1"; + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java new file mode 100644 index 0000000..ca8d41d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: OracleQueryer + * @Description: Oracle数据库查询器类。 + * 在使用该查询器时,请先参考:http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html + * 获取与相应版本的Oracle jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class OracleQueryer extends AbstractQueryer implements Queryer { + + public OracleQueryer(AutoDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java new file mode 100644 index 0000000..01cd744 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: PostgresqlQueryer + * @Description: Postgresql数据库查询器类。 + * 在使用该查询器时,请先参考:https://jdbc.postgresql.org/download.html + * 获取与相应版本的Postgresql jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class PostgresqlQueryer extends AbstractQueryer implements Queryer { + public PostgresqlQueryer(AutoDataSource dataSource) { + super(dataSource); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java new file mode 100644 index 0000000..cf18bde --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: SQLiteQueryer + * @Description: SQLite3数据库查询器类。 + * 在使用该查询器时,请先参考:https://bitbucket.org/xerial/sqlite-jdbc + * 获取jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class SQLiteQueryer extends AbstractQueryer implements Queryer { + + public SQLiteQueryer(AutoDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java new file mode 100644 index 0000000..d91fa48 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: SqlServerQueryer + * @Description: MS SQLServer 数据库查询器类。 + * 在使用该查询器时,请先参考:https://msdn.microsoft.com/library/mt484311.aspx + * 获取sqlserver jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class SqlServerQueryer extends AbstractQueryer implements Queryer { + + public SqlServerQueryer(AutoDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/util/JdbcUtils.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/util/JdbcUtils.java new file mode 100644 index 0000000..045ec06 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/sql/util/JdbcUtils.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.util; + +import com.skyeye.sql.dbpool.DataSourcePoolFactory; +import com.skyeye.sql.entity.AutoDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @ClassName: JdbcUtils + * @Description: Jdbc工具类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class JdbcUtils { + private static Logger logger = LoggerFactory.getLogger(JdbcUtils.class); + private static Map dataSourceMap = new ConcurrentHashMap<>(100); + + public static DataSource getDataSource(AutoDataSource rptDs) { + // 用数据源用户名,密码,jdbcUrl做为key + String key = String.format("%s|%s|%s", rptDs.getUser(), rptDs.getPassword(), rptDs.getJdbcUrl()) + .toLowerCase(); + DataSource dataSource = dataSourceMap.get(key); + if (dataSource == null) { + dataSource = DataSourcePoolFactory.create(rptDs.getDbPoolClass()).wrap(rptDs); + dataSourceMap.put(key, dataSource); + } + return dataSource; + } + + public static void releaseJdbcResource(Connection conn, Statement stmt, ResultSet rs) { + try { + if (stmt != null) { + stmt.close(); + } + if (rs != null) { + rs.close(); + } + if (conn != null) { + conn.close(); + } + } catch (final SQLException ex) { + logger.error("数据库资源释放异常", ex); + throw new RuntimeException("数据库资源释放异常", ex); + } + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoStepTypeEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoStepTypeEnum.java new file mode 100644 index 0000000..6af06d2 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoStepTypeEnum.java @@ -0,0 +1,41 @@ +package com.skyeye.usercase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + + +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + + +/** + * @ClassName: AutoProjectState + * @Description: 项目状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoStepTypeEnum implements SkyeyeEnumClass { + + STEP(1, "步骤", true, true), + CASE(2, "用例", true, false), + SCRIPT(3, "脚本", true, false), + TIMER(4, "定时器", true, false), + DATABASE(5, "数据库", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoValueFromTypeEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoValueFromTypeEnum.java new file mode 100644 index 0000000..46a481e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/classenum/AutoValueFromTypeEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoProjectState + * @Description: 项目状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoValueFromTypeEnum implements SkyeyeEnumClass { + + CUSTOMIZE(1, "自定义", true, true), + EXPRESSION(2, "表达式", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/controller/AutoCaseController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/controller/AutoCaseController.java new file mode 100644 index 0000000..5de17b8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/controller/AutoCaseController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.usercase.entity.AutoCase; +import com.skyeye.usercase.entity.AutoUserCaseQueryDo; +import com.skyeye.usercase.service.AutoCaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoCaseController + * @Description: 用例管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/16 20:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用例管理", tags = "用例管理", modelName = "用例管理") +public class AutoCaseController { + + @Autowired + private AutoCaseService autoCaseService; + + /** + * 获取case列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoCaseList", value = "获取用例列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoUserCaseQueryDo.class) + @RequestMapping("/post/AutoCaseController/queryAutoCaseList") + public void queryAutoCaseList(InputObject inputObject, OutputObject outputObject) { + autoCaseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑case + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoCase", value = "新增/编辑管理列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoCase.class) + @RequestMapping("/post/AutoCaseController/writeAutoCase") + public void writeAutoCase(InputObject inputObject, OutputObject outputObject) { + autoCaseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除case信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoCaseById", value = "根据ID删除用例信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoCaseController/deleteAutoCaseById") + public void deleteAutoCaseById(InputObject inputObject, OutputObject outputObject) { + autoCaseService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询case信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoCaseById", value = "查询管理列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoCaseController/queryAutoCaseById") + public void queryAutoCaseById(InputObject inputObject, OutputObject outputObject) { + autoCaseService.selectById(inputObject, outputObject); + } + + /** + * 根据id执行用例 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "executeCase", value = "根据id执行用例", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoCaseController/executeCase") + public void executeCase(InputObject inputObject, OutputObject outputObject) { + autoCaseService.executeCase(inputObject, outputObject); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoCaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoCaseDao.java new file mode 100644 index 0000000..53ef26d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoCaseDao.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoCase; +import com.skyeye.usercase.entity.AutoUserCaseQueryDo; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoCaseDao + * @Description: 用例数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoCaseDao extends SkyeyeBaseMapper { + List> queryAutoCaseList(AutoUserCaseQueryDo pageInfo); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepApiDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepApiDao.java new file mode 100644 index 0000000..c04fd5d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepApiDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepApi; +/** + * @ClassName: AutoStepApiDao + * @Description: 用例步骤关联的api数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepApiDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepAssertDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepAssertDao.java new file mode 100644 index 0000000..c2e9e78 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepAssertDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepAssert; +/** + * @ClassName: AutoStepAssertDao + * @Description: 用例步骤关联的断言数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ + +public interface AutoStepAssertDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepCaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepCaseDao.java new file mode 100644 index 0000000..fc89fce --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepCaseDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepCase; +/** + * @ClassName: AutoStepCaseDao + * @Description: 用例步骤关联的用例数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepCaseDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDao.java new file mode 100644 index 0000000..9b77757 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStep; +/** + * @ClassName: AutoStepDao + * @Description: 用例步骤数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseDao.java new file mode 100644 index 0000000..6041ca0 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepDatabase; +/** + * @ClassName: AutoStepDatabaseDao + * @Description: 用例步骤关联的数据库数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepDatabaseDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseValueDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseValueDao.java new file mode 100644 index 0000000..879818e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepDatabaseValueDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepDatabaseValue; +/** + * @ClassName: AutoStepDatabaseValueDao + * @Description: 用例步骤关联的数据库取值数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepDatabaseValueDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepInputDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepInputDao.java new file mode 100644 index 0000000..6672513 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/dao/AutoStepInputDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.usercase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.usercase.entity.AutoStepInput; +/** + * @ClassName: AutoStepInputDao + * @Description: 用例步骤前置条件数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepInputDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoCase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoCase.java new file mode 100644 index 0000000..10be6f1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoCase.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AutoCase + * @Description: 用例实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField(value = {"objectId", "name"}) +@RedisCacheField(name = "auto:case", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "auto_case") +@ApiModel(value = "用例实体类") +public class AutoCase extends BaseGeneralInfo { + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField("module_id") + @ApiModelProperty(value = "模块id", required = "required") + private String moduleId; + + @TableField(value = "result_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "结果的key", required = "required") + private String resultKey; + + @TableField(exist = false) + @ApiModelProperty(value = "步骤信息", required = "required,json") + private List stepList; + + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStep.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStep.java new file mode 100644 index 0000000..fa19392 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStep.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AutoStep + * @Description: 用例步骤实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step") +@ApiModel(value = "用例步骤实体类") +public class AutoStep extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("result_key") + @ApiModelProperty(value = "结果的key", required = "required") + private String resultKey; + + @TableField("order_by") + @ApiModelProperty(value = "顺序", required = "required") + private Integer orderBy; + + @TableField("type") + @ApiModelProperty(value = "步骤类型,参考#AutoStepTypeEnum", required = "required") + private Integer type; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; + + @TableField(exist = false) + @ApiModelProperty(value = "API", required = "json") + private AutoStepApi stepApi; + + @TableField(exist = false) + @ApiModelProperty(value = "断言", required = "json") + private List stepAssertList; + + @TableField(exist = false) + @ApiModelProperty(value = "用例", required = "json") + private AutoStepCase stepCase; + + @TableField(exist = false) + @ApiModelProperty(value = "数据库", required = "json") + private AutoStepDatabase stepDatabase; + + @TableField(exist = false) + @ApiModelProperty(value = "前置条件", required = "json") + private List stepInputList; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepApi.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepApi.java new file mode 100644 index 0000000..e51d4d9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepApi.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; +/** + * @ClassName: AutoStepApi + * @Description: 用例步骤关联的api实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.api.entity.AutoApi; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +@Data +@TableName(value = "auto_step_api") +@ApiModel(value = "用例步骤关联的api实体类") +public class AutoStepApi extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_id") + @Property(value = "步骤id") + private String stepId; + + @TableField("api_id") + @ApiModelProperty(value = "接口id", required = "required") + private String apiId; + + @TableField(exist = false) + @Property("接口信息") + private AutoApi apiMation; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepAssert.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepAssert.java new file mode 100644 index 0000000..7ad8b7b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepAssert.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoStepAssert + * @Description: 用例步骤关联的断言实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step_assert") +@ApiModel(value = "用例步骤关联的断言实体类") +public class AutoStepAssert extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_id") + @Property(value = "步骤id") + private String stepId; + + @TableField("`key`") + @ApiModelProperty(value = "断言的取值参数", required = "required") + private String key; + + @TableField("operator") + @ApiModelProperty(value = "操作符", required = "required") + private String operator; + + @TableField("value_from") + @ApiModelProperty(value = "值的数据来源,参考#AutoValueFromTypeEnum", required = "required") + private Integer valueFrom; + + @TableField("value") + @ApiModelProperty(value = "断言对比得值") + private String value; + + @TableField("order_by") + @ApiModelProperty(value = "排序", required = "required") + private Integer orderBy; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepCase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepCase.java new file mode 100644 index 0000000..50eaca8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepCase.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoStepCase + * @Description: 用例步骤关联的用例实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step_case") +@ApiModel(value = "用例步骤关联的用例实体类") +public class AutoStepCase extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_id") + @Property(value = "步骤id") + private String stepId; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; + + @TableField("link_case_id") + @ApiModelProperty(value = "所属用例id", required = "required") + private String linkCaseId; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabase.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabase.java new file mode 100644 index 0000000..6aad6c9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabase.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.database.entity.AutoDataBase; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: AutoStepDatabase + * @Description: 用例步骤关联的数据库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step_database") +@ApiModel(value = "用例步骤关联的数据库实体类") +public class AutoStepDatabase extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_id") + @Property(value = "步骤id") + private String stepId; + + @TableField("database_id") + @ApiModelProperty(value = "数据库id", required = "required") + private String databaseId; + + @TableField(exist = false) + @Property("数据库信息") + private AutoDataBase databaseMation; + + @TableField("sql_content") + @ApiModelProperty(value = "sql脚本", required = "required") + private String sqlContent; + + @TableField(exist = false) + @ApiModelProperty(value = "数据库取值", required = "json") + private List stepDatabaseValueList; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabaseValue.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabaseValue.java new file mode 100644 index 0000000..92b41e5 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepDatabaseValue.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoStepDatabaseValue + * @Description: 用例步骤关联的数据库取值实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step_database_value") +@ApiModel(value = "用例步骤关联的数据库取值实体类") +public class AutoStepDatabaseValue extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_database_id") + @ApiModelProperty(value = "用例步骤-关联的数据库id") + private String stepDatabaseId; + + @TableField("`key`") + @ApiModelProperty(value = "取值的别名", required = "required") + private String key; + + @TableField("value") + @ApiModelProperty(value = "取值的方式", required = "required") + private String value; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepInput.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepInput.java new file mode 100644 index 0000000..69cfa1e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoStepInput.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AutoStepInput + * @Description: 用例步骤前置条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "auto_step_input") +@ApiModel(value = "用例步骤前置条件实体类") +public class AutoStepInput extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("step_id") + @Property(value = "步骤id") + private String stepId; + + @TableField("`key`") + @ApiModelProperty(value = "键", required = "required") + private String key; + + @TableField("value_from") + @ApiModelProperty(value = "值的数据来源", required = "required") + private Integer valueFrom; + + @TableField("value") + @ApiModelProperty(value = "值") + private String value; + + @TableField("case_id") + @Property(value = "所属用例") + private String caseId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoUserCaseQueryDo.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoUserCaseQueryDo.java new file mode 100644 index 0000000..bea6a1d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/entity/AutoUserCaseQueryDo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: AutoUserCaseQueryDo + * @Description: 用例列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("用例列表查询条件实体类") +public class AutoUserCaseQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "模块id") + private String moduleId; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoCaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoCaseService.java new file mode 100644 index 0000000..3b98c53 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoCaseService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.history.entity.AutoHistoryCase; +import com.skyeye.usercase.entity.AutoCase; + +/** + * @ClassName: AutoCaseService + * @Description: 用例管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoCaseService extends SkyeyeBusinessService { + + void executeCase(InputObject inputObject, OutputObject outputObject); + + void executeCase(String id, Boolean recordData); + + Object executeCase(AutoCase autoCase, Boolean recordData); + + Object updateHistoryCase(AutoCase autoCase, Boolean recordData, AutoHistoryCase autoHistoryCase); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepApiService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepApiService.java new file mode 100644 index 0000000..4be366b --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepApiService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.usercase.entity.AutoStep; +import com.skyeye.usercase.entity.AutoStepApi; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepApiService + * @Description: 用例步骤关联的api管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepApiService extends SkyeyeBusinessService { + + void saveList(String objectId, List autoStepApiList); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); + + void executeStepApi(AutoStep autoStep, Map result, Map inputParams, AutoHistoryStep autoHistoryStep); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepAssertService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepAssertService.java new file mode 100644 index 0000000..3603372 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepAssertService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.usercase.entity.AutoStepAssert; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepAssertService + * @Description: 用例步骤关联的断言管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepAssertService extends SkyeyeBusinessService { + + void saveList(String objectId, List autoStepAssertList); + + void deleteByObjectId(String objectId); + + Map> selectByObjectId(String objectId); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepCaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepCaseService.java new file mode 100644 index 0000000..dbb73d1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepCaseService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.usercase.entity.AutoStepCase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepCaseService + * @Description: 用例步骤关联的用例管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepCaseService extends SkyeyeBusinessService { + void saveList(String objectId, List autoStepCaseList); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseService.java new file mode 100644 index 0000000..31a1742 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.usercase.entity.AutoStep; +import com.skyeye.usercase.entity.AutoStepDatabase; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepDatabaseService + * @Description: 用例步骤关联的数据库管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepDatabaseService extends SkyeyeBusinessService { + void saveList(String objectId, List autoStepDatabaseList); + + void deleteByObjectId(String objectId); + + Map selectByObjectId(String objectId); + + void executeAtepDatabase(AutoStep autoStep, Map result, Map inputParams, AutoHistoryStep autoHistoryStep); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseValueService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseValueService.java new file mode 100644 index 0000000..b9c70a8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepDatabaseValueService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.usercase.entity.AutoStepDatabaseValue; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepDatabaseValueService + * @Description: 用例步骤关联的数据库取值管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepDatabaseValueService extends SkyeyeBusinessService { + void saveList(String objectId, List beans); + + void deleteByObjectId(String objectId); + + Map> selectByObjectId(String objectId); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepInputService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepInputService.java new file mode 100644 index 0000000..ab8c0af --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepInputService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.usercase.entity.AutoStepInput; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoStepInputService + * @Description: 用例步骤前置条件管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepInputService extends SkyeyeBusinessService { + + void saveList(String objectId, List autoStepInputList); + + void deleteByObjectId(String objectId); + + Map> selectByObjectId(String objectId); +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepService.java new file mode 100644 index 0000000..c5fa4f9 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/AutoStepService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.usercase.entity.AutoStep; + +import java.util.List; + +/** + * @ClassName: AutoStepService + * @Description: 用例步骤管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface AutoStepService extends SkyeyeBusinessService { + + List queryAutoStepListByCaseId(String caseId); + + void deleteByObjectId(String objectId); +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoCaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoCaseServiceImpl.java new file mode 100644 index 0000000..c23ba0a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoCaseServiceImpl.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.jayway.jsonpath.JsonPath; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.attr.classenum.AttrSymbols; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import com.skyeye.history.classenum.AutoHistoryCaseExecuteResult; +import com.skyeye.history.entity.AutoHistoryCase; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.history.entity.AutoHistoryStepAssert; +import com.skyeye.history.entity.AutoHistoryStepCase; +import com.skyeye.history.service.AutoHistoryCaseService; +import com.skyeye.module.service.AutoModuleService; +import com.skyeye.usercase.classenum.AutoStepTypeEnum; +import com.skyeye.usercase.classenum.AutoValueFromTypeEnum; +import com.skyeye.usercase.dao.AutoCaseDao; +import com.skyeye.usercase.entity.*; +import com.skyeye.usercase.service.AutoCaseService; +import com.skyeye.usercase.service.AutoStepApiService; +import com.skyeye.usercase.service.AutoStepDatabaseService; +import com.skyeye.usercase.service.AutoStepService; +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 javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.util.*; + +/** + * @ClassName: AutoCaseServiceImpl + * @Description: 用例管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例管理", groupName = "用例管理") +public class AutoCaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoCaseService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private AutoStepService autoStepService; + + @Autowired + private AutoStepApiService autoStepApiService; + + @Autowired + private AutoStepDatabaseService autoStepDatabaseService; + + @Autowired + private AutoHistoryCaseService autoHistoryCaseService; + + @Autowired + private AutoModuleService autoModuleService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + AutoUserCaseQueryDo pageInfo = inputObject.getParams(AutoUserCaseQueryDo.class); + List> beans = skyeyeBaseMapper.queryAutoCaseList(pageInfo); + autoModuleService.setMationForMap(beans, "moduleId", "moduleMation"); + return beans; + } + + @Override + public void writePostpose(AutoCase autoCase, String userId) { + List autoStepList = autoCase.getStepList(); + autoStepList.forEach(autoStep -> { + autoStep.setCaseId(autoCase.getId()); + }); + autoStepService.deleteByObjectId(autoCase.getId()); + autoStepService.createEntity(autoCase.getStepList(), userId); + } + + @Override + public AutoCase getDataFromDb(String id) { + AutoCase autoCase = super.getDataFromDb(id); + autoCase.setStepList(autoStepService.queryAutoStepListByCaseId(id)); + return autoCase; + } + + @Override + public void deletePostpose(String objectId) { + autoStepService.deleteByObjectId(objectId); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void executeCase(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + executeCase(id, true); + } + + @Override + public void executeCase(String id, Boolean recordData) { + AutoCase autoCase = selectById(id); + executeCase(autoCase, recordData); + } + + @Override + public Object executeCase(AutoCase autoCase, Boolean recordData) { + if (autoHistoryCaseService.checkUserCaseRuning(autoCase.getId())) { + throw new CustomException("存在执行中的用例,请稍后执行"); + } + AutoHistoryCase autoHistoryCase = new AutoHistoryCase(); + if (recordData) { + // 需要记录执行历史信息 + autoHistoryCase.setName(autoCase.getName()); + autoHistoryCase.setModuleId(autoCase.getModuleId()); + autoHistoryCase.setResultKey(autoCase.getResultKey()); + autoHistoryCase.setCaseId(autoCase.getId()); + autoHistoryCaseService.createEntity(autoHistoryCase, StrUtil.EMPTY); + } + if (!recordData) { + // 执行子用例是需要返回 + return updateHistoryCase(autoCase, recordData, autoHistoryCase); + } else { + // 发送消息 + Map userCaseMsg = new HashMap<>(); + userCaseMsg.put("autoHistoryCaseStr", JSONUtil.toJsonStr(autoHistoryCase)); + userCaseMsg.put("autoCaseStr", JSONUtil.toJsonStr(autoCase)); + userCaseMsg.put("type", MqConstants.JobMateMationJobType.USERCASE_EXECUTE_SERVICE.getJobType()); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(userCaseMsg)); + jobMateMation.setUserId(autoCase.getCreateId()); + iJobMateMationService.sendMQProducer(jobMateMation); + } + return null; + } + + @Override + public Object updateHistoryCase(AutoCase autoCase, Boolean recordData, AutoHistoryCase autoHistoryCase) { + Integer executeResult = AutoHistoryCaseExecuteResult.EXECUTION_SUCCESSFUL.getKey(); + // 用例执行步骤 + List autoHistoryStepList = new ArrayList<>(); + Object object = null; + try { + // 结果集对象 + Map result = new HashMap<>(); + for (AutoStep autoStep : autoCase.getStepList()) { + AutoHistoryStep autoHistoryStep = new AutoHistoryStep(); + autoHistoryStep.setName(autoStep.getName()); + autoHistoryStep.setOrderBy(autoStep.getOrderBy()); + autoHistoryStep.setResultKey(autoStep.getResultKey()); + autoHistoryStep.setType(autoStep.getType()); + autoHistoryStep.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_SUCCESSFUL.getKey()); + // 获取前置条件(入参) + Map inputParams = getInputParams(result, autoStep.getStepInputList()); + try { + // 执行 + if (autoStep.getType() == AutoStepTypeEnum.STEP.getKey()) { + autoStepApiService.executeStepApi(autoStep, result, inputParams, autoHistoryStep); + } else if (autoStep.getType() == AutoStepTypeEnum.CASE.getKey()) { + if (ObjectUtil.isEmpty(autoStep.getStepCase()) || StrUtil.isEmpty(autoStep.getStepCase().getCaseId())) { + throw new CustomException("未绑定用例"); + } + AutoCase childAutoCase = selectById(autoStep.getStepCase().getCaseId()); + Object aCase = executeCase(childAutoCase, false); + result.put(autoStep.getResultKey(), aCase); + controctCaseMation(autoHistoryStep, result, autoStep); + } else if (autoStep.getType() == AutoStepTypeEnum.SCRIPT.getKey()) { + + } else if (autoStep.getType() == AutoStepTypeEnum.TIMER.getKey()) { + + } else if (autoStep.getType() == AutoStepTypeEnum.DATABASE.getKey()) { + autoStepDatabaseService.executeAtepDatabase(autoStep, result, inputParams, autoHistoryStep); + } + } catch (Exception ex) { + autoHistoryStep.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey()); + logger.warn("execute step:{} is Failed,Msg is: ", autoStep.getId(), ex); + } + autoHistoryStepList.add(autoHistoryStep); + if (autoHistoryStep.getExecuteResult() == AutoHistoryCaseExecuteResult.EXECUTION_SUCCESSFUL.getKey()) { + // 如果前面的执行成功,则执行断言 + List autoHistoryStepAssertList = new ArrayList<>(); + Boolean executeAssertResult = executeAssert(autoStep.getStepAssertList(), autoHistoryStepAssertList, result); + autoHistoryStep.setAutoHistoryStepAssertList(autoHistoryStepAssertList); + if (!executeAssertResult) { + autoHistoryStep.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey()); + throw new CustomException("断言执行失败"); + } + } else { + throw new CustomException("执行失败"); + } + if (!recordData) { + // 执行子用例是需要返回 + object = result.get(autoStep.getResultKey()); + } + } + } catch (Exception ee) { + executeResult = AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey(); + logger.warn("execute userCase:{} is Failed,Msg is: ", autoCase.getId(), ee); + } finally { + if (recordData) { + // 修改执行历史信息 + autoHistoryCase.setStepList(autoHistoryStepList); + autoHistoryCaseService.updateEntity(autoHistoryCase, StrUtil.EMPTY); + autoHistoryCaseService.finishAutoCaseHistoryById(autoHistoryCase.getId(), executeResult); + } + } + return object; + } + + private void controctCaseMation(AutoHistoryStep autoHistoryStep, Map result, AutoStep autoStep) { + AutoHistoryStepCase autoHistoryStepCase = new AutoHistoryStepCase(); + autoHistoryStepCase.setExecuteCaseId(autoStep.getStepCase().getLinkCaseId()); + autoHistoryStepCase.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_SUCCESSFUL.getKey()); + autoHistoryStepCase.setInputValue(""); + autoHistoryStepCase.setOutputValue(String.valueOf(result.get(autoStep.getResultKey()))); + autoHistoryStep.setAutoHistoryStepCase(autoHistoryStepCase); + } + + private Map getInputParams(Map result, List stepInputList) { + Map inputParams = new HashMap<>(); + if (CollectionUtil.isEmpty(stepInputList)) { + return inputParams; + } + + Map hasValParams = new HashMap<>(); + String resultStr = JSONUtil.toJsonStr(result); + stepInputList.forEach(autoStepAssert -> { + if (autoStepAssert.getValueFrom() == AutoValueFromTypeEnum.EXPRESSION.getKey()) { + String value = JsonPath.read(resultStr, String.format(Locale.ROOT, "$.%s", autoStepAssert.getValue())); + hasValParams.put(autoStepAssert.getValue(), value); + } + }); + + stepInputList.forEach(stepInput -> { + if (stepInput.getValueFrom() == AutoValueFromTypeEnum.CUSTOMIZE.getKey()) { + inputParams.put(stepInput.getKey(), stepInput.getValue()); + } else if (stepInput.getValueFrom() == AutoValueFromTypeEnum.EXPRESSION.getKey()) { + inputParams.put(stepInput.getKey(), String.valueOf(hasValParams.get(stepInput.getValue()))); + } + }); + return inputParams; + } + + private Boolean executeAssert(List stepAssertList, List autoHistoryStepAssertList, Map result) throws ScriptException { + if (CollectionUtil.isEmpty(stepAssertList)) { + return true; + } + + // 获取需要通过表达式获取的值对象 + Map hasValParams = new HashMap<>(); + String resultStr = JSONUtil.toJsonStr(result); + stepAssertList.forEach(autoStepAssert -> { + Object value = JsonPath.read(resultStr, String.format(Locale.ROOT, "$.%s", autoStepAssert.getKey())); + hasValParams.put(autoStepAssert.getKey(), value); + if (autoStepAssert.getValueFrom() == AutoValueFromTypeEnum.EXPRESSION.getKey()) { + value = JsonPath.read(resultStr, String.format(Locale.ROOT, "$.%s", autoStepAssert.getValue())); + hasValParams.put(autoStepAssert.getValue(), value); + } + }); + + for (AutoStepAssert autoStepAssert : stepAssertList) { + AutoHistoryStepAssert autoHistoryStepAssert = new AutoHistoryStepAssert(); + autoHistoryStepAssert.setKey(autoStepAssert.getKey()); + autoHistoryStepAssert.setOperator(autoStepAssert.getOperator()); + autoHistoryStepAssert.setValueFrom(autoStepAssert.getValueFrom()); + if (autoStepAssert.getValueFrom() == AutoValueFromTypeEnum.CUSTOMIZE.getKey()) { + autoHistoryStepAssert.setValue(autoStepAssert.getValue()); + } else if (autoStepAssert.getValueFrom() == AutoValueFromTypeEnum.EXPRESSION.getKey()) { + autoHistoryStepAssert.setValue(String.valueOf(hasValParams.get(autoStepAssert.getValue()))); + } + + autoHistoryStepAssert.setRealValue(String.valueOf(hasValParams.get(autoStepAssert.getKey()))); + autoHistoryStepAssert.setOrderBy(autoStepAssert.getOrderBy()); + + String regx = String.format(Locale.ROOT, "'%s' %s '%s'", autoHistoryStepAssert.getRealValue(), AttrSymbols.getSymbols(autoStepAssert.getOperator()), autoHistoryStepAssert.getValue()); + + // 创建一个ScriptEngineManager实例 + ScriptEngineManager manager = new ScriptEngineManager(); + // 获取JavaScript引擎 + ScriptEngine engine = manager.getEngineByName("JavaScript"); + Boolean approvalResult = (Boolean) engine.eval(regx); + if (approvalResult) { + autoHistoryStepAssert.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_SUCCESSFUL.getKey()); + } else { + autoHistoryStepAssert.setExecuteResult(AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey()); + } + autoHistoryStepAssertList.add(autoHistoryStepAssert); + if (autoHistoryStepAssert.getExecuteResult() == AutoHistoryCaseExecuteResult.EXECUTION_FAILED.getKey()) { + return false; + } + } + return true; + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepApiServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepApiServiceImpl.java new file mode 100644 index 0000000..7dcb140 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepApiServiceImpl.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.api.entity.AutoApi; +import com.skyeye.api.service.AutoApiService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.history.entity.AutoHistoryStepApi; +import com.skyeye.usercase.dao.AutoStepApiDao; +import com.skyeye.usercase.entity.AutoStep; +import com.skyeye.usercase.entity.AutoStepApi; +import com.skyeye.usercase.service.AutoStepApiService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepApiServiceImpl + * @Description: 用例步骤关联的api管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤关联的api管理", groupName = "用例步骤关联的api管理", manageShow = false) +public class AutoStepApiServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepApiService { + + @Autowired + private AutoApiService autoApiService; + + @Override + public void saveList(String objectId, List autoStepApiList) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(autoStepApiList)) { + for (AutoStepApi apis : autoStepApiList) { + apis.setCaseId(objectId); + } + createEntity(autoStepApiList, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepApi::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepApi::getCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(AutoStepApi::getStepId, Function.identity(), (v1, v2) -> v1)); + } + + @Override + public void executeStepApi(AutoStep autoStep, Map result, Map inputParams, AutoHistoryStep autoHistoryStep) { + if (ObjectUtil.isEmpty(autoStep.getStepApi()) || StrUtil.isEmpty(autoStep.getStepApi().getId()) + || StrUtil.isEmpty(autoStep.getStepApi().getApiId())) { + throw new CustomException("不存在该API或者未绑定API"); + } + AutoApi autoApi = autoApiService.selectById(autoStep.getStepApi().getApiId()); + autoApi.setInputExample(JSONUtil.toJsonStr(inputParams)); + AutoHistoryStepApi autoHistoryStepApi = new AutoHistoryStepApi(); + Map apiResult = autoApiService.apiTest(autoApi, autoHistoryStepApi); + autoHistoryStep.setAutoHistoryStepApi(autoHistoryStepApi); + result.put(autoStep.getResultKey(), apiResult); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepAssertServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepAssertServiceImpl.java new file mode 100644 index 0000000..7af96a4 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepAssertServiceImpl.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.usercase.dao.AutoStepAssertDao; +import com.skyeye.usercase.entity.AutoStepAssert; +import com.skyeye.usercase.service.AutoStepAssertService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepAssertServiceImpl + * @Description: 用例步骤关联的断言管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤关联的断言管理", groupName = "用例步骤关联的断言管理", manageShow = false) +public class AutoStepAssertServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepAssertService { + + @Override + public void saveList(String objectId, List autoStepAssertList) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(autoStepAssertList)) { + for (AutoStepAssert asserts : autoStepAssertList) { + asserts.setCaseId(objectId); + } + createEntity(autoStepAssertList, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepAssert::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map> selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepAssert::getCaseId), objectId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(AutoStepAssert::getOrderBy)); + List list = list(queryWrapper); + return list.stream().collect(Collectors.groupingBy(AutoStepAssert::getStepId)); + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepCaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepCaseServiceImpl.java new file mode 100644 index 0000000..b7881ba --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepCaseServiceImpl.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.usercase.dao.AutoStepCaseDao; +import com.skyeye.usercase.entity.AutoStepCase; +import com.skyeye.usercase.service.AutoStepCaseService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepCaseServiceImpl + * @Description: 用例步骤关联的用例管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤关联的用例管理", groupName = "用例步骤关联的用例管理", manageShow = false) +public class AutoStepCaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepCaseService { + + @Override + public void saveList(String objectId, List autoStepCaseList) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(autoStepCaseList)) { + for (AutoStepCase cases : autoStepCaseList) { + cases.setCaseId(objectId); + } + createEntity(autoStepCaseList, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepCase::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepCase::getCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(AutoStepCase::getStepId, Function.identity(), (v1, v2) -> v1)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseServiceImpl.java new file mode 100644 index 0000000..33fb422 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseServiceImpl.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.database.service.AutoDataBaseService; +import com.skyeye.exception.CustomException; +import com.skyeye.history.entity.AutoHistoryStep; +import com.skyeye.history.entity.AutoHistoryStepDatabase; +import com.skyeye.sql.entity.AutoDataSource; +import com.skyeye.sql.entity.ReportMetaDataRow; +import com.skyeye.sql.query.factory.QueryerFactory; +import com.skyeye.usercase.dao.AutoStepDatabaseDao; +import com.skyeye.usercase.entity.AutoStep; +import com.skyeye.usercase.entity.AutoStepDatabase; +import com.skyeye.usercase.entity.AutoStepDatabaseValue; +import com.skyeye.usercase.service.AutoStepDatabaseService; +import com.skyeye.usercase.service.AutoStepDatabaseValueService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepDatabaseServiceImpl + * @Description: 用例步骤关联的数据库管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤关联的数据库管理", groupName = "用例步骤关联的数据库管理", manageShow = false) +public class AutoStepDatabaseServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepDatabaseService { + + @Autowired + private AutoStepDatabaseValueService autoStepDatabaseValueService; + + @Autowired + private AutoDataBaseService autoDataBaseService; + + @Override + public void writePostpose(List autoStepDatabaseList, String userId) { + List autoStepDatabaseValueList = new ArrayList<>(); + autoStepDatabaseList.forEach(autoStepDatabase -> { + autoStepDatabase.getStepDatabaseValueList().forEach(autoStepDatabaseValue -> { + autoStepDatabaseValue.setStepDatabaseId(autoStepDatabase.getId()); + }); + autoStepDatabaseValueList.addAll(autoStepDatabase.getStepDatabaseValueList()); + }); + autoStepDatabaseValueService.saveList(autoStepDatabaseList.stream().findFirst().orElse(new AutoStepDatabase()).getCaseId(), autoStepDatabaseValueList); + } + + @Override + public void saveList(String objectId, List autoStepDatabaseList) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(autoStepDatabaseList)) { + for (AutoStepDatabase databases : autoStepDatabaseList) { + databases.setCaseId(objectId); + } + createEntity(autoStepDatabaseList, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + autoStepDatabaseValueService.deleteByObjectId(objectId); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepDatabase::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepDatabase::getCaseId), objectId); + List list = list(queryWrapper); + Map> databaseValue = autoStepDatabaseValueService.selectByObjectId(objectId); + list.forEach(autoStepDatabase -> { + autoStepDatabase.setStepDatabaseValueList(databaseValue.get(autoStepDatabase.getId())); + }); + return list.stream().collect(Collectors.toMap(AutoStepDatabase::getStepId, Function.identity(), (v1, v2) -> v1)); + } + + @Override + public void executeAtepDatabase(AutoStep autoStep, Map result, Map inputParams, AutoHistoryStep autoHistoryStep) { + if (ObjectUtil.isEmpty(autoStep.getStepDatabase()) || StrUtil.isEmpty(autoStep.getStepDatabase().getId()) + || StrUtil.isEmpty(autoStep.getStepDatabase().getDatabaseId())) { + throw new CustomException("不存在该数据库或者未绑定数据库"); + } + if (StrUtil.isEmpty(autoStep.getStepDatabase().getSqlContent())) { + throw new CustomException("脚本不能为空"); + } + // 替换占位符的字段 + String sqlContent = autoStep.getStepDatabase().getSqlContent(); + for (Map.Entry entry : inputParams.entrySet()) { + sqlContent = sqlContent.replaceAll(String.format("#\\{%s\\}", entry.getKey()), String.format("'%s'", entry.getValue())); + } + + AutoDataSource autoDataSource = autoDataBaseService.getReportDataSource(autoStep.getStepDatabase().getDatabaseId()); + // 数据库执行信息 + AutoHistoryStepDatabase autoHistoryStepDatabase = new AutoHistoryStepDatabase(); + autoHistoryStepDatabase.setDatabaseId(autoStep.getStepDatabase().getId()); + autoHistoryStepDatabase.setSqlContent(sqlContent); + try { + List metaDataRows = QueryerFactory.create(autoDataSource).getMetaDataRows(sqlContent); + // 获取数据库查询出来的接口值,并进行数据组装 + List> selResult = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(autoStep.getStepDatabase().getStepDatabaseValueList())) { + for (ReportMetaDataRow metaDataRow : metaDataRows) { + Map sel = new HashMap<>(); + autoStep.getStepDatabase().getStepDatabaseValueList().forEach(autoStepDatabaseValue -> { + sel.put(autoStepDatabaseValue.getKey(), metaDataRow.getCell(autoStepDatabaseValue.getValue()).getValue()); + }); + selResult.add(sel); + } + } + result.put(autoStep.getResultKey(), selResult); + + autoHistoryStepDatabase.setOutputValue(JSONUtil.toJsonStr(selResult)); + } catch (Exception ex) { + autoHistoryStepDatabase.setOutputValue(ex.toString()); + throw new CustomException("executeAtepDatabase ", ex); + } finally { + autoHistoryStep.setAutoHistoryStepDatabase(autoHistoryStepDatabase); + } + } + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseValueServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseValueServiceImpl.java new file mode 100644 index 0000000..b77108d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepDatabaseValueServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.usercase.dao.AutoStepDatabaseValueDao; +import com.skyeye.usercase.entity.AutoStepDatabaseValue; +import com.skyeye.usercase.service.AutoStepDatabaseValueService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepDatabaseValueServiceImpl + * @Description: 用例步骤关联的数据库取值管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤关联的数据库取值管理", groupName = "用例步骤关联的数据库取值管理", manageShow = false) +public class AutoStepDatabaseValueServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepDatabaseValueService { + + @Override + public void saveList(String objectId, List beans) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(beans)) { + for (AutoStepDatabaseValue databaseValues : beans) { + databaseValues.setCaseId(objectId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepDatabaseValue::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map> selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepDatabaseValue::getCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.groupingBy(AutoStepDatabaseValue::getStepDatabaseId)); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepInputServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepInputServiceImpl.java new file mode 100644 index 0000000..d5fefa2 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepInputServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.usercase.dao.AutoStepInputDao; +import com.skyeye.usercase.entity.AutoStepInput; +import com.skyeye.usercase.service.AutoStepInputService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepInputServiceImpl + * @Description: 用例步骤前置条件管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤前置条件管理", groupName = "用例步骤前置条件管理", manageShow = false) +public class AutoStepInputServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepInputService { + + @Override + public void saveList(String objectId, List autoStepInputList) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(autoStepInputList)) { + for (AutoStepInput inputs : autoStepInputList) { + inputs.setCaseId(objectId); + } + createEntity(autoStepInputList, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepInput::getCaseId), objectId); + remove(queryWrapper); + } + + @Override + public Map> selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStepInput::getCaseId), objectId); + List list = list(queryWrapper); + return list.stream().collect(Collectors.groupingBy(AutoStepInput::getStepId)); + } +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepServiceImpl.java new file mode 100644 index 0000000..cea1537 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/usercase/service/impl/AutoStepServiceImpl.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.usercase.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.usercase.classenum.AutoStepTypeEnum; +import com.skyeye.usercase.dao.AutoStepDao; +import com.skyeye.usercase.entity.*; +import com.skyeye.usercase.service.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoStepServiceImpl + * @Description: 用例步骤管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "用例步骤管理", groupName = "用例步骤管理", manageShow = false) +public class AutoStepServiceImpl extends SkyeyeBusinessServiceImpl implements AutoStepService { + + @Autowired + private AutoStepInputService autoStepInputService; + + @Autowired + private AutoStepAssertService autoStepAssertService; + + @Autowired + private AutoStepApiService autoStepApiService; + + @Autowired + private AutoStepCaseService autoStepCaseService; + + @Autowired + private AutoStepDatabaseService autoStepDatabaseService; + + @Override + public void writePostpose(List autoStepList, String userId) { + Map> listMap = autoStepList.stream() + .collect(Collectors.groupingBy(AutoStep::getType)); + List autoStepInputList = new ArrayList<>(); + List autoStepAssertList = new ArrayList<>(); + List autoStepApiList = new ArrayList<>(); + List autoStepCaseList = new ArrayList<>(); + List autoStepDatabaseList = new ArrayList<>(); + listMap.forEach((key, value) -> { + if (key.equals(AutoStepTypeEnum.STEP.getKey())) { + value.forEach(step -> { + step.getStepApi().setStepId(step.getId()); + autoStepApiList.add(step.getStepApi()); + }); + } else if (key.equals(AutoStepTypeEnum.CASE.getKey())) { + value.forEach(step -> { + step.getStepCase().setStepId(step.getId()); + autoStepCaseList.add(step.getStepCase()); + }); + } else if (key.equals(AutoStepTypeEnum.DATABASE.getKey())) { + value.forEach(step -> { + step.getStepDatabase().setStepId(step.getId()); + autoStepDatabaseList.add(step.getStepDatabase()); + }); + } + value.forEach(bean -> { + // 前置条件 + bean.getStepInputList().forEach(item -> { + item.setStepId(bean.getId()); + }); + autoStepInputList.addAll(bean.getStepInputList()); + // 断言 + bean.getStepAssertList().forEach(item -> { + item.setStepId(bean.getId()); + }); + autoStepAssertList.addAll(bean.getStepAssertList()); + }); + }); + autoStepApiService.saveList(autoStepList.stream().findFirst().orElse(new AutoStep()).getCaseId(), autoStepApiList); + autoStepCaseService.saveList(autoStepList.stream().findFirst().orElse(new AutoStep()).getCaseId(), autoStepCaseList); + autoStepDatabaseService.saveList(autoStepList.stream().findFirst().orElse(new AutoStep()).getCaseId(), autoStepDatabaseList); + autoStepInputService.saveList(autoStepList.stream().findFirst().orElse(new AutoStep()).getCaseId(), autoStepInputList); + autoStepAssertService.saveList(autoStepList.stream().findFirst().orElse(new AutoStep()).getCaseId(), autoStepAssertList); + } + + @Override + public List queryAutoStepListByCaseId(String caseId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStep::getCaseId), caseId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(AutoStep::getOrderBy)); + List autoStepList = list(queryWrapper); + + Map autoStepApiMap = autoStepApiService.selectByObjectId(caseId); + Map autoStepCaseMap = autoStepCaseService.selectByObjectId(caseId); + Map autoStepDatabaseMap = autoStepDatabaseService.selectByObjectId(caseId); + Map> autoStepMap = autoStepInputService.selectByObjectId(caseId); + Map> autoStepAssertMap = autoStepAssertService.selectByObjectId(caseId); + autoStepList.forEach(autoStep -> { + if (autoStep.getType().equals(AutoStepTypeEnum.STEP.getKey())) { + autoStep.setStepApi(autoStepApiMap.get(autoStep.getId())); + } else if (autoStep.getType().equals(AutoStepTypeEnum.CASE.getKey())) { + autoStep.setStepCase(autoStepCaseMap.get(autoStep.getId())); + } else if (autoStep.getType().equals(AutoStepTypeEnum.DATABASE.getKey())) { + autoStep.setStepDatabase(autoStepDatabaseMap.get(autoStep.getId())); + } + // 前置条件 + autoStep.setStepInputList(autoStepMap.get(autoStep.getId())); + // 断言 + autoStep.setStepAssertList(autoStepAssertMap.get(autoStep.getId())); + }); + return autoStepList; + } + + @Override + public void deleteByObjectId(String objectId) { + autoStepCaseService.deleteByObjectId(objectId); + autoStepDatabaseService.deleteByObjectId(objectId); + autoStepInputService.deleteByObjectId(objectId); + autoStepApiService.deleteByObjectId(objectId); + autoStepAssertService.deleteByObjectId(objectId); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoStep::getCaseId), objectId); + remove(queryWrapper); + } +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableAuthEnum.java new file mode 100644 index 0000000..2626c69 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableAuthEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoVariableAuthEnum + * @Description: 变量权限枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoVariableAuthEnum implements SkyeyeEnumClass { + + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableType.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableType.java new file mode 100644 index 0000000..dfc17e8 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/classenum/AutoVariableType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoVariableType + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/3/29 16:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoVariableType implements SkyeyeEnumClass { + + GLOBAL_VARIABLE("globalVariable", "全局变量", true, false), + RANDOM_VARIABLE("randomVariable", "随机变量", true, false), + GLOBAL_HEADER("globalHeader", "全局Header", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/controller/AutoVariableController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/controller/AutoVariableController.java new file mode 100644 index 0000000..ec0ab47 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/controller/AutoVariableController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.variable.entity.AutoVariable; +import com.skyeye.variable.service.AutoVariableService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoVariableController + * @Description: 变量管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "变量管理", tags = "变量管理", modelName = "变量管理") +public class AutoVariableController { + + @Autowired + private AutoVariableService autoVariableService; + + /** + * 获取变量信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoVariableList", value = "获取变量信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoVariableController/queryAutoVariableList") + public void queryAutoVariableList(InputObject inputObject, OutputObject outputObject) { + autoVariableService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改变量信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoVariable", value = "新增/编辑变量信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoVariable.class) + @RequestMapping("/post/AutoVariableController/writeAutoVariable") + public void writeAutoVariable(InputObject inputObject, OutputObject outputObject) { + autoVariableService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除变量信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoVariableById", value = "根据ID删除变量信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoVariableController/deleteAutoVariableById") + public void deleteAutoVariableById(InputObject inputObject, OutputObject outputObject) { + autoVariableService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询变量信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoVariableById", value = "根据id查询变量信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoVariableController/queryAutoVariableById") + public void queryAutoVariableById(InputObject inputObject, OutputObject outputObject) { + autoVariableService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/dao/AutoVariableDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/dao/AutoVariableDao.java new file mode 100644 index 0000000..a8e6758 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/dao/AutoVariableDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.variable.entity.AutoVariable; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoVariableDao + * @Description: 变量管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoVariableDao extends SkyeyeBaseMapper { + List> queryAutoVariableList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/entity/AutoVariable.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/entity/AutoVariable.java new file mode 100644 index 0000000..863ddc6 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/entity/AutoVariable.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: AutoVariable + * @Description: 变量管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "auto:variable", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName("auto_variable") +@ApiModel(value = "变量实体类") +public class AutoVariable extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`key`") + @ApiModelProperty(value = "键", required = "required") + private String key; + + @TableField("`value`") + @ApiModelProperty(value = "值", required = "required") + private String value; + + @TableField("type") + @ApiModelProperty(value = "类型,参考#AutoVariableType", required = "required") + private String type; + + @TableField("remark") + @ApiModelProperty("备注") + private String remark; + + @TableField("environment_id") + @ApiModelProperty(value = "环境id", required = "required") + private String environmentId; +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/AutoVariableService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/AutoVariableService.java new file mode 100644 index 0000000..f2a586a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/AutoVariableService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.variable.entity.AutoVariable; + +import java.util.Map; + +/** + * @ClassName: AutoVariableService + * @Description: 变量管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoVariableService extends SkyeyeTeamAuthService { + + Map getAutoVariable(String type, String environmentId); + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/impl/AutoVariableServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/impl/AutoVariableServiceImpl.java new file mode 100644 index 0000000..64840ee --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/variable/service/impl/AutoVariableServiceImpl.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.variable.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.environment.service.AutoEnvironmentService; +import com.skyeye.variable.classenum.AutoVariableAuthEnum; +import com.skyeye.variable.dao.AutoVariableDao; +import com.skyeye.variable.entity.AutoVariable; +import com.skyeye.variable.service.AutoVariableService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AutoVariableServiceImpl + * @Description: 变量管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "变量管理", groupName = "变量管理", teamAuth = true) +public class AutoVariableServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoVariableService { + + @Autowired + private AutoEnvironmentService autoEnvironmentService; + + @Override + public Class getAuthEnumClass() { + return AutoVariableAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoVariableAuthEnum.ADD.getKey(), AutoVariableAuthEnum.EDIT.getKey(), AutoVariableAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoVariableList(commonPageInfo); + autoEnvironmentService.setMationForMap(beans, "environmentId", "environmentMation"); + return beans; + } + + @Override + public Map getAutoVariable(String type, String environmentId) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoVariable::getType), type); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoVariable::getEnvironmentId), environmentId); + List list = list(queryWrapper); + Map stringMap = list.stream().collect(Collectors.toMap(AutoVariable::getKey, AutoVariable::getValue)); + return stringMap; + } +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionAuthEnum.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionAuthEnum.java new file mode 100644 index 0000000..c31e369 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoVersionAuthEnum + * @Description: 版本权限枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 8:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoVersionAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionState.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionState.java new file mode 100644 index 0000000..5a03002 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/classenum/AutoVersionState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AutoVersionState + * @Description: 版本状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/20 19:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AutoVersionState implements SkyeyeEnumClass { + + GET("get", "新建", true, true), + PROGRESS("progress", "进行中", true, false), + END("end", "结束", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/controller/AutoVersionController.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/controller/AutoVersionController.java new file mode 100644 index 0000000..717de9f --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/controller/AutoVersionController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.version.entity.AutoVersion; +import com.skyeye.version.service.AutoVersionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AutoVersionController + * @Description: 版本管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "版本管理", tags = "版本管理", modelName = "版本管理") +public class AutoVersionController { + + @Autowired + private AutoVersionService autoVersionService; + + /** + * 获取版本信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoVersionList", value = "获取版本信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AutoVersionController/queryAutoVersionList") + public void queryAutoVersionList(InputObject inputObject, OutputObject outputObject) { + autoVersionService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改版本信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAutoVersion", value = "新增/编辑版本信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AutoVersion.class) + @RequestMapping("/post/AutoVersionController/writeAutoVersion") + public void writeAutoVersion(InputObject inputObject, OutputObject outputObject) { + autoVersionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除版本信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAutoVersionById", value = "根据ID删除版本信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AutoVersionController/deleteAutoVersionById") + public void deleteAutoVersionById(InputObject inputObject, OutputObject outputObject) { + autoVersionService.deleteById(inputObject, outputObject); + } + + /** + * 根据项目id获取版本信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAutoVersionByObjectId", value = "根据项目id获取版本信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "项目id", required = "required")}) + @RequestMapping("/post/AutoVersionController/queryAutoVersionByObjectId") + public void queryAutoVersionByObjectId(InputObject inputObject, OutputObject outputObject) { + autoVersionService.queryAutoVersionByObjectId(inputObject, outputObject); + } +} + diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/dao/AutoVersionDao.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/dao/AutoVersionDao.java new file mode 100644 index 0000000..b37362a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/dao/AutoVersionDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.version.entity.AutoVersion; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoVersionDao + * @Description: 版本管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoVersionDao extends SkyeyeBaseMapper { + + List> queryAutoVersionList(CommonPageInfo commonPageInfo); +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/entity/AutoVersion.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/entity/AutoVersion.java new file mode 100644 index 0000000..c4b56dd --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/entity/AutoVersion.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: AutoVersion + * @Description: 版本管理实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField("no") +@RedisCacheField(name = "auto:version", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName("auto_version") +@ApiModel(value = "版本实体类") +public class AutoVersion extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField("no") + @ApiModelProperty(value = "版本号", required = "required") + private String no; + + @TableField("state") + @ApiModelProperty(value = "状态,参考#AutoVersionState", required = "required") + private String state; + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/AutoVersionService.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/AutoVersionService.java new file mode 100644 index 0000000..a8d4970 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/AutoVersionService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.demand.entity.AutoDemand; +import com.skyeye.version.entity.AutoVersion; + +/** + * @ClassName: AutoVersionService + * @Description: 版本管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AutoVersionService extends SkyeyeTeamAuthService { + + void queryAutoVersionByObjectId(InputObject inputObject, OutputObject outputObject); + + +} diff --git a/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/impl/AutoVersionServiceImpl.java b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/impl/AutoVersionServiceImpl.java new file mode 100644 index 0000000..110ad8a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/java/com/skyeye/version/service/impl/AutoVersionServiceImpl.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.version.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.version.classenum.AutoVersionAuthEnum; +import com.skyeye.version.classenum.AutoVersionState; +import com.skyeye.version.dao.AutoVersionDao; +import com.skyeye.version.entity.AutoVersion; +import com.skyeye.version.service.AutoVersionService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AutoVersionServiceImpl + * @Description: 版本管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/26 9:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "版本管理", groupName = "版本管理", teamAuth = true) +public class AutoVersionServiceImpl extends SkyeyeTeamAuthServiceImpl implements AutoVersionService { + + @Override + public Class getAuthEnumClass() { + return AutoVersionAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(AutoVersionAuthEnum.ADD.getKey(), AutoVersionAuthEnum.EDIT.getKey(), AutoVersionAuthEnum.DELETE.getKey()); + } + + @Override + public void validatorEntity(AutoVersion entity) { + if (StrUtil.equals(entity.getState(), AutoVersionState.PROGRESS.getKey())) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoVersion::getObjectId), entity.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoVersion::getState), entity.getState()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + AutoVersion autoVersion = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(autoVersion)) { + throw new CustomException("该项目存在进行中的版本,请先结束该版本。"); + } + } + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAutoVersionList(commonPageInfo); + return beans; + } + + @Override + public void queryAutoVersionByObjectId(InputObject inputObject, OutputObject outputObject) { + String objectId = inputObject.getParams().get("objectId").toString(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AutoVersion::getObjectId), objectId); + List result = list(queryWrapper); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/api/AutoApiMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/api/AutoApiMapper.xml new file mode 100644 index 0000000..797d8df --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/api/AutoApiMapper.xml @@ -0,0 +1,45 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/bug/AutoBugMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/bug/AutoBugMapper.xml new file mode 100644 index 0000000..b889e8d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/bug/AutoBugMapper.xml @@ -0,0 +1,80 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/database/AutoDataBaseMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/database/AutoDataBaseMapper.xml new file mode 100644 index 0000000..a512f1d --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/database/AutoDataBaseMapper.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/demand/AutoDemandMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/demand/AutoDemandMapper.xml new file mode 100644 index 0000000..4bce282 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/demand/AutoDemandMapper.xml @@ -0,0 +1,47 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/environment/AutoEnvironmentMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/environment/AutoEnvironmentMapper.xml new file mode 100644 index 0000000..92b65eb --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/environment/AutoEnvironmentMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/history/AutoHistoryCaseMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/history/AutoHistoryCaseMapper.xml new file mode 100644 index 0000000..cb365ad --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/history/AutoHistoryCaseMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/microservice/AutoMicroserviceMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/microservice/AutoMicroserviceMapper.xml new file mode 100644 index 0000000..6590c3a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/microservice/AutoMicroserviceMapper.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/module/AutoModuleMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/module/AutoModuleMapper.xml new file mode 100644 index 0000000..1b2e9b1 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/module/AutoModuleMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/product/AutoProductMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/product/AutoProductMapper.xml new file mode 100644 index 0000000..cdef884 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/product/AutoProductMapper.xml @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/project/AutoProjectMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/project/AutoProjectMapper.xml new file mode 100644 index 0000000..615ac4e --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/project/AutoProjectMapper.xml @@ -0,0 +1,41 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/server/AutoServerMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/server/AutoServerMapper.xml new file mode 100644 index 0000000..67b8159 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/server/AutoServerMapper.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/usercase/AutoCaseMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/usercase/AutoCaseMapper.xml new file mode 100644 index 0000000..a4a132a --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/usercase/AutoCaseMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/variable/AutoVariableMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/variable/AutoVariableMapper.xml new file mode 100644 index 0000000..eb0d725 --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/variable/AutoVariableMapper.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-pro/src/main/resources/mapper/version/AutoVersionMapper.xml b/skyeye-auto/auto-pro/src/main/resources/mapper/version/AutoVersionMapper.xml new file mode 100644 index 0000000..158acfe --- /dev/null +++ b/skyeye-auto/auto-pro/src/main/resources/mapper/version/AutoVersionMapper.xml @@ -0,0 +1,37 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-web/.gitignore b/skyeye-auto/auto-web/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-auto/auto-web/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-auto/auto-web/pom.xml b/skyeye-auto/auto-web/pom.xml new file mode 100644 index 0000000..dec939d --- /dev/null +++ b/skyeye-auto/auto-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-auto + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + auto-web + + + 8 + 8 + UTF-8 + + + + + + com.skyeye + auto-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-auto/auto-web/src/main/java/com/SkyAutoApplication.java b/skyeye-auto/auto-web/src/main/java/com/SkyAutoApplication.java new file mode 100644 index 0000000..c374196 --- /dev/null +++ b/skyeye-auto/auto-web/src/main/java/com/SkyAutoApplication.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class SkyAutoApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyAutoApplication.class, args); + } + +} diff --git a/skyeye-auto/auto-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-auto/auto-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..561a9bf --- /dev/null +++ b/skyeye-auto/auto-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-auto/auto-web/src/main/resources/banner.txt b/skyeye-auto/auto-web/src/main/resources/banner.txt new file mode 100644 index 0000000..e1b7251 --- /dev/null +++ b/skyeye-auto/auto-web/src/main/resources/banner.txt @@ -0,0 +1,34 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 +*/ \ No newline at end of file diff --git a/skyeye-auto/auto-web/src/main/resources/bootstrap.yml b/skyeye-auto/auto-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..dc29c3a --- /dev/null +++ b/skyeye-auto/auto-web/src/main/resources/bootstrap.yml @@ -0,0 +1,47 @@ +server: + port: 8111 + +spring: + application: + name: skyeye-auto-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:9000 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:9000 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: true # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + +topic: + # 用例执行的topic + usercase-execute-service: USERCASE_EXECUTE_SERVICE \ No newline at end of file diff --git a/skyeye-auto/auto-web/src/main/resources/jvm调优参数配置 b/skyeye-auto/auto-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-auto/auto-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-auto/auto-web/src/main/resources/log4j.properties b/skyeye-auto/auto-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-auto/auto-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-auto/pom.xml b/skyeye-auto/pom.xml new file mode 100644 index 0000000..93fd90d --- /dev/null +++ b/skyeye-auto/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-auto + pom + 1.0-SNAPSHOT + + + auto-web + auto-pro + auto-common + + + \ No newline at end of file diff --git a/skyeye-boss/.gitignore b/skyeye-boss/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-boss/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-boss/boss-common/.gitignore b/skyeye-boss/boss-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-boss/boss-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-boss/boss-common/pom.xml b/skyeye-boss/boss-common/pom.xml new file mode 100644 index 0000000..7f56771 --- /dev/null +++ b/skyeye-boss/boss-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-boss + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + boss-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-common/src/main/java/com/skyeye/constants/BossConstants.java b/skyeye-boss/boss-common/src/main/java/com/skyeye/constants/BossConstants.java new file mode 100644 index 0000000..3e224c6 --- /dev/null +++ b/skyeye-boss/boss-common/src/main/java/com/skyeye/constants/BossConstants.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constants; + +import com.skyeye.common.util.SpringUtils; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.jedis.JedisClientService; + +/** + * @ClassName: BossConstants + * @Description: 招聘模块常用类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/16 19:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class BossConstants { + + public static void deleteCache(String userId) { + JedisClientService jedisClient = SpringUtils.getBean(JedisClientService.class); + IAuthUserService iAuthUserService = SpringUtils.getBean(IAuthUserService.class); + String cacheKey = iAuthUserService.queryCacheKeyById(userId); + // 删除缓存中的用户信息 + jedisClient.del(cacheKey); + } + +} diff --git a/skyeye-boss/boss-pro/.gitignore b/skyeye-boss/boss-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-boss/boss-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-boss/boss-pro/pom.xml b/skyeye-boss/boss-pro/pom.xml new file mode 100644 index 0000000..1ce3d80 --- /dev/null +++ b/skyeye-boss/boss-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-boss + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + boss-pro + + + + + com.skyeye + boss-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/classenum/ArrangementState.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/classenum/ArrangementState.java new file mode 100644 index 0000000..5c5cbdd --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/classenum/ArrangementState.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: BossInterviewArrangementState + * @Description: 面试安排状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ArrangementState implements SkyeyeEnumClass { + + SUBMIT(2, "已提交待安排面试人员", true, false), + TO_BE_INTERVIEWED(3, "已提交待面试", true, false), + INTERVIEWED_PASS(4, "面试通过", true, false), + INTERVIEWED_FAIL(5, "面试不通过", true, false), + COMPLATE(6, "已完成入职", true, false), + COMPLATE_REFUSE(7, "已完成拒绝入职", true, false), + NULLIFY(8, "作废(HR操作)", true, false), + INDUCTION_OTHER(9, "入职其他部门", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/controller/ArrangementController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/controller/ArrangementController.java new file mode 100644 index 0000000..3a6a1fc --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/controller/ArrangementController.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.arrangement.entity.Arrangement; +import com.skyeye.arrangement.service.ArrangementService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * @ClassName: ArrangementController + * @Description: 面试安排控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/14 11:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "面试安排", tags = "面试安排", modelName = "面试安排") +public class ArrangementController { + + @Autowired + private ArrangementService arrangementService; + + /** + * 获取我录入的面试安排信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyEntryBossInterviewArrangementList", value = "获取我录入的面试安排信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArrangementController/queryMyEntryBossInterviewArrangementList") + public void queryMyEntryBossInterviewArrangementList(InputObject inputObject, OutputObject outputObject) { + arrangementService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑面试安排 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeArrangement", value = "新增/编辑面试安排", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Arrangement.class) + @RequestMapping("/post/ArrangementController/writeArrangement") + public void writeArrangement(InputObject inputObject, OutputObject outputObject) { + arrangementService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询面试安排信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryArrangementById", value = "根据id查询面试安排信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArrangementController/queryArrangementById") + public void queryArrangementById(InputObject inputObject, OutputObject outputObject) { + arrangementService.selectById(inputObject, outputObject); + } + + /** + * 作废面试安排信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "nullifyArrangement", value = "作废面试安排信息", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ArrangementController/nullifyArrangement") + public void nullifyArrangement(InputObject inputObject, OutputObject outputObject) { + arrangementService.nullifyArrangement(inputObject, outputObject); + } + + /** + * 获取我录入的人员需求关联的面试者信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyEntryBossPersonRequireAboutArrangementList", value = "获取我录入的人员需求关联的面试者信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArrangementController/queryMyEntryBossPersonRequireAboutArrangementList") + public void queryMyEntryBossPersonRequireAboutArrangementList(InputObject inputObject, OutputObject outputObject) { + arrangementService.queryMyEntryBossPersonRequireAboutArrangementList(inputObject, outputObject); + } + + /** + * 部门经理面试安排信息设置面试官 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setBossInterviewer", value = "部门经理面试安排信息设置面试官", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "interviewer", name = "interviewer", value = "面试官id", required = "required")}) + @RequestMapping("/post/ArrangementController/setBossInterviewer") + public void setBossInterviewer(InputObject inputObject, OutputObject outputObject) { + arrangementService.setBossInterviewer(inputObject, outputObject); + } + + /** + * 获取面试官为当前登录用户的面试者信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryArrangementInterviewerIsMyList", value = "获取面试官为当前登录用户的面试者信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ArrangementController/queryArrangementInterviewerIsMyList") + public void queryArrangementInterviewerIsMyList(InputObject inputObject, OutputObject outputObject) { + arrangementService.queryArrangementInterviewerIsMyList(inputObject, outputObject); + } + + /** + * 设置面试结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setBossInterviewResult", value = "设置面试结果", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "4.面试通过 5.面试不通过", required = "required,num"), + @ApiImplicitParam(id = "evaluation", name = "evaluation", value = "面试评价", required = "required")}) + @RequestMapping("/post/ArrangementController/setBossInterviewResult") + public void setBossInterviewResult(InputObject inputObject, OutputObject outputObject) { + arrangementService.setBossInterviewResult(inputObject, outputObject); + } + + /** + * 设置入职结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setInductionResult", value = "设置入职结果", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "6.同意入职 7.拒绝入职", required = "required,num"), + @ApiImplicitParam(id = "reason", name = "reason", value = "拒绝入职的原因,当拒绝入职时必填"), + @ApiImplicitParam(id = "workTime", name = "workTime", value = "参加工作时间,格式为yyyy-MM-dd。同意入职后必填"), + @ApiImplicitParam(id = "entryTime", name = "entryTime", value = "入职时间,格式为yyyy-MM-dd。同意入职后必填"), + @ApiImplicitParam(id = "userIdCard", name = "userIdCard", value = "身份证。同意入职后必填"), + @ApiImplicitParam(id = "inductionState", name = "inductionState", value = "员工入职状态"), + @ApiImplicitParam(id = "trialTime", name = "trialTime", value = "如果有试用期,则为试用期到期时间。当state=4时,该字段必填")}) + @RequestMapping("/post/ArrangementController/setInductionResult") + public void setInductionResult(InputObject inputObject, OutputObject outputObject) { + arrangementService.setInductionResult(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/dao/ArrangementDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/dao/ArrangementDao.java new file mode 100644 index 0000000..beafc61 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/dao/ArrangementDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.dao; + +import com.skyeye.arrangement.entity.Arrangement; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArrangementDao + * @Description: 面试安排数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/14 11:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArrangementDao extends SkyeyeBaseMapper { + + List> queryBossInterviewArrangementList(CommonPageInfo commonPageInfo); + + List> queryMyEntryBossPersonRequireAboutArrangementList(CommonPageInfo pageInfo); + + List> queryArrangementInterviewerIsMyList(CommonPageInfo queryDo); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/entity/Arrangement.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/entity/Arrangement.java new file mode 100644 index 0000000..12aff6e --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/entity/Arrangement.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.arrangement.classenum.ArrangementState; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.interviewee.entity.Interviewee; +import com.skyeye.personrequire.entity.PersonRequire; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Arrangement + * @Description: 面试安排表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/14 16:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "boss_interview_arrangement") +@RedisCacheField(name = "boss:arrangement", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel("面试安排表实体类") +public class Arrangement extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property("单据编号") + private String oddNumber; + + @TableField(value = "interview_id") + @ApiModelProperty(value = "面试者id", required = "required") + private String interviewId; + + @TableField(exist = false) + @Property(value = "面试者信息") + private Interviewee interviewMation; + + @TableField(value = "interview_time") + @ApiModelProperty(value = "面试时间", required = "required") + private String interviewTime; + + @TableField(value = "person_require_id") + @ApiModelProperty(value = "人员需求申请id", required = "required") + private String personRequireId; + + @TableField(exist = false) + @Property(value = "人员需求申请信息") + private PersonRequire personRequireMation; + + @TableField(value = "interviewer") + @ApiModelProperty(value = "面试官id,需要由人员需求的申请人进行人员安排") + private String interviewer; + + @TableField(exist = false) + @Property(value = "面试官信息") + private Map interviewerMation; + + @TableField(value = "job_score_id") + @ApiModelProperty(value = "面试通过后,需要面试官进行定级,如果该岗位没有职级,可以不做定级") + private String jobScoreId; + + @TableField(exist = false) + @Property(value = "岗位定级信息") + private Map jobScoreMation; + + @TableField(value = "state") + @ApiModelProperty(value = "状态,参考#ArrangementState") + private Integer state; + + @TableField(value = "evaluation") + @ApiModelProperty(value = "面试评价") + private String evaluation; + + @TableField(value = "reason") + @ApiModelProperty(value = "拒绝入职的原因") + private String reason; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/ArrangementService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/ArrangementService.java new file mode 100644 index 0000000..e5e2627 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/ArrangementService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.service; + +import com.skyeye.arrangement.entity.Arrangement; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ArrangementService + * @Description: 面试安排服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/14 11:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ArrangementService extends SkyeyeBusinessService { + + void nullifyArrangement(InputObject inputObject, OutputObject outputObject); + + void queryMyEntryBossPersonRequireAboutArrangementList(InputObject inputObject, OutputObject outputObject); + + void setBossInterviewer(InputObject inputObject, OutputObject outputObject); + + void queryArrangementInterviewerIsMyList(InputObject inputObject, OutputObject outputObject); + + void setBossInterviewResult(InputObject inputObject, OutputObject outputObject); + + void setInductionResult(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/impl/ArrangementServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/impl/ArrangementServiceImpl.java new file mode 100644 index 0000000..38f34df --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/arrangement/service/impl/ArrangementServiceImpl.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.arrangement.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.arrangement.classenum.ArrangementState; +import com.skyeye.arrangement.dao.ArrangementDao; +import com.skyeye.arrangement.entity.Arrangement; +import com.skyeye.arrangement.service.ArrangementService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.centerrest.entity.staff.UserStaffRest; +import com.skyeye.centerrest.user.SysEveUserStaffService; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.interviewee.classenum.IntervieweeStatusEnum; +import com.skyeye.interviewee.service.IntervieweeService; +import com.skyeye.organization.service.ICompanyJobScoreService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.personrequire.service.PersonRequireService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ArrangementServiceImpl + * @Description: 面试安排服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/14 11:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "面试安排", groupName = "面试安排") +public class ArrangementServiceImpl extends SkyeyeBusinessServiceImpl implements ArrangementService { + + @Autowired + private IntervieweeService intervieweeService; + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobScoreService iCompanyJobScoreService; + + @Autowired + private PersonRequireService personRequireService; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + // 我录入的 + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryBossInterviewArrangementList(commonPageInfo); + iAuthUserService.setMationForMap(beans, "interviewer", "interviewerMation"); + intervieweeService.setMationForMap(beans, "interviewId", "interviewMation"); + personRequireService.setMationForMap(beans, "personRequireId", "personRequireMation"); + iCompanyJobScoreService.setMationForMap(beans, "jobScoreId", "jobScoreMation"); + return beans; + } + + @Override + public void createPrepose(Arrangement entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(this.getClass().getName(), business); + entity.setOddNumber(oddNumber); + entity.setState(ArrangementState.SUBMIT.getKey()); + } + + @Override + public void validatorEntity(Arrangement entity) { + // 校验基础信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Arrangement::getInterviewId), entity.getInterviewId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Arrangement::getPersonRequireId), entity.getPersonRequireId()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Arrangement checkArrangement = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkArrangement)) { + throw new CustomException("该面试者已安排面试."); + } + } + + @Override + public void writePostpose(Arrangement entity, String userId) { + super.writePostpose(entity, userId); + // 修改面试者信息为面试中 + intervieweeService.editStateById(entity.getInterviewId(), IntervieweeStatusEnum.INTERVIEW_STATUS.getKey()); + } + + @Override + public Arrangement selectById(String id) { + Arrangement arrangement = super.selectById(id); + // 岗位定级信息 + if (StrUtil.isNotEmpty(arrangement.getJobScoreId())) { + Map jobScore = iCompanyJobScoreService.queryDataMationById(arrangement.getJobScoreId()); + arrangement.setJobScoreMation(jobScore); + } + // 面试者信息 + arrangement.setInterviewMation(intervieweeService.selectById(arrangement.getInterviewId())); + // 面试官信息 + if (StrUtil.isNotEmpty(arrangement.getInterviewer())) { + Map interviewer = iAuthUserService.queryDataMationById(arrangement.getInterviewer()); + arrangement.setInterviewerMation(interviewer); + } + // 人员需求信息 + personRequireService.setDataMation(arrangement, Arrangement::getPersonRequireId); + return arrangement; + } + + private void editStateById(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getState), state); + update(updateWrapper); + } + + /** + * 作废面试安排信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void nullifyArrangement(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Arrangement arrangement = selectById(id); + if (ObjectUtil.isEmpty(arrangement)) { + outputObject.setreturnMessage("this data is non-exits."); + return; + } + Integer state = arrangement.getState(); + if (state.equals(ArrangementState.SUBMIT.getKey()) + || state.equals(ArrangementState.TO_BE_INTERVIEWED.getKey())) { + // 2,3状态可以作废 + editStateById(id, ArrangementState.NULLIFY.getKey()); + refreshCache(id); + } + } + + /** + * 获取我录入的人员需求关联的面试者信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyEntryBossPersonRequireAboutArrangementList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + pageInfo.setStateList(getArrangementState()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryMyEntryBossPersonRequireAboutArrangementList(pageInfo); + iAuthUserService.setMationForMap(beans, "interviewer", "interviewerMation"); + intervieweeService.setMationForMap(beans, "interviewId", "interviewMation"); + personRequireService.setMationForMap(beans, "personRequireId", "personRequireMation"); + iCompanyJobScoreService.setMationForMap(beans, "jobScoreId", "jobScoreMation"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + private List getArrangementState() { + List arrangementState = new ArrayList<>(); + arrangementState.add(String.valueOf(ArrangementState.SUBMIT.getKey())); + arrangementState.add(String.valueOf(ArrangementState.TO_BE_INTERVIEWED.getKey())); + arrangementState.add(String.valueOf(ArrangementState.INTERVIEWED_PASS.getKey())); + arrangementState.add(String.valueOf(ArrangementState.INTERVIEWED_FAIL.getKey())); + arrangementState.add(String.valueOf(ArrangementState.COMPLATE.getKey())); + arrangementState.add(String.valueOf(ArrangementState.COMPLATE_REFUSE.getKey())); + arrangementState.add(String.valueOf(ArrangementState.INDUCTION_OTHER.getKey())); + return arrangementState; + } + + /** + * 部门经理面试安排信息设置面试官 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void setBossInterviewer(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + String interviewer = map.get("interviewer").toString(); + Arrangement arrangement = selectById(id); + if (ObjectUtil.isEmpty(arrangement)) { + outputObject.setreturnMessage("this data is non-exits."); + return; + } + Integer state = arrangement.getState(); + if (state.equals(ArrangementState.SUBMIT.getKey()) + || state.equals(ArrangementState.TO_BE_INTERVIEWED.getKey())) { + // 2,3状态可以设置面试官 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getInterviewer), interviewer); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getState), ArrangementState.TO_BE_INTERVIEWED.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 获取面试官为当前登录用户的面试者信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryArrangementInterviewerIsMyList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo queryDo = inputObject.getParams(CommonPageInfo.class); + queryDo.setCreateId(inputObject.getLogParams().get("id").toString()); + queryDo.setStateList(getArrangementInterviewerIsMyState()); + + Page pages = PageHelper.startPage(queryDo.getPage(), queryDo.getLimit()); + List> beans = skyeyeBaseMapper.queryArrangementInterviewerIsMyList(queryDo); + iAuthUserService.setMationForMap(beans, "interviewer", "interviewerMation"); + intervieweeService.setMationForMap(beans, "interviewId", "interviewMation"); + personRequireService.setMationForMap(beans, "personRequireId", "personRequireMation"); + iCompanyJobScoreService.setMationForMap(beans, "jobScoreId", "jobScoreMation"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + private List getArrangementInterviewerIsMyState() { + List arrangementState = new ArrayList<>(); + arrangementState.add(String.valueOf(ArrangementState.TO_BE_INTERVIEWED.getKey())); + arrangementState.add(String.valueOf(ArrangementState.INTERVIEWED_PASS.getKey())); + arrangementState.add(String.valueOf(ArrangementState.INTERVIEWED_FAIL.getKey())); + arrangementState.add(String.valueOf(ArrangementState.COMPLATE.getKey())); + arrangementState.add(String.valueOf(ArrangementState.COMPLATE_REFUSE.getKey())); + return arrangementState; + } + + /** + * 设置面试结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void setBossInterviewResult(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Arrangement arrangement = selectById(id); + if (ObjectUtil.isEmpty(arrangement)) { + outputObject.setreturnMessage("this data is non-exits."); + return; + } + if (arrangement.getState().equals(ArrangementState.TO_BE_INTERVIEWED.getKey())) { + // 3状态可以设置面试结果 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getEvaluation), map.get("evaluation").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getState), map.get("state").toString()); + update(updateWrapper); + refreshCache(id); + } + } + + /** + * 设置入职结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void setInductionResult(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Integer state = Integer.parseInt(map.get("state").toString()); + String reason = map.get("reason").toString(); + Arrangement arrangement = selectById(id); + if (ObjectUtil.isEmpty(arrangement)) { + outputObject.setreturnMessage("this data is non-exits."); + return; + } + if (arrangement.getState().equals(ArrangementState.INTERVIEWED_PASS.getKey())) { + // 4状态可以设置入职结果 + if (state.equals(ArrangementState.COMPLATE.getKey())) { + // 同意入职 + // 修改该面试安排为通过 + setInductionResult(id, ArrangementState.COMPLATE.getKey(), reason); + // 修改该面试人员的其他面试为拒绝 + setOtherInductionResult(id, arrangement.getInterviewId()); + // 修改面试者状态为面试通过 + intervieweeService.editStateById(arrangement.getInterviewId(), IntervieweeStatusEnum.INTERVIEW_PASS_STATUS.getKey()); + // 修改人员需求申请单信息 + personRequireService.updatePersonRequireNum(arrangement.getPersonRequireId(), CommonNumConstants.NUM_ONE); + // 添加员工信息 + UserStaffRest sysUserStaff = getSysUserStaffMation(arrangement, map); + ExecuteFeignClient.get(() -> sysEveUserStaffService.insertNewUserStaff(sysUserStaff)); + } else { + // 拒绝入职 + if (ToolUtil.isBlank(reason)) { + outputObject.setreturnMessage("请填写拒绝入职的原因."); + return; + } + setInductionResult(id, ArrangementState.COMPLATE_REFUSE.getKey(), reason); + } + refreshCache(id); + } + } + + private void setInductionResult(String id, Integer state, String reason) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getState), state); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getReason), reason); + update(updateWrapper); + } + + private void setOtherInductionResult(String id, String interviewId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.ne(CommonConstants.ID, id); + updateWrapper.ne(MybatisPlusUtil.toColumns(Arrangement::getState), ArrangementState.NULLIFY.getKey()); + updateWrapper.eq(MybatisPlusUtil.toColumns(Arrangement::getInterviewId), interviewId); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getState), ArrangementState.INDUCTION_OTHER.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Arrangement::getReason), "已入职其他项目组"); + update(updateWrapper); + } + + private UserStaffRest getSysUserStaffMation(Arrangement arrangement, Map map) { + UserStaffRest sysUserStaff = new UserStaffRest(); + sysUserStaff.setUserName(arrangement.getInterviewMation().getName()); + sysUserStaff.setUserSex(arrangement.getInterviewMation().getSex()); + sysUserStaff.setPhone(arrangement.getInterviewMation().getPhone()); + sysUserStaff.setUserPhoto("../../assets/images/anonymousphoto.jpg"); + sysUserStaff.setUserIdCard(map.get("userIdCard").toString()); + String departmentId = arrangement.getPersonRequireMation().getRecruitDepartmentId(); + Map department = iDepmentService.queryDataMationById(departmentId); + sysUserStaff.setCompanyId(department.get("companyId").toString()); + sysUserStaff.setDepartmentId(departmentId); + sysUserStaff.setJobId(arrangement.getPersonRequireMation().getRecruitJobId()); + sysUserStaff.setWorkTime(map.get("workTime").toString()); + sysUserStaff.setEntryTime(map.get("entryTime").toString()); + if (StrUtil.isEmpty(map.get("inductionState").toString())) { + throw new CustomException("员工入职状态不能为空。"); + } + sysUserStaff.setState(Integer.parseInt(map.get("inductionState").toString())); + sysUserStaff.setTrialTime(map.get("trialTime").toString()); + sysUserStaff.setInterviewArrangementId(arrangement.getId()); + return sysUserStaff; + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffLeaveRest.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffLeaveRest.java new file mode 100644 index 0000000..51ac2e8 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffLeaveRest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.centerrest.entity.staff; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: UserStaffLeaveRest + * @Description: 员工离职实体入参 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/26 11:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("员工离职实体入参") +public class UserStaffLeaveRest implements Serializable { + + @ApiModelProperty(value = "员工id", required = "required") + private String rowId; + + @ApiModelProperty(value = "离职时间") + private String quitTime; + + @ApiModelProperty(value = "离职原因") + private String quitReason; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffRest.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffRest.java new file mode 100644 index 0000000..dbd5acb --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/entity/staff/UserStaffRest.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.centerrest.entity.staff; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: UserStaffRest + * @Description: 员工信息对象 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/19 16:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("员工信息对象") +public class UserStaffRest implements Serializable { + + @ApiModelProperty(value = "员工性别 0保密 1男 2女", required = "required,num") + private Integer userSex; + + @ApiModelProperty(value = "身份证", required = "idcard") + private String userIdCard; + + @ApiModelProperty(value = "员工姓名", required = "required") + private String userName; + + @ApiModelProperty(value = "头像", required = "required") + private String userPhoto; + + @ApiModelProperty(value = "邮箱", required = "email") + private String email; + + @ApiModelProperty(value = "QQ") + private String qq; + + @ApiModelProperty(value = "手机号", required = "phone") + private String phone; + + @ApiModelProperty(value = "家庭电话") + private String homePhone; + + @ApiModelProperty(value = "所属公司", required = "required") + private String companyId; + + @ApiModelProperty(value = "所属部门", required = "required") + private String departmentId; + + @ApiModelProperty(value = "所属职位", required = "required") + private String jobId; + + @ApiModelProperty(value = "职位定级") + private String jobScoreId; + + @ApiModelProperty(value = "个性签名") + private String userSign; + + @ApiModelProperty(value = "参加工作时间,格式为yyyy-MM-dd", required = "required") + private String workTime; + + @ApiModelProperty(value = "入职时间,格式为yyyy-MM-dd", required = "required") + private String entryTime; + + @ApiModelProperty(value = "员工考勤时间段,逗号隔开") + private String checkTimeStr; + + @ApiModelProperty(value = "员工类型 1.普通员工 2.教师", required = "required,num", defaultValue = "1") + private Integer type = 1; + + @ApiModelProperty(value = "员工在职状态", required = "required,num") + private Integer state; + + @ApiModelProperty(value = "如果有试用期,则为试用期到期时间。当state=4时,该字段必填") + private String trialTime; + + @ApiModelProperty(value = "关联的面试安排信息id") + private String interviewArrangementId; + + /** + * 如果有试用期,则为转正日期 + */ + private String becomeWorkerTime; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/user/SysEveUserStaffService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/user/SysEveUserStaffService.java new file mode 100644 index 0000000..bd43632 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/centerrest/user/SysEveUserStaffService.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.centerrest.user; + +import com.skyeye.centerrest.entity.staff.UserStaffLeaveRest; +import com.skyeye.centerrest.entity.staff.UserStaffRest; +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +/** + * @ClassName: SysEveUserStaffService + * @Description: 员工信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 14:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface SysEveUserStaffService { + + /** + * 新增员工信息 + * + * @param userStaffRest 员工信息 + * @return + */ + @PostMapping("/writeSysUserStaff") + String insertNewUserStaff(UserStaffRest userStaffRest); + + /** + * 员工离职 + * + * @param userStaffLeaveRest 员工离职信息 + * @return + */ + @PostMapping("/staff006") + String userStaffQuit(UserStaffLeaveRest userStaffLeaveRest); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/IntervieweeStatusEnum.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/IntervieweeStatusEnum.java new file mode 100644 index 0000000..a583ad3 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/IntervieweeStatusEnum.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: IntervieweeStatusEnum + * @Description: 面试者状态的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum IntervieweeStatusEnum implements SkyeyeEnumClass { + + PENDING_INTERVIEW_STATUS(0, "待面试", true, false), + INTERVIEW_STATUS(1, "面试中", true, false), + INTERVIEW_PASS_STATUS(2, "面试通过", true, false), + INTERVIEW_FAILED_STATUS(3, "待面试", true, false), + REJECTED_STATUS(4, "拒绝入职", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getIntervieweeStateName(Integer status) { + for (IntervieweeStatusEnum q : IntervieweeStatusEnum.values()) { + if (q.getKey().equals(status)) { + return q.getValue(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/UserTransferType.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/UserTransferType.java new file mode 100644 index 0000000..5375767 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/classenum/UserTransferType.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: UserTransferType + * @Description: 员工转岗类型的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserTransferType implements SkyeyeEnumClass { + + FLAT_TONE(1, "平调", true, false), + PROMOTION(2, "晋升", true, false), + DEMOTION(3, "降职", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getNameByType(Integer type) { + for (UserTransferType bean : UserTransferType.values()) { + if (type == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeController.java new file mode 100644 index 0000000..3f6e8e7 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.interviewee.entity.Interviewee; +import com.skyeye.interviewee.service.IntervieweeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IntervieweeController + * @Description: 面试者管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/27 13:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "面试者管理", tags = "面试者管理", modelName = "面试者管理") +public class IntervieweeController { + + @Autowired + private IntervieweeService intervieweeService; + + /** + * 获取面试者信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "bossInterviewee001", value = "获取面试者信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/IntervieweeController/queryBossIntervieweeList") + public void queryBossIntervieweeList(InputObject inputObject, OutputObject outputObject) { + intervieweeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑面试者信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeInterviewee", value = "新增/编辑面试者信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Interviewee.class) + @RequestMapping("/post/IntervieweeController/writeInterviewee") + public void insertBossInterviewee(InputObject inputObject, OutputObject outputObject) { + intervieweeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除面试者信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteIntervieweeById", value = "删除待面试者", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/IntervieweeController/deleteIntervieweeById") + public void deleteIntervieweeById(InputObject inputObject, OutputObject outputObject) { + intervieweeService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeFromController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeFromController.java new file mode 100644 index 0000000..ff3a610 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/controller/IntervieweeFromController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.interviewee.entity.IntervieweeFrom; +import com.skyeye.interviewee.service.IntervieweeFromService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IntervieweeFromController + * @Description: 面试者来源管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/7 13:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "面试者来源管理", tags = "面试者来源管理", modelName = "面试者管理") +public class IntervieweeFromController { + + @Autowired + private IntervieweeFromService bossIntervieweeFromService; + + /** + * 获取面试者来源信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "bossIntervieweeFrom001", value = "获取面试者来源信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BossIntervieweeFromController/queryBossIntervieweeFromList") + public void queryBossIntervieweeFromList(InputObject inputObject, OutputObject outputObject) { + bossIntervieweeFromService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑面试者来源信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBossIntervieweeFrom", value = "新增/编辑面试者来源信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = IntervieweeFrom.class) + @RequestMapping("/post/BossIntervieweeFromController/writeBossIntervieweeFrom") + public void writeBossIntervieweeFrom(InputObject inputObject, OutputObject outputObject) { + bossIntervieweeFromService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除面试者来源信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBossIntervieweeFrom", value = "删除面试者来源信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键ID", required = "required")}) + @RequestMapping("/post/BossIntervieweeFromController/deleteBossIntervieweeFrom") + public void deleteBossIntervieweeFrom(InputObject inputObject, OutputObject outputObject) { + bossIntervieweeFromService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有的面试者来源信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllBossIntervieweeFrom", value = "获取所有的面试者来源信息", method = "GET", allUse = "2") + @RequestMapping("/post/BossIntervieweeFromController/queryAllBossIntervieweeFrom") + public void queryAllBossIntervieweeFrom(InputObject inputObject, OutputObject outputObject) { + bossIntervieweeFromService.queryAllBossIntervieweeFrom(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeDao.java new file mode 100644 index 0000000..c681ab4 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.interviewee.entity.Interviewee; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IntervieweeDao + * @Description: 面试者管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/27 13:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IntervieweeDao extends SkyeyeBaseMapper { + + List> queryBossIntervieweeList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeFromDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeFromDao.java new file mode 100644 index 0000000..7bbba69 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/dao/IntervieweeFromDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.interviewee.entity.IntervieweeFrom; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IntervieweeFromDao + * @Description: 面试者来源管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/7 13:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IntervieweeFromDao extends SkyeyeBaseMapper { + + List> queryBossIntervieweeFromList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/Interviewee.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/Interviewee.java new file mode 100644 index 0000000..6fea3d4 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/Interviewee.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Interviewee + * @Description: 面试者实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/22 20:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "boss:interviewee", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "boss_interview") +@ApiModel("面试者实体类") +public class Interviewee extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "姓名", required = "required") + private String name; + + @TableField(value = "sex") + @ApiModelProperty(value = "性别,参考#SexEnum", required = "required,num") + private Integer sex; + + @TableField(value = "idcard") + @ApiModelProperty(value = "身份证号", required = "idcard") + private String idcard; + + @TableField(value = "phone") + @ApiModelProperty(value = "联系方式", required = "required,phone") + private String phone; + + @TableField(value = "from_id") + @ApiModelProperty(value = "来源id", required = "required") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源信息") + private IntervieweeFrom fromMation; + + @TableField(value = "favorite_job") + @ApiModelProperty(value = "心意岗位", required = "required") + private String favoriteJob; + + @TableField(value = "basic_resume") + @ApiModelProperty(value = "基本简历", required = "required") + private String basicResume; + + @TableField(value = "work_years") + @ApiModelProperty(value = "工作年限", required = "required") + private String workYears; + + @TableField(value = "state") + @Property(value = "状态,参考#IntervieweeStatusEnum") + private Integer state; + + @TableField(value = "charge_person_id") + @ApiModelProperty(value = "负责人id", required = "required") + private String chargePersonId; + + @TableField(exist = false) + @Property(value = "负责人信息") + private Map chargePersonMation; + + @TableField(value = "refuse_reason") + @ApiModelProperty(value = "当state=4时,需要填写该内容,拒绝入职的原因") + private String refuseReason; + + @TableField(value = "refuse_time") + @ApiModelProperty(value = "当state=4时,拒绝的日期,格式为yyyy-MM-dd") + private String refuseTime; + + @TableField(value = "last_join_department_id") + @ApiModelProperty(value = "当state=2时,最后入职的部门id") + private String lastJoinDepartmentId; + + @TableField(exist = false) + @Property(value = "最后入职的部门信息") + private Map lastJoinDepartmentMation; + + @TableField(value = "last_join_time") + @ApiModelProperty(value = "当state=2时,最后入职的日期,格式为yyyy-MM-dd") + private String lastJoinTime; + + @TableField(exist = false) + @ApiModelProperty(value = "附件简历", required = "json") + private Enclosure enclosureResume; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/IntervieweeFrom.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/IntervieweeFrom.java new file mode 100644 index 0000000..c0d8f20 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/entity/IntervieweeFrom.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: IntervieweeFrom + * @Description: 面试者来源实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/22 20:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "boss:interviewee:from", cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "boss_interviewee_from") +@ApiModel("面试者来源实体类") +public class IntervieweeFrom extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField(value = "from_url") + @ApiModelProperty(value = "来源地址") + private String fromUrl; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeFromService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeFromService.java new file mode 100644 index 0000000..4dac85b --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeFromService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.interviewee.entity.IntervieweeFrom; + +/** + * @ClassName: IntervieweeFromService + * @Description: 面试者来源管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/7 13:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IntervieweeFromService extends SkyeyeBusinessService { + + void queryAllBossIntervieweeFrom(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeService.java new file mode 100644 index 0000000..903c12e --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/IntervieweeService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.interviewee.entity.Interviewee; + +/** + * @ClassName: IntervieweeService + * @Description: 面试者管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/27 13:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IntervieweeService extends SkyeyeBusinessService { + + void editStateById(String id, Integer state); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeFromServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeFromServiceImpl.java new file mode 100644 index 0000000..a35ea10 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeFromServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.interviewee.dao.IntervieweeFromDao; +import com.skyeye.interviewee.entity.IntervieweeFrom; +import com.skyeye.interviewee.service.IntervieweeFromService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IntervieweeFromServiceImpl + * @Description: 面试者来源管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/7 13:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "面试者来源管理", groupName = "面试者管理") +public class IntervieweeFromServiceImpl extends SkyeyeBusinessServiceImpl implements IntervieweeFromService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryBossIntervieweeFromList(commonPageInfo); + return beans; + } + + /** + * 获取所有的面试者来源信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllBossIntervieweeFrom(InputObject inputObject, OutputObject outputObject) { + List intervieweeFromList = queryAllData(); + outputObject.setBeans(intervieweeFromList); + outputObject.settotal(intervieweeFromList.size()); + } +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeServiceImpl.java new file mode 100644 index 0000000..bb6c99a --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/interviewee/service/impl/IntervieweeServiceImpl.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.interviewee.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.base.handler.enclosure.EnclosureDetailsHandler; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.interviewee.classenum.IntervieweeStatusEnum; +import com.skyeye.interviewee.dao.IntervieweeDao; +import com.skyeye.interviewee.entity.Interviewee; +import com.skyeye.interviewee.service.IntervieweeFromService; +import com.skyeye.interviewee.service.IntervieweeService; +import com.skyeye.organization.service.IDepmentService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IntervieweeServiceImpl + * @Description: 面试者管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/27 13:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "面试者管理", groupName = "面试者管理") +public class IntervieweeServiceImpl extends SkyeyeBusinessServiceImpl implements IntervieweeService { + + @Autowired + private IntervieweeFromService intervieweeFromService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private EnclosureDetailsHandler enclosureDetailsHandler; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Integer type = Integer.parseInt(pageInfo.getType()); + String userId = inputObject.getLogParams().get("id").toString(); + if (type == 1) { + // 我录入的 + pageInfo.setCreateId(userId); + } else if (type == 2) { + // 我负责的 + pageInfo.setChargePersonId(userId); + } + List> beans = skyeyeBaseMapper.queryBossIntervieweeList(pageInfo); + iAuthUserService.setMationForMap(beans, "chargePersonId", "chargePersonMation"); + // 获取面试者来源信息 + intervieweeFromService.setMationForMap(beans, "fromId", "fromMation"); + // 附件 + beans.forEach(bean -> { + Interviewee interviewee = BeanUtil.toBean(bean, Interviewee.class); + enclosureDetailsHandler.executorHandler(interviewee); + bean.put("enclosureResume", interviewee.getEnclosureResume()); + }); + return beans; + } + + @Override + public void createPrepose(Interviewee entity) { + entity.setState(IntervieweeStatusEnum.PENDING_INTERVIEW_STATUS.getKey()); + } + + @Override + public void validatorEntity(Interviewee entity) { + // 根据姓名、手机号查询面试者信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Interviewee::getName), entity.getName()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Interviewee::getPhone), entity.getPhone()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Interviewee::getLastJoinTime)); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Interviewee interviewee = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(interviewee)) { + // 获取相同姓名+手机号最近的一条面试者数据 + List needCheckStates = + Arrays.asList(IntervieweeStatusEnum.PENDING_INTERVIEW_STATUS.getKey(), + IntervieweeStatusEnum.INTERVIEW_STATUS.getKey(), + IntervieweeStatusEnum.INTERVIEW_FAILED_STATUS.getKey()); + if (needCheckStates.contains(interviewee.getState())) { + throw new CustomException("同一个姓名、手机号的面试者已存在, 请重新确认面试者信息!"); + } else if (IntervieweeStatusEnum.INTERVIEW_PASS_STATUS.getKey().equals(interviewee.getState())) { + Date lastJoinTimeDate = DateUtil.getPointTime(interviewee.getLastJoinTime(), DateUtil.YYYY_MM_DD); + // 比较当前时间与最后入职的日期相差几个月 + long differMonth = cn.hutool.core.date.DateUtil.betweenMonth(lastJoinTimeDate, new Date(), true); + if (differMonth < 6) { + throw new CustomException("该面试者通过面试未没有超过半年,则不允许录入"); + } + } else if (IntervieweeStatusEnum.REJECTED_STATUS.getKey().equals(interviewee.getState())) { + Date refuseTimeDate = DateUtil.getPointTime(interviewee.getRefuseTime(), DateUtil.YYYY_MM_DD); + // 比较当前时间与最后入职的日期相差几个月 + long differMonth = cn.hutool.core.date.DateUtil.betweenMonth(refuseTimeDate, new Date(), true); + if (differMonth < 6) { + throw new CustomException("该面试者不通过面试未没有超过半年,则不允许录入"); + } + } + } + } + + @Override + public Interviewee selectById(String id) { + Interviewee interviewee = super.selectById(id); + // 设置面试者来源信息 + interviewee.setFromMation(intervieweeFromService.selectById(interviewee.getFromId())); + // 设置负责人 + interviewee.setChargePersonMation(iAuthUserService.queryDataMationById(interviewee.getChargePersonId())); + // 设置入职的部门 + iDepmentService.setDataMation(interviewee, Interviewee::getLastJoinDepartmentId); + return interviewee; + } + + @Override + public List selectByIds(String... ids) { + List intervieweeList = super.selectByIds(ids); + // 获取面试者来源信息 + intervieweeFromService.setDataMation(intervieweeList, Interviewee::getFromId); + // 设置负责人信息 + iAuthUserService.setDataMation(intervieweeList, Interviewee::getChargePersonId); + // 设置入职的部门 + iDepmentService.setDataMation(intervieweeList, Interviewee::getLastJoinDepartmentId); + return intervieweeList; + } + + @Override + protected void deletePreExecution(Interviewee entity) { + if (!IntervieweeStatusEnum.PENDING_INTERVIEW_STATUS.getKey().equals(entity.getState())) { + throw new CustomException("删除失败, 只有待面试状态的数据可删除!"); + } + } + + @Override + public void editStateById(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Interviewee::getState), state); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/controller/JobTransferController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/controller/JobTransferController.java new file mode 100644 index 0000000..c5af37c --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/controller/JobTransferController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jobtransfer.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.jobtransfer.entity.JobTransfer; +import com.skyeye.jobtransfer.service.JobTransferService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: JobTransferController + * @Description: 岗位调动申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-27 15:57:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "岗位调动申请", tags = "岗位调动申请", modelName = "岗位调动申请") +public class JobTransferController { + + @Autowired + private JobTransferService jobTransferService; + + /** + * 获取我发起的岗位调动申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBossInterviewJobTransferList", value = "获取我发起的岗位调动申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/JobTransferController/queryJobTransferList") + public void queryJobTransferList(InputObject inputObject, OutputObject outputObject) { + jobTransferService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑岗位调动申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeJobTransfer", value = "新增/编辑岗位调动申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = JobTransfer.class) + @RequestMapping("/post/JobTransferController/writeJobTransfer") + public void writeJobTransfer(InputObject inputObject, OutputObject outputObject) { + jobTransferService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 岗位调动申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitJobTransfer", value = "岗位调动申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "岗位调动申请主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "[提交审批]操作必填审批人", required = "required")}) + @RequestMapping("/post/JobTransferController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + jobTransferService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废岗位调动申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidJobTransfer", value = "作废岗位调动申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "岗位调动申请主键id", required = "required")}) + @RequestMapping("/post/JobTransferController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + jobTransferService.invalid(inputObject, outputObject); + } + + /** + * 撤销岗位调动申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeJobTransfer", value = "撤销岗位调动申请", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/JobTransferController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + jobTransferService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/dao/JobTransferDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/dao/JobTransferDao.java new file mode 100644 index 0000000..4e77bee --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/dao/JobTransferDao.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jobtransfer.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.jobtransfer.entity.JobTransfer; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobTransferDao + * @Description: 岗位调动申请数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-27 15:57:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JobTransferDao extends SkyeyeBaseMapper { + + List> queryJobTransferList(CommonPageInfo pageInfo); + + void updateBossInterviewJobMation(JobTransfer jobTransfer); +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/entity/JobTransfer.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/entity/JobTransfer.java new file mode 100644 index 0000000..65c9896 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/entity/JobTransfer.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jobtransfer.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: JobTransfer + * @Description: 岗位调动申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-27 15:57:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "boss:jobTransfer", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "boss_interview_job_transfer", autoResultMap = true) +@ApiModel("岗位调动申请实体类") +public class JobTransfer extends SkyeyeFlowable { + + @TableField(value = "transfer_type") + @ApiModelProperty(value = "调动类型,参考#UserTransferType", required = "required") + private Integer transferType; + + @TableField(value = "transfer_staff_id") + @ApiModelProperty(value = "申请人id(员工id)", required = "required") + private String transferStaffId; + + @TableField(exist = false) + @Property(value = "申请人信息") + private Map transferStaffMation; + + @TableField(value = "primary_company_id") + @ApiModelProperty(value = "原企业id") + private String primaryCompanyId; + + @TableField(exist = false) + @Property(value = "原企业信息") + private Map primaryCompanyMation; + + @TableField(value = "primary_department_id") + @ApiModelProperty(value = "原部门id") + private String primaryDepartmentId; + + @TableField(exist = false) + @Property(value = "原部门信息") + private Map primaryDepartmentMation; + + @TableField(value = "primary_job_id") + @ApiModelProperty(value = "原岗位id") + private String primaryJobId; + + @TableField(exist = false) + @Property(value = "原岗位信息") + private Map primaryJobMation; + + @TableField(value = "primary_job_score_id") + @ApiModelProperty(value = "原岗位定级id") + private String primaryJobScoreId; + + @TableField(exist = false) + @Property(value = "原岗位定级信息") + private Map primaryJobScoreMation; + + @TableField(value = "current_company_id") + @ApiModelProperty(value = "现企业id", required = "required") + private String currentCompanyId; + + @TableField(exist = false) + @Property(value = "现企业信息") + private Map currentCompanyMation; + + @TableField(value = "current_department_id") + @ApiModelProperty(value = "现部门id", required = "required") + private String currentDepartmentId; + + @TableField(exist = false) + @Property(value = "现部门信息") + private Map currentDepartmentMation; + + @TableField(value = "current_job_id") + @ApiModelProperty(value = "现岗位id", required = "required") + private String currentJobId; + + @TableField(exist = false) + @Property(value = "现岗位信息") + private Map currentJobMation; + + @TableField(value = "current_job_score_id") + @ApiModelProperty(value = "现岗位定级") + private String currentJobScoreId; + + @TableField(exist = false) + @Property(value = "现岗位定级信息") + private Map currentJobScoreMation; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注说明", required = "required") + private String remark; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/JobTransferService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/JobTransferService.java new file mode 100644 index 0000000..5632845 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/JobTransferService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jobtransfer.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.jobtransfer.entity.JobTransfer; + +/** + * @ClassName: JobTransferService + * @Description: 岗位调动申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-27 15:57:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JobTransferService extends SkyeyeFlowableService { + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/impl/JobTransferServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/impl/JobTransferServiceImpl.java new file mode 100644 index 0000000..3ed98b8 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/jobtransfer/service/impl/JobTransferServiceImpl.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jobtransfer.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.constants.BossConstants; +import com.skyeye.exception.CustomException; +import com.skyeye.jobtransfer.dao.JobTransferDao; +import com.skyeye.jobtransfer.entity.JobTransfer; +import com.skyeye.jobtransfer.service.JobTransferService; +import com.skyeye.organization.service.ICompanyJobScoreService; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: JobTransferServiceImpl + * @Description: 岗位调动申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-27 15:57:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "岗位调动申请", groupName = "岗位调动申请", flowable = true) +public class JobTransferServiceImpl extends SkyeyeFlowableServiceImpl implements JobTransferService { + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + @Autowired + private ICompanyJobScoreService iCompanyJobScoreService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryJobTransferList(pageInfo); + List staffIds = beans.stream().map(bean -> bean.get("transferStaffId").toString()).collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String transferStaffId = bean.get("transferStaffId").toString(); + bean.put("transferStaffMation", staffMap.get(transferStaffId)); + }); + iCompanyService.setMationForMap(beans, "primaryCompanyId", "primaryCompanyMation"); + iCompanyService.setMationForMap(beans, "currentCompanyId", "currentCompanyMation"); + + iDepmentService.setMationForMap(beans, "primaryDepartmentId", "primaryDepartmentMation"); + iDepmentService.setMationForMap(beans, "currentDepartmentId", "currentDepartmentMation"); + + iCompanyJobService.setMationForMap(beans, "primaryJobId", "primaryJobMation"); + iCompanyJobService.setMationForMap(beans, "currentJobId", "currentJobMation"); + + iCompanyJobScoreService.setMationForMap(beans, "primaryJobScoreId", "primaryJobScoreMation"); + iCompanyJobScoreService.setMationForMap(beans, "currentJobScoreId", "currentJobScoreMation"); + return beans; + } + + + @Override + public void validatorEntity(JobTransfer entity) { + // 校验基础信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JobTransfer::getTransferStaffId), entity.getTransferStaffId()); + List states = Arrays.asList(FlowableStateEnum.DRAFT.getKey(), + FlowableStateEnum.IN_EXAMINE.getKey(), FlowableStateEnum.REJECT.getKey(), FlowableStateEnum.REVOKE.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(JobTransfer::getState), states); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + JobTransfer checkJobTeansfer = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkJobTeansfer)) { + throw new CustomException("该员工已存在调动申请."); + } + // 获取用户的信息 + Map> staffMap = iAuthUserService + .queryUserMationListByStaffIds(Arrays.asList(entity.getTransferStaffId())); + Map staff = staffMap.get(entity.getTransferStaffId()); + entity.setPrimaryCompanyId(staff.get("companyId").toString()); + entity.setPrimaryDepartmentId(staff.get("departmentId").toString()); + entity.setPrimaryJobId(staff.get("jobId").toString()); + entity.setPrimaryJobScoreId(staff.get("jobScoreId").toString()); + } + + @Override + public JobTransfer selectById(String id) { + JobTransfer jobTransfer = super.selectById(id); + // 获取申请人信息 + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(Arrays.asList(jobTransfer.getTransferStaffId())); + Map staff = staffMap.get(jobTransfer.getTransferStaffId()); + staff.put("id", staff.get("staffId")); + jobTransfer.setTransferStaffMation(staff); + + // 原岗位信息 + jobTransfer.setPrimaryCompanyMation(iCompanyService.queryDataMationById(jobTransfer.getPrimaryCompanyId())); + jobTransfer.setPrimaryDepartmentMation(iDepmentService.queryDataMationById(jobTransfer.getPrimaryDepartmentId())); + jobTransfer.setPrimaryJobMation(iCompanyJobService.queryDataMationById(jobTransfer.getPrimaryJobId())); + if (StrUtil.isNotEmpty(jobTransfer.getPrimaryJobScoreId())) { + jobTransfer.setPrimaryJobScoreMation(iCompanyJobScoreService.queryDataMationById(jobTransfer.getPrimaryJobScoreId())); + } + + // 现岗位信息 + jobTransfer.setCurrentCompanyMation(iCompanyService.queryDataMationById(jobTransfer.getCurrentCompanyId())); + jobTransfer.setCurrentDepartmentMation(iDepmentService.queryDataMationById(jobTransfer.getCurrentDepartmentId())); + jobTransfer.setCurrentJobMation(iCompanyJobService.queryDataMationById(jobTransfer.getCurrentJobId())); + if (StrUtil.isNotEmpty(jobTransfer.getCurrentJobScoreId())) { + jobTransfer.setCurrentJobScoreMation(iCompanyJobScoreService.queryDataMationById(jobTransfer.getCurrentJobScoreId())); + } + + jobTransfer.setStateName(FlowableStateEnum.getStateName(jobTransfer.getState())); + iAuthUserService.setName(jobTransfer, "createId", "createName"); + return jobTransfer; + } + + @Override + protected void approvalEndIsSuccess(JobTransfer entity) { + // 修改员工岗位信息 + skyeyeBaseMapper.updateBossInterviewJobMation(entity); + // 获取申请人信息 + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(Arrays.asList(entity.getTransferStaffId())); + String userId = staffMap.get(entity.getTransferStaffId()).get("id").toString(); + if (!ToolUtil.isBlank(userId)) { + // 删除该员工对应的缓存信息 + BossConstants.deleteCache(userId); + } + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/classenum/PersonRequireStateEnum.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/classenum/PersonRequireStateEnum.java new file mode 100644 index 0000000..e2c6c9d --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/classenum/PersonRequireStateEnum.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: PersonRequireStateEnum + * @Description: 人员需求状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PersonRequireStateEnum implements SkyeyeEnumClass { + + IN_RECRUITMENT("inRecruitment", "招聘中", true, false), + END_RECRUITMENT("endRecruitment", "招聘结束", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/controller/PersonRequireController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/controller/PersonRequireController.java new file mode 100644 index 0000000..73afb42 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/controller/PersonRequireController.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personrequire.entity.PersonRequire; +import com.skyeye.personrequire.service.PersonRequireService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PersonRequireController + * @Description: 人员需求控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/8 16:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "人员需求申请", tags = "人员需求申请", modelName = "人员需求申请") +public class PersonRequireController { + + @Autowired + private PersonRequireService personRequireService; + + /** + * 获取我发起的人员需求申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBossPersonRequireList", value = "获取我发起的人员需求申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PersonRequireController/queryPersonRequireList") + public void queryPersonRequireList(InputObject inputObject, OutputObject outputObject) { + personRequireService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑人员需求申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePersonRequire", value = "新增/编辑人员需求申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PersonRequire.class) + @RequestMapping("/post/PersonRequireController/writePersonRequire") + public void writePersonRequire(InputObject inputObject, OutputObject outputObject) { + personRequireService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 人员需求申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitPersonRequire", value = "人员需求申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "人员需求主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "[提交审批]操作必填审批人", required = "required")}) + @RequestMapping("/post/PersonRequireController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + personRequireService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废人员需求申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidPersonRequire", value = "作废人员需求申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "人员需求主键id", required = "required")}) + @RequestMapping("/post/PersonRequireController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + personRequireService.invalid(inputObject, outputObject); + } + + /** + * 撤销人员需求申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokePersonRequire", value = "撤销人员需求申请", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/PersonRequireController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + personRequireService.revoke(inputObject, outputObject); + } + + /** + * 人员需求申请责任人设置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setPersonLiable", value = "人员需求申请责任人设置", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "人员需求主键id", required = "required"), + @ApiImplicitParam(id = "personLiable", name = "personLiable", value = "人员需求的责任人", required = "required,json")}) + @RequestMapping("/post/PersonRequireController/setPersonLiable") + public void setPersonLiable(InputObject inputObject, OutputObject outputObject) { + personRequireService.setPersonLiable(inputObject, outputObject); + } + + /** + * 获取我负责的人员需求申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyChargePersonRequireList", value = "获取我负责的人员需求申请", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PersonRequireController/queryMyChargePersonRequireList") + public void queryMyChargePersonRequireList(InputObject inputObject, OutputObject outputObject) { + personRequireService.queryMyChargePersonRequireList(inputObject, outputObject); + } + + /** + * 获取所有审批通过状态之后的人员需求申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllBossPersonRequireList", value = "获取所有审批通过状态之后的人员需求申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PersonRequireController/queryAllPersonRequireList") + public void queryAllPersonRequireList(InputObject inputObject, OutputObject outputObject) { + personRequireService.queryAllPersonRequireList(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/dao/PersonRequireDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/dao/PersonRequireDao.java new file mode 100644 index 0000000..cd9a76a --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/dao/PersonRequireDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.personrequire.entity.PersonRequire; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PersonRequireDao + * @Description: 人员需求数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/8 16:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PersonRequireDao extends SkyeyeBaseMapper { + + List> queryPersonRequireList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/entity/PersonRequire.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/entity/PersonRequire.java new file mode 100644 index 0000000..72e9348 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/entity/PersonRequire.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PersonRequire + * @Description: 人员需求申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/9 18:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "boss:personRequire", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "boss_person_require", autoResultMap = true) +@ApiModel("人员需求申请实体类") +public class PersonRequire extends SkyeyeFlowable { + + @TableField(value = "recruit_department_id") + @ApiModelProperty(value = "招聘部门id", required = "required") + private String recruitDepartmentId; + + @TableField(exist = false) + @Property(value = "招聘部门信息") + private Map recruitDepartmentMation; + + @TableField(value = "recruit_job_id") + @ApiModelProperty(value = "招聘岗位id", required = "required") + private String recruitJobId; + + @TableField(exist = false) + @Property(value = "招聘岗位信息") + private Map recruitJobMation; + + @TableField(value = "recruit_num") + @ApiModelProperty(value = "招聘人数", required = "required") + private Integer recruitNum; + + @TableField(value = "wages") + @ApiModelProperty(value = "薪资范围", required = "required") + private String wages; + + @TableField(value = "job_require") + @ApiModelProperty(value = "岗位要求", required = "required") + private String jobRequire; + + @TableField(value = "remark") + @ApiModelProperty(value = "说明备注") + private String remark; + + @TableField(value = "person_liable", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "人员需求的责任人") + private List personLiable; + + @TableField(exist = false) + @Property(value = "人员需求的责任人信息") + private List> personLiableMation; + + @TableField(value = "recruited_num") + @Property(value = "已招聘人数") + private Integer recruitedNum; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/PersonRequireService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/PersonRequireService.java new file mode 100644 index 0000000..3da80dc --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/PersonRequireService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personrequire.entity.PersonRequire; + +/** + * @ClassName: PersonRequireService + * @Description: 人员需求服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/8 16:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PersonRequireService extends SkyeyeFlowableService { + + void setPersonLiable(InputObject inputObject, OutputObject outputObject); + + void queryMyChargePersonRequireList(InputObject inputObject, OutputObject outputObject); + + void queryAllPersonRequireList(InputObject inputObject, OutputObject outputObject); + + /** + * 修改招聘人数num + * + * @param id + * @param num + */ + void updatePersonRequireNum(String id, Integer num); +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/impl/PersonRequireServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/impl/PersonRequireServiceImpl.java new file mode 100644 index 0000000..c624491 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/personrequire/service/impl/PersonRequireServiceImpl.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personrequire.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.personrequire.classenum.PersonRequireStateEnum; +import com.skyeye.personrequire.dao.PersonRequireDao; +import com.skyeye.personrequire.entity.PersonRequire; +import com.skyeye.personrequire.service.PersonRequireService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PersonRequireServiceImpl + * @Description: 人员需求服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/8 16:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "人员需求申请", groupName = "人员需求申请", flowable = true) +public class PersonRequireServiceImpl extends SkyeyeFlowableServiceImpl implements PersonRequireService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = queryBySQL(pageInfo); + return beans; + } + + private List> queryBySQL(CommonPageInfo pageInfo) { + List> beans = skyeyeBaseMapper.queryPersonRequireList(pageInfo); + iDepmentService.setMationForMap(beans, "recruitDepartmentId", "recruitDepartmentMation"); + iCompanyJobService.setMationForMap(beans, "recruitJobId", "recruitJobMation"); + return beans; + } + + @Override + public PersonRequire selectById(String id) { + PersonRequire personRequire = super.selectById(id); + // 获取部门信息 + personRequire.setRecruitDepartmentMation(iDepmentService.queryDataMationById(personRequire.getRecruitDepartmentId())); + // 获取招聘岗位 + personRequire.setRecruitJobMation(iCompanyJobService.queryDataMationById(personRequire.getRecruitJobId())); + // 获取负责人信息 + if (CollectionUtil.isNotEmpty(personRequire.getPersonLiable())) { + personRequire.setPersonLiableMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(personRequire.getPersonLiable()))); + } + return personRequire; + } + + @Override + public List selectByIds(String... ids) { + List personRequires = super.selectByIds(ids); + // 获取部门信息 + iDepmentService.setDataMation(personRequires, PersonRequire::getRecruitDepartmentId); + // 获取招聘岗位 + iCompanyJobService.setDataMation(personRequires, PersonRequire::getRecruitJobId); + // 获取负责人信息 + List personLiableIds = personRequires.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getPersonLiable())) + .flatMap(norms -> norms.getPersonLiable().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(personLiableIds)) { + Map> userMap = iAuthUserService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(personLiableIds)); + personRequires.forEach(personRequire -> { + if (CollectionUtil.isEmpty(personRequire.getPersonLiable())) { + return; + } + List> userMation = new ArrayList<>(); + personRequire.getPersonLiable().forEach(personLiableId -> { + if (!userMap.containsKey(personLiableId)) { + return; + } + userMation.add(userMap.get(personLiableId)); + }); + personRequire.setPersonLiableMation(userMation); + }); + } + return personRequires; + } + + /** + * 人员需求申请责任人设置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void setPersonLiable(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + PersonRequire personRequire = selectById(id); + if (StrUtil.equals(FlowableStateEnum.PASS.getKey(), personRequire.getState()) + || StrUtil.equals(PersonRequireStateEnum.IN_RECRUITMENT.getKey(), personRequire.getState())) { + // 审核通过状态/招聘中可以设置责任人 + List personLiable = JSONUtil.toList(map.get("personLiable").toString(), null); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + personRequire.setPersonLiable(personLiable); + update(personRequire, updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("只有审核通过状态下/招聘中可以设置责任人"); + } + } + + /** + * 获取我负责的人员需求申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyChargePersonRequireList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + // 我负责的 + pageInfo.setChargePersonId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = queryBySQL(pageInfo); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取所有审批通过状态之后的人员需求申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllPersonRequireList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + // 审核通过,招聘中,招聘结束 + pageInfo.setStateList(Arrays.asList(FlowableStateEnum.PASS.getKey(), PersonRequireStateEnum.IN_RECRUITMENT.getKey(), + PersonRequireStateEnum.END_RECRUITMENT.getKey())); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = queryBySQL(pageInfo); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void updatePersonRequireNum(String id, Integer num) { + PersonRequire personRequire = selectById(id); + if (StrUtil.equals(FlowableStateEnum.PASS.getKey(), personRequire.getState()) + || StrUtil.equals(PersonRequireStateEnum.IN_RECRUITMENT.getKey(), personRequire.getState())) { + // 审核通过,招聘中的可以修改已招聘人数 + Integer currentNum = personRequire.getRecruitedNum() + num; + if (currentNum > personRequire.getRecruitNum()) { + throw new CustomException("超出该人员需求申请单的招聘人数。"); + } + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(PersonRequire::getRecruitedNum), currentNum); + if (currentNum == personRequire.getRecruitNum()) { + updateWrapper.set(MybatisPlusUtil.toColumns(PersonRequire::getState), PersonRequireStateEnum.END_RECRUITMENT.getKey()); + } + update(updateWrapper); + refreshCache(id); + } else { + throw new CustomException("人员需求申请单状态错误。"); + } + } +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/controller/QuitController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/controller/QuitController.java new file mode 100644 index 0000000..e74b20b --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/controller/QuitController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.quit.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.quit.entity.Quit; +import com.skyeye.quit.service.QuitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: QuitController + * @Description: 离职申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-25 18:08:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "离职申请", tags = "离职申请", modelName = "离职申请") +public class QuitController { + + @Autowired + private QuitService quitService; + + /** + * 获取我发起的离职申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBossInterviewQuitList", value = "获取我发起的离职申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/QuitController/queryInterviewQuitList") + public void queryInterviewQuitList(InputObject inputObject, OutputObject outputObject) { + quitService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑离职申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeInterviewQuit", value = "新增/编辑离职申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Quit.class) + @RequestMapping("/post/QuitController/writeInterviewQuit") + public void writeInterviewQuit(InputObject inputObject, OutputObject outputObject) { + quitService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 离职申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitInterviewQuit", value = "离职申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "离职申请主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "[提交审批]操作必填审批人", required = "required")}) + @RequestMapping("/post/QuitController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + quitService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废离职申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidInterviewQuit", value = "作废离职申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "离职申请主键id", required = "required")}) + @RequestMapping("/post/QuitController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + quitService.invalid(inputObject, outputObject); + } + + /** + * 撤销离职申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeInterviewQuit", value = "撤销离职申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/QuitController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + quitService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/dao/QuitDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/dao/QuitDao.java new file mode 100644 index 0000000..6294838 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/dao/QuitDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.quit.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.quit.entity.Quit; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: QuitDao + * @Description: 离职申请数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-25 18:08:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QuitDao extends SkyeyeBaseMapper { + + List> queryBossInterviewQuitList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/entity/Quit.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/entity/Quit.java new file mode 100644 index 0000000..1d415c5 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/entity/Quit.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.quit.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +/** + * @ClassName: Quit + * @Description: 离职申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-25 18:08:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "boss:quit", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "boss_interview_quit", autoResultMap = true) +@ApiModel("离职申请实体类") +public class Quit extends SkyeyeFlowable { + + @TableField(value = "leave_time") + @ApiModelProperty(value = "申请离职的日期", required = "required") + private String leaveTime; + + @TableField(value = "leave_type") + @ApiModelProperty(value = "离职类型,参考#UserQuitType", required = "required") + private String leaveType; + + @TableField(value = "remark") + @ApiModelProperty(value = "离职原因", required = "required") + private String remark; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/QuitService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/QuitService.java new file mode 100644 index 0000000..5ab2ed0 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/QuitService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.quit.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.quit.entity.Quit; + +/** + * @ClassName: QuitService + * @Description: 离职申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-25 18:08:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QuitService extends SkyeyeFlowableService { + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/impl/QuitServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/impl/QuitServiceImpl.java new file mode 100644 index 0000000..8ad775b --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/quit/service/impl/QuitServiceImpl.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.quit.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.centerrest.entity.staff.UserStaffLeaveRest; +import com.skyeye.centerrest.user.SysEveUserStaffService; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.UserStaffState; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.constants.BossConstants; +import com.skyeye.exception.CustomException; +import com.skyeye.quit.dao.QuitDao; +import com.skyeye.quit.entity.Quit; +import com.skyeye.quit.service.QuitService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: QuitServiceImpl + * @Description: 离职申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-25 18:08:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "离职申请", groupName = "离职申请", flowable = true) +public class QuitServiceImpl extends SkyeyeFlowableServiceImpl implements QuitService { + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryBossInterviewQuitList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(Quit entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + boolean canApply = isCanApply(userId, entity.getId()); + if (!canApply) { + throw new CustomException("您已提交过离职申请,请等待审批。"); + } + } + + @Override + public Quit selectById(String id) { + Quit quit = super.selectById(id); + iAuthUserService.setName(quit, "createId", "createName"); + return quit; + } + + @Override + protected void approvalEndIsSuccess(Quit entity) { + Map userMation = iAuthUserService.queryDataMationById(entity.getCreateId()); + String staffId = userMation.get("staffId").toString(); + + // 修改员工信息为离职状态 + UserStaffLeaveRest userStaffLeaveRest = new UserStaffLeaveRest(); + userStaffLeaveRest.setRowId(staffId); + userStaffLeaveRest.setQuitTime(entity.getLeaveTime()); + userStaffLeaveRest.setQuitReason(entity.getRemark()); + ExecuteFeignClient.get(() -> sysEveUserStaffService.userStaffQuit(userStaffLeaveRest)); + // 删除该员工对应的缓存信息 + BossConstants.deleteCache(entity.getCreateId()); + } + + /** + * 是否可以提交离职申请。true:可以;false:不可以 + * + * @param userId 用户id + * @return true:可以;false:不可以 + */ + private boolean isCanApply(String userId, String id) { + Map user = iAuthUserService.queryDataMationById(userId); + Integer state = Integer.parseInt(user.get("state").toString()); + // 是否可以提交离职申请。true:可以;false:不可以 + boolean canApply = false; + if (state == UserStaffState.ON_THE_JOB.getKey() + || state == UserStaffState.PROBATION.getKey() + || state == UserStaffState.PROBATION_PERIOD.getKey()) { + // 试用期,获取该用户是否有已经添加的离职申请(不是作废状态的) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Quit::getCreateId), userId); + queryWrapper.ne(MybatisPlusUtil.toColumns(Quit::getState), FlowableStateEnum.INVALID.getKey()); + if (StringUtils.isNotEmpty(id)) { + queryWrapper.ne(CommonConstants.ID, id); + } + List list = list(queryWrapper); + if (CollectionUtil.isEmpty(list)) { + // 为空,说明还没有提交离职申请 + canApply = true; + } + } + return canApply; + } +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/controller/RegularWorkerController.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/controller/RegularWorkerController.java new file mode 100644 index 0000000..532846a --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/controller/RegularWorkerController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.regularworker.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.regularworker.entity.RegularWorker; +import com.skyeye.regularworker.service.RegularWorkerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RegularWorkerController + * @Description: 转正申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-24 15:16:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "转正申请", tags = "转正申请", modelName = "转正申请") +public class RegularWorkerController { + + @Autowired + private RegularWorkerService regularWorkerService; + + /** + * 获取我发起的转正申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBossInterviewRegularWorkerList", value = "获取我发起的转正申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RegularWorkerController/queryRegularWorkerList") + public void queryRegularWorkerList(InputObject inputObject, OutputObject outputObject) { + regularWorkerService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑转正申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRegularWorker", value = "新增/编辑转正申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RegularWorker.class) + @RequestMapping("/post/RegularWorkerController/writeRegularWorker") + public void writeRegularWorker(InputObject inputObject, OutputObject outputObject) { + regularWorkerService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转正申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitRegularWorker", value = "转正申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "转正申请主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "[提交审批]操作必填审批人", required = "required")}) + @RequestMapping("/post/RegularWorkerController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + regularWorkerService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废转正申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidRegularWorker", value = "作废转正申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "转正申请主键id", required = "required")}) + @RequestMapping("/post/RegularWorkerController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + regularWorkerService.invalid(inputObject, outputObject); + } + + /** + * 撤销转正申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeRegularWorker", value = "撤销转正申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/RegularWorkerController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + regularWorkerService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/dao/RegularWorkerDao.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/dao/RegularWorkerDao.java new file mode 100644 index 0000000..775b372 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/dao/RegularWorkerDao.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.regularworker.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.regularworker.entity.RegularWorker; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: RegularWorkerDao + * @Description: 转正申请数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-24 15:16:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RegularWorkerDao extends SkyeyeBaseMapper { + + List> queryBossRegularWorkerList(CommonPageInfo pageInfo); + + /** + * 修改员工状态为正式工 + * + * @param userId 用户id + * @param state 状态 + * @param regularTime 转正日期 + */ + void updateUserStaffState(@Param("userId") String userId, @Param("state") Integer state, + @Param("regularTime") String regularTime); +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/entity/RegularWorker.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/entity/RegularWorker.java new file mode 100644 index 0000000..0f184b5 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/entity/RegularWorker.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.regularworker.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: RegularWorker + * @Description: 转正申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-24 15:16:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "boss:regularWorker", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "boss_interview_regular_worker", autoResultMap = true) +@ApiModel("转正申请实体类") +public class RegularWorker extends SkyeyeFlowable { + + @TableField(value = "department_id") + @Property(value = "申请人部门id") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "job_id") + @Property(value = "申请人岗位id") + private String jobId; + + @TableField(exist = false) + @Property(value = "岗位信息") + private Map jobMation; + + @TableField(value = "regular_time") + @ApiModelProperty(value = "转正日期", required = "required") + private String regularTime; + + @TableField(value = "remark") + @ApiModelProperty(value = "申请说明", required = "required") + private String remark; + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/RegularWorkerService.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/RegularWorkerService.java new file mode 100644 index 0000000..e81fca9 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/RegularWorkerService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.regularworker.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.regularworker.entity.RegularWorker; + +/** + * @ClassName: RegularWorkerService + * @Description: 转正申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-24 15:16:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RegularWorkerService extends SkyeyeFlowableService { + +} diff --git a/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/impl/RegularWorkerServiceImpl.java b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/impl/RegularWorkerServiceImpl.java new file mode 100644 index 0000000..bc7917f --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/java/com/skyeye/regularworker/service/impl/RegularWorkerServiceImpl.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.regularworker.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.UserStaffState; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.constants.BossConstants; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.quit.entity.Quit; +import com.skyeye.regularworker.dao.RegularWorkerDao; +import com.skyeye.regularworker.entity.RegularWorker; +import com.skyeye.regularworker.service.RegularWorkerService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: RegularWorkerServiceImpl + * @Description: 转正申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022-04-24 15:16:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "转正申请", groupName = "转正申请", flowable = true) +public class RegularWorkerServiceImpl extends SkyeyeFlowableServiceImpl implements RegularWorkerService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryBossRegularWorkerList(pageInfo); + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + iCompanyJobService.setMationForMap(beans, "jobId", "jobMation"); + return beans; + } + + @Override + public void validatorEntity(RegularWorker entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + boolean canApply = isCanApply(userId, entity.getId()); + if (!canApply) { + throw new CustomException("您已提交过转正申请,请等待审批。"); + } + // 获取用户的信息 + Map> staffMap = iAuthUserService + .queryUserMationListByStaffIds(Arrays.asList(userId)); + Map staff = staffMap.get(userId); + entity.setDepartmentId(staff.get("departmentId").toString()); + entity.setJobId(staff.get("jobId").toString()); + } + + @Override + public RegularWorker selectById(String id) { + RegularWorker regularWorker = super.selectById(id); + iAuthUserService.setName(regularWorker, "createId", "createName"); + // 部门信息 + Map department = iDepmentService.queryDataMationById(regularWorker.getDepartmentId()); + regularWorker.setDepartmentMation(department); + // 岗位信息 + regularWorker.setJobMation(iCompanyJobService.queryDataMationById(regularWorker.getJobId())); + return regularWorker; + } + + @Override + protected void approvalEndIsSuccess(RegularWorker entity) { + skyeyeBaseMapper.updateUserStaffState(entity.getCreateId(), UserStaffState.ON_THE_JOB.getKey(), entity.getRegularTime()); + // 删除该员工对应的缓存信息 + BossConstants.deleteCache(entity.getCreateId()); + } + + /** + * 是否可以提交转正申请。true:可以;false:不可以 + * + * @param userId 用户id + * @return true:可以;false:不可以 + */ + private boolean isCanApply(String userId, String id) { + Map user = iAuthUserService.queryDataMationById(userId); + Integer state = Integer.parseInt(user.get("state").toString()); + // 是否可以提交转正申请。true:可以;false:不可以 + boolean canApply = false; + if (state == UserStaffState.PROBATION_PERIOD.getKey()) { + // 试用期,获取该用户是否有已经添加的转正申请(不是作废状态的) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Quit::getCreateId), userId); + queryWrapper.ne(MybatisPlusUtil.toColumns(Quit::getState), FlowableStateEnum.INVALID.getKey()); + if (StringUtils.isNotEmpty(id)) { + queryWrapper.ne(CommonConstants.ID, id); + } + List list = list(queryWrapper); + if (CollectionUtil.isEmpty(list)) { + // 为空,说明还没有提交转正申请 + canApply = true; + } + } + return canApply; + } +} diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/arrangement/ArrangementMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/arrangement/ArrangementMapper.xml new file mode 100644 index 0000000..b82e271 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/arrangement/ArrangementMapper.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeFromMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeFromMapper.xml new file mode 100644 index 0000000..af929a3 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeFromMapper.xml @@ -0,0 +1,28 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeMapper.xml new file mode 100644 index 0000000..ef59830 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/interviewee/IntervieweeMapper.xml @@ -0,0 +1,45 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/jobtransfer/JobTransferMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/jobtransfer/JobTransferMapper.xml new file mode 100644 index 0000000..c3f9dc0 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/jobtransfer/JobTransferMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + UPDATE sys_eve_user_staff + + company_id = #{currentCompanyId}, + department_id = #{currentDepartmentId}, + job_id = #{currentJobId}, + job_score_id = #{currentJobScoreId}, + + WHERE id = #{transferStaffId} + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/personRequire/PersonRequireMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/personRequire/PersonRequireMapper.xml new file mode 100644 index 0000000..c4cfc00 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/personRequire/PersonRequireMapper.xml @@ -0,0 +1,44 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/quit/QuitMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/quit/QuitMapper.xml new file mode 100644 index 0000000..516db5b --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/quit/QuitMapper.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-pro/src/main/resources/mapper/regularworker/RegularWorkerMapper.xml b/skyeye-boss/boss-pro/src/main/resources/mapper/regularworker/RegularWorkerMapper.xml new file mode 100644 index 0000000..f4b27f5 --- /dev/null +++ b/skyeye-boss/boss-pro/src/main/resources/mapper/regularworker/RegularWorkerMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + UPDATE sys_eve_user_staff + + state = #{state}, + become_worker_time = #{regularTime} + + WHERE user_id = #{userId} + + + \ No newline at end of file diff --git a/skyeye-boss/boss-web/.gitignore b/skyeye-boss/boss-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-boss/boss-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-boss/boss-web/pom.xml b/skyeye-boss/boss-web/pom.xml new file mode 100644 index 0000000..1929d6a --- /dev/null +++ b/skyeye-boss/boss-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-boss + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + boss-web + + + 8 + 8 + + + + + + com.skyeye + boss-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-boss/boss-web/src/main/java/com/BossApplication.java b/skyeye-boss/boss-web/src/main/java/com/BossApplication.java new file mode 100644 index 0000000..948a9c5 --- /dev/null +++ b/skyeye-boss/boss-web/src/main/java/com/BossApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class BossApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(BossApplication.class, args); + } + +} diff --git a/skyeye-boss/boss-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-boss/boss-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..6929a6e --- /dev/null +++ b/skyeye-boss/boss-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.*.dao", + "com.skyeye.eve.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-boss/boss-web/src/main/resources/banner.txt b/skyeye-boss/boss-web/src/main/resources/banner.txt new file mode 100644 index 0000000..01334f8 --- /dev/null +++ b/skyeye-boss/boss-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev boss-web.jar >> /opt/service/project/nohup-boss.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-boss/boss-web/src/main/resources/bootstrap.yml b/skyeye-boss/boss-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5aa1e63 --- /dev/null +++ b/skyeye-boss/boss-web/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +server: + port: 8104 + +spring: + application: + name: skyeye-boss-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: localhost:9000 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: localhost:9000 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-boss/boss-web/src/main/resources/jvm调优参数配置 b/skyeye-boss/boss-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-boss/boss-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-boss/boss-web/src/main/resources/log4j.properties b/skyeye-boss/boss-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-boss/boss-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-boss/pom.xml b/skyeye-boss/pom.xml new file mode 100644 index 0000000..e7893a4 --- /dev/null +++ b/skyeye-boss/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + boss-common + boss-pro + boss-web + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-boss + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-checkwork/.gitignore b/skyeye-checkwork/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-checkwork/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-common/.gitignore b/skyeye-checkwork/checkwork-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-checkwork/checkwork-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-common/pom.xml b/skyeye-checkwork/checkwork-common/pom.xml new file mode 100644 index 0000000..8a6a652 --- /dev/null +++ b/skyeye-checkwork/checkwork-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-checkwork + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + checkwork-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-common/src/main/java/com/skyeye/constants/CheckWorkConstants.java b/skyeye-checkwork/checkwork-common/src/main/java/com/skyeye/constants/CheckWorkConstants.java new file mode 100644 index 0000000..7b2a1da --- /dev/null +++ b/skyeye-checkwork/checkwork-common/src/main/java/com/skyeye/constants/CheckWorkConstants.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constants; + +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.util.ToolUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: CheckWorkConstants + * @Description: 考勤相关的常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/24 11:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public class CheckWorkConstants { + + /** + * 构造上班日的对象数据 + * + * @param day 指定日期 + * @return + */ + public static Map structureWorkMation(String day) { + Map mation = new HashMap<>(); + mation.put("title", "班"); + mation.put("start", day + " 00:00:00"); + mation.put("end", day + " 23:59:59"); + mation.put("backgroundColor", ""); + mation.put("allDay", "1"); + mation.put("showBg", "2"); + mation.put("editable", false); + mation.put("type", CheckDayType.DAY_IS_WORKING.getKey()); + mation.put("className", CheckDayType.DAY_IS_WORKING.getClassName()); + return mation; + } + + /** + * 构造星期天休息日的对象数据 + * + * @param day 指定日期 + * @param title 标题 + * @return + */ + public static Map structureRestMation(String day, String title) { + Map mation = new HashMap<>(); + mation.put("title", ToolUtil.isBlank(title) ? "休" : title); + mation.put("start", day + " 00:00:00"); + mation.put("end", day + " 23:59:59"); + mation.put("backgroundColor", "#54FF9F"); + mation.put("allDay", "1"); + mation.put("showBg", "2"); + mation.put("editable", false); + mation.put("type", CheckDayType.DAY_IS_HOLIDAY.getKey()); + mation.put("className", CheckDayType.DAY_IS_HOLIDAY.getClassName()); + return mation; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/.gitignore b/skyeye-checkwork/checkwork-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/pom.xml b/skyeye-checkwork/checkwork-pro/pom.xml new file mode 100644 index 0000000..1d2a5f0 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-checkwork + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + checkwork-pro + + + + + com.skyeye + checkwork-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/controller/AppealController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/controller/AppealController.java new file mode 100644 index 0000000..4648f3c --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/controller/AppealController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.appeal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.appeal.entity.Appeal; +import com.skyeye.appeal.service.AppealService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AppealController + * @Description: 考勤申诉管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/18 11:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "考勤申诉", tags = "考勤申诉", modelName = "考勤申诉") +public class AppealController { + + @Autowired + private AppealService appealService; + + /** + * 获取我的考勤申诉列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAppealList", value = "获取我的考勤申诉列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AppealController/queryAppealList") + public void queryAppealList(InputObject inputObject, OutputObject outputObject) { + appealService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑考勤申诉 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAppeal", value = "新增/编辑考勤申诉", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Appeal.class) + @RequestMapping("/post/AppealController/writeAppeal") + public void writeAppeal(InputObject inputObject, OutputObject outputObject) { + appealService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 考勤申诉提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitAppeal", value = "考勤申诉提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/AppealController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + appealService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废考勤申诉 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidAppeal", value = "作废考勤申诉", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AppealController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + appealService.invalid(inputObject, outputObject); + } + + /** + * 撤销考勤申诉 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeAppeal", value = "撤销考勤申诉", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/AppealController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + appealService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/dao/AppealDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/dao/AppealDao.java new file mode 100644 index 0000000..e77f373 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/dao/AppealDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.appeal.dao; + +import com.skyeye.appeal.entity.Appeal; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AppealDao + * @Description: 考勤申诉管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/18 11:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AppealDao extends SkyeyeBaseMapper { + + List> queryAppealList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/entity/Appeal.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/entity/Appeal.java new file mode 100644 index 0000000..dfe7048 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/entity/Appeal.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.appeal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.checkwork.entity.CheckWork; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +/** + * @ClassName: Appeal + * @Description: 考勤申诉实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/18 11:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:appeal", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "check_work_appeal") +@ApiModel("考勤申诉实体类") +public class Appeal extends SkyeyeFlowable { + + @TableField("work_id") + @ApiModelProperty(value = "考勤工作日id", required = "required") + private String workId; + + @TableField(exist = false) + @Property(value = "考勤工作日信息") + private CheckWork workMation; + + @TableField("appeal_reason_id") + @ApiModelProperty(value = "申诉类型id,数据字典", required = "required") + private String appealReasonId; + + @TableField("appeal_reason") + @ApiModelProperty(value = "申诉原因", required = "required") + private String appealReason; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/AppealService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/AppealService.java new file mode 100644 index 0000000..6a531d8 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/AppealService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.appeal.service; + +import com.skyeye.appeal.entity.Appeal; +import com.skyeye.base.business.service.SkyeyeFlowableService; + +/** + * @ClassName: AppealService + * @Description: 考勤申诉管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/18 11:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AppealService extends SkyeyeFlowableService { +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/impl/AppealServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/impl/AppealServiceImpl.java new file mode 100644 index 0000000..cbd8aa9 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/appeal/service/impl/AppealServiceImpl.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.appeal.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.appeal.dao.AppealDao; +import com.skyeye.appeal.entity.Appeal; +import com.skyeye.appeal.service.AppealService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.checkwork.service.CheckWorkService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AppealServiceImpl + * @Description: 考勤申诉管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/18 11:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "考勤申诉", groupName = "考勤申诉", flowable = true) +public class AppealServiceImpl extends SkyeyeFlowableServiceImpl implements AppealService { + + @Autowired + private CheckWorkService checkWorkService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryAppealList(pageInfo); + return beans; + } + + @Override + public Appeal selectById(String id) { + Appeal appeal = super.selectById(id); + checkWorkService.setDataMation(appeal, Appeal::getWorkId); + return appeal; + } +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/controller/CancelLeaveController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/controller/CancelLeaveController.java new file mode 100644 index 0000000..9b6b654 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/controller/CancelLeaveController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.cancleleave.entity.CancelLeave; +import com.skyeye.cancleleave.service.CancelLeaveService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CancelLeaveController + * @Description: 销假申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/11 9:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "销假申请", tags = "销假申请", modelName = "销假申请") +public class CancelLeaveController { + + @Autowired + private CancelLeaveService cancelLeaveService; + + /** + * 获取我的销假申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkcancelleave001", value = "获取我的销假申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CancelLeaveController/queryCancelLeaveList") + public void queryCancelLeaveList(InputObject inputObject, OutputObject outputObject) { + cancelLeaveService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑销假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCancelLeave", value = "新增/编辑销假申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CancelLeave.class) + @RequestMapping("/post/CancelLeaveController/writeCancelLeave") + public void writeCancelLeave(InputObject inputObject, OutputObject outputObject) { + cancelLeaveService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 销假申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkcancelleave006", value = "销假申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/CancelLeaveController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + cancelLeaveService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废销假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkcancelleave007", value = "作废销假申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CancelLeaveController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + cancelLeaveService.invalid(inputObject, outputObject); + } + + /** + * 撤销销假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkcancelleave009", value = "撤销出差申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/CancelLeaveController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + cancelLeaveService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveDao.java new file mode 100644 index 0000000..569f341 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveDao.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.dao; + +import com.skyeye.cancleleave.entity.CancelLeave; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CancelLeaveDao + * @Description: 销假申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/11 9:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface CancelLeaveDao extends SkyeyeBaseMapper { + + List> queryMyCheckWorkCancelLeaveList(CommonPageInfo pageInfo); + + /** + * 获取指定日期已经审核通过的信息 + * + * @param createId 创建人 + * @param cancelDay 指定日期 + * @param childState 子对象状态 + * @return + */ + Map queryCheckWorkCancelLeaveByMation(@Param("createId") String createId, + @Param("cancelDay") String cancelDay, + @Param("childState") String childState); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveTimeSlotDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveTimeSlotDao.java new file mode 100644 index 0000000..dd5e8b6 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/dao/CancelLeaveTimeSlotDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.dao; + +import com.skyeye.cancleleave.entity.CancelLeaveTimeSlot; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CancelLeaveTimeSlotDao + * @Description: 销假申请销假时间段数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 14:28 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CancelLeaveTimeSlotDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeave.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeave.java new file mode 100644 index 0000000..b7df594 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeave.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: CancelLeave + * @Description: 销假申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:cancelLeave", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "check_work_cancel_leave", autoResultMap = true) +@ApiModel("销假申请实体类") +public class CancelLeave extends SkyeyeFlowable { + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "销假时间段", required = "required,json") + private List cancelLeaveTimeSlotList; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeaveTimeSlot.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeaveTimeSlot.java new file mode 100644 index 0000000..e60bab3 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/entity/CancelLeaveTimeSlot.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import com.skyeye.worktime.entity.CheckWorkTime; +import lombok.Data; + +/** + * @ClassName: CancelLeaveTimeSlot + * @Description: 销假申请销假时间段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "check_work_cancel_leave_time_slot", autoResultMap = true) +@ApiModel("销假申请销假时间段实体类") +public class CancelLeaveTimeSlot extends SkyeyeLinkData { + + @TableField(value = "time_id") + @ApiModelProperty(value = "班次id", required = "required") + private String timeId; + + @TableField(exist = false) + @Property(value = "班次信息") + private CheckWorkTime timeMation; + + @TableField(value = "cancel_day") + @ApiModelProperty(value = "销假日期,格式:yyyy-MM-dd", required = "required") + private String cancelDay; + + @TableField(value = "cancel_start_time") + @ApiModelProperty(value = "销假开始时间,格式:HH:mm:ss", required = "required") + private String cancelStartTime; + + @TableField(value = "cancel_end_time") + @ApiModelProperty(value = "销假结束时间,格式:HH:mm:ss", required = "required") + private String cancelEndTime; + + @TableField(value = "cancel_hour") + @ApiModelProperty(value = "销假工时", required = "required") + private String cancelHour; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveService.java new file mode 100644 index 0000000..dd90c0a --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.cancleleave.entity.CancelLeave; + +/** + * @ClassName: CheckWorkCancelLeaveService + * @Description: 销假申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/11 9:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface CancelLeaveService extends SkyeyeFlowableService { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveTimeSlotService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveTimeSlotService.java new file mode 100644 index 0000000..7235598 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/CancelLeaveTimeSlotService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.cancleleave.entity.CancelLeaveTimeSlot; + +/** + * @ClassName: CancelLeaveTimeSlotService + * @Description: 销假申请销假时间段服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 14:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CancelLeaveTimeSlotService extends SkyeyeLinkDataService { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveServiceImpl.java new file mode 100644 index 0000000..705f888 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveServiceImpl.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.cancleleave.dao.CancelLeaveDao; +import com.skyeye.cancleleave.entity.CancelLeave; +import com.skyeye.cancleleave.entity.CancelLeaveTimeSlot; +import com.skyeye.cancleleave.service.CancelLeaveService; +import com.skyeye.cancleleave.service.CancelLeaveTimeSlotService; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.centerrest.entity.checkwork.UserStaffHolidayRest; +import com.skyeye.eve.centerrest.user.SysEveUserService; +import com.skyeye.exception.CustomException; +import com.skyeye.leave.classenum.UseYearHolidayType; +import com.skyeye.leave.service.LeaveService; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.service.CheckWorkTimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CheckWorkCancelLeaveServiceImpl + * @Description: 销假申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/11 9:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "销假申请", groupName = "销假申请", flowable = true) +public class CancelLeaveServiceImpl extends SkyeyeFlowableServiceImpl implements CancelLeaveService { + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Autowired + private CancelLeaveTimeSlotService cancelLeaveTimeSlotService; + + @Autowired + private LeaveService leaveService; + + @Autowired + private SysEveUserService sysEveUserService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryMyCheckWorkCancelLeaveList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(CancelLeave entity) { + checkOrderItem(entity.getCancelLeaveTimeSlotList()); + } + + @Override + public void writeChild(CancelLeave entity, String userId) { + cancelLeaveTimeSlotService.saveLinkList(entity.getId(), entity.getCancelLeaveTimeSlotList()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(List cancelLeaveTimeSlots) { + List cancelDay = cancelLeaveTimeSlots.stream() + .map(bean -> String.format(Locale.ROOT, "%s-%s", bean.getTimeId(), bean.getCancelDay())).distinct() + .collect(Collectors.toList()); + if (cancelLeaveTimeSlots.size() != cancelDay.size()) { + throw new CustomException("同一班次中不允许出现相同的销假日期"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + cancelLeaveTimeSlotService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public CancelLeave getDataFromDb(String id) { + CancelLeave cancelLeave = super.getDataFromDb(id); + List cancelLeaveTimeSlotList = cancelLeaveTimeSlotService.selectByPId(cancelLeave.getId()); + cancelLeave.setCancelLeaveTimeSlotList(cancelLeaveTimeSlotList); + return cancelLeave; + } + + @Override + public CancelLeave selectById(String id) { + CancelLeave cancelLeave = super.selectById(id); + // 获取考勤班次信息 + List timeIds = cancelLeave.getCancelLeaveTimeSlotList().stream() + .map(CancelLeaveTimeSlot::getTimeId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(timeIds)) { + Map checkWorkTimeMap = checkWorkTimeService.selectMapByIds(timeIds); + cancelLeave.getCancelLeaveTimeSlotList().forEach(cancelLeaveTimeSlot -> { + cancelLeaveTimeSlot.setTimeMation(checkWorkTimeMap.get(cancelLeaveTimeSlot.getTimeId())); + cancelLeaveTimeSlot.setStateName(FlowableChildStateEnum.getStateName(cancelLeaveTimeSlot.getState())); + }); + } + cancelLeave.setStateName(FlowableStateEnum.getStateName(cancelLeave.getState())); + iAuthUserService.setName(cancelLeave, "createId", "createName"); + return cancelLeave; + } + + @Override + public void revokePostpose(CancelLeave entity) { + super.revokePostpose(entity); + cancelLeaveTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(CancelLeave entity) { + calcUserStaffCancelLeaveMation(entity.getId(), entity.getCreateId()); + } + + @Override + protected void approvalEndIsFailed(CancelLeave entity) { + cancelLeaveTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + /** + * 计算销假中关联的年假信息,更新员工年假 + * + * @param cancelLeaveId 销假信息id + * @param createId 创建人id + */ + private void calcUserStaffCancelLeaveMation(String cancelLeaveId, String createId) { + // 用户信息 + Map user = iAuthUserService.queryDataMationById(createId); + // 员工id + String staffId = user.get("staffId").toString(); + // 员工当前剩余年假 + String annualLeave = user.get("annualLeave").toString(); + // 员工当前剩余补休 + String holidayNumber = user.get("holidayNumber").toString(); + // 员工当前已休补休 + String retiredHolidayNumber = user.get("retiredHolidayNumber").toString(); + // 获取销假天数信息 + List cancelLeaveTimeSlotList = cancelLeaveTimeSlotService.selectByPId(cancelLeaveId); + for (CancelLeaveTimeSlot day : cancelLeaveTimeSlotList) { + String cancelLeaveTimeId = day.getId(); + String cancelDay = day.getCancelDay(); + String timeId = day.getTimeId(); + String cancelHour = day.getCancelHour(); + // 判断该员工在这一天是否有销假成功的记录,如果有,则审核失败,如果没有,则继续操作 + Map mation = skyeyeBaseMapper.queryCheckWorkCancelLeaveByMation(createId, cancelDay, FlowableChildStateEnum.ADEQUATE.getKey()); + if (CollectionUtil.isEmpty(mation)) { + // 判断该员工在这一天是否有请假记录,如果没有,则审核失败,如果有,则继续操作 + Map leaveDayMation = leaveService.queryCheckWorkLeaveByMation(createId, timeId, cancelDay); + if (leaveDayMation != null && !leaveDayMation.isEmpty()) { + Integer useYearHoliday = Integer.parseInt(leaveDayMation.get("useYearHoliday").toString()); + if (useYearHoliday.equals(UseYearHolidayType.USE_ANNUAL_LEAVE.getKey())) { + // 如果之前请假使用的是年假,则恢复年假 + annualLeave = CalculationUtil.add(annualLeave, cancelHour, CommonNumConstants.NUM_TWO); + } else if (useYearHoliday.equals(UseYearHolidayType.USE_COMPENSATORY_LEAVE.getKey())) { + // 如果之前请假使用的是补休,则恢复补休 + retiredHolidayNumber = CalculationUtil.subtract(retiredHolidayNumber, cancelHour, CommonNumConstants.NUM_TWO); + holidayNumber = CalculationUtil.add(holidayNumber, cancelHour, CommonNumConstants.NUM_TWO); + } + // 修改销假记录为成功 + cancelLeaveTimeSlotService.editStateById(cancelLeaveTimeId, FlowableChildStateEnum.ADEQUATE.getKey()); + continue; + } + } + cancelLeaveTimeSlotService.editStateById(cancelLeaveTimeId, FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + // 修改员工剩余年假信息 + UserStaffHolidayRest sysUserStaffHoliday = new UserStaffHolidayRest(); + sysUserStaffHoliday.setStaffId(staffId); + sysUserStaffHoliday.setQuarterYearHour(annualLeave); + sysUserStaffHoliday.setAnnualLeaveStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.editSysUserStaffAnnualLeaveById(sysUserStaffHoliday)).getBean(); + // 修改员工剩余补休信息 + sysUserStaffHoliday.setHolidayNumber(holidayNumber); + sysUserStaffHoliday.setHolidayStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.updateSysUserStaffHolidayNumberById(sysUserStaffHoliday)).getBean(); + // 修改员工已休补休信息 + sysUserStaffHoliday.setRetiredHolidayNumber(retiredHolidayNumber); + sysUserStaffHoliday.setRetiredHolidayStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.updateSysUserStaffRetiredHolidayNumberById(sysUserStaffHoliday)).getBean(); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveTimeSlotServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveTimeSlotServiceImpl.java new file mode 100644 index 0000000..91a3274 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/cancleleave/service/impl/CancelLeaveTimeSlotServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.cancleleave.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.cancleleave.dao.CancelLeaveTimeSlotDao; +import com.skyeye.cancleleave.entity.CancelLeaveTimeSlot; +import com.skyeye.cancleleave.service.CancelLeaveTimeSlotService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: CancelLeaveTimeSlotServiceImpl + * @Description: 销假申请销假时间段服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 14:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "销假时间段", groupName = "销假申请", manageShow = false) +public class CancelLeaveTimeSlotServiceImpl extends SkyeyeLinkDataServiceImpl implements CancelLeaveTimeSlotService { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/CheckTypeFrom.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/CheckTypeFrom.java new file mode 100644 index 0000000..83e727c --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/CheckTypeFrom.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ChectTypeFrom + * @Description: 考勤按钮的显示状态的类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CheckTypeFrom implements SkyeyeEnumClass { + + CHECT_BTN_FROM_TIMEID(1, "根据班次id计算考勤按钮的显示状态", false, false), + CHECT_BTN_FROM_OVERTIME(2, "根据加班日计算考勤按钮的显示状态", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockInTime.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockInTime.java new file mode 100644 index 0000000..0d5cdeb --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockInTime.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ClockInTime + * @Description: 上班打卡状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ClockInTime implements SkyeyeEnumClass { + + SYSTEM(0, "系统填充", true, false), + NORMAL(1, "正常", true, false), + LATE(2, "迟到", true, false), + NOTCLOCK(3, "未打卡", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getClockInState(Integer str) { + for (ClockInTime q : ClockInTime.values()) { + if (q.getKey().equals(str)) { + return q.getValue(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockOutTime.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockOutTime.java new file mode 100644 index 0000000..9f35d64 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockOutTime.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ClockOutTime + * @Description: 下班打卡状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ClockOutTime implements SkyeyeEnumClass { + + SYSTEM(0, "系统填充", true, false), + NORMAL(1, "正常", true, false), + EARLY(2, "早退", true, false), + NOTCLOCK(3, "未打卡", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getClockOutState(Integer str) { + for (ClockOutTime q : ClockOutTime.values()) { + if (q.getKey().equals(str)) { + return q.getValue(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockState.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockState.java new file mode 100644 index 0000000..c78355d --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/classenum/ClockState.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ClockState + * @Description: 考勤状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ClockState implements SkyeyeEnumClass { + + START(0, "早卡", true, false), + NORMAL(1, "全勤", true, false), + ABSENCE(2, "缺勤", true, false), + IN_SUFFICIENT(3, "工时不足", true, false), + NOT_START(4, "缺早卡", true, false), + NOT_END(5, "缺晚卡", true, false), + SYSTEM(6, "系统天空", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getClockState(Integer str) { + for (ClockState q : ClockState.values()) { + if (q.getKey().equals(str)) { + return q.getValue(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/controller/CheckWorkController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/controller/CheckWorkController.java new file mode 100644 index 0000000..ff90268 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/controller/CheckWorkController.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.checkwork.service.CheckWorkService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.centerrest.entity.checkwork.DayWork; +import com.skyeye.eve.centerrest.entity.checkwork.UserOtherDayMation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CheckWorkController + * @Description: 考勤打卡管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 15:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "考勤打卡管理", tags = "考勤打卡管理", modelName = "考勤打卡管理") +public class CheckWorkController { + + @Autowired + private CheckWorkService checkWorkService; + + /** + * 上班打卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork001", value = "上班打卡", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id", required = "required"), + @ApiImplicitParam(id = "longitude", name = "longitude", value = "经度"), + @ApiImplicitParam(id = "latitude", name = "latitude", value = "纬度"), + @ApiImplicitParam(id = "address", name = "address", value = "打卡的地址")}) + @RequestMapping("/post/CheckWorkController/insertCheckWorkStartWork") + public void insertCheckWorkStartWork(InputObject inputObject, OutputObject outputObject) { + checkWorkService.insertCheckWorkStartWork(inputObject, outputObject); + } + + /** + * 下班打卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork002", value = "下班打卡", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id", required = "required"), + @ApiImplicitParam(id = "longitude", name = "longitude", value = "经度"), + @ApiImplicitParam(id = "latitude", name = "latitude", value = "纬度"), + @ApiImplicitParam(id = "address", name = "address", value = "打卡的地址")}) + @RequestMapping("/post/CheckWorkController/editCheckWorkEndWork") + public void editCheckWorkEndWork(InputObject inputObject, OutputObject outputObject) { + checkWorkService.editCheckWorkEndWork(inputObject, outputObject); + } + + /** + * 查看我的考勤列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork003", value = "查看我的考勤列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CheckWorkController/queryCheckWorkList") + public void queryCheckWorkList(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryPageList(inputObject, outputObject); + } + + /** + * 当前登录用户可以进行申诉的打卡信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork004", value = "当前登录用户可以进行申诉的打卡信息列表", method = "GET", allUse = "2") + @RequestMapping("/post/CheckWorkController/queryCheckWorkIdByAppealType") + public void queryCheckWorkIdByAppealType(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryCheckWorkIdByAppealType(inputObject, outputObject); + } + + /** + * 判断显示打上班卡或者下班卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork013", value = "判断显示打上班卡或者下班卡", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id", required = "required")}) + @RequestMapping("/post/CheckWorkController/queryCheckWorkTimeToShowButton") + public void queryCheckWorkTimeToShowButton(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryCheckWorkTimeToShowButton(inputObject, outputObject); + } + + /** + * 根据月份查询当月的考勤信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork014", value = "根据月份查询当月的考勤信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id", required = "required"), + @ApiImplicitParam(id = "monthMation", name = "monthMation", value = "当前月上个年月", required = "required")}) + @RequestMapping("/post/CheckWorkController/queryCheckWorkMationByMonth") + public void queryCheckWorkMationByMonth(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryCheckWorkMationByMonth(inputObject, outputObject); + } + + /** + * 获取考勤报表数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork015", value = "获取考勤报表数据", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "limit", name = "limit", value = "分页参数,每页多少条数据", required = "required,num"), + @ApiImplicitParam(id = "page", name = "page", value = "分页参数,第几页", required = "required,num"), + @ApiImplicitParam(id = "userName", name = "userName", value = "员工姓名"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "起始时间", required = "required"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "最后时间", required = "required"), + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id")}) + @RequestMapping("/post/CheckWorkController/queryCheckWorkReport") + public void queryCheckWorkReport(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryCheckWorkReport(inputObject, outputObject); + } + + /** + * 获取考勤图表数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork016", value = "获取考勤报表数据", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userName", name = "userName", value = "员工姓名"), + @ApiImplicitParam(id = "arr", name = "arr", value = "时间数组", required = "required"), + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id")}) + @RequestMapping("/post/CheckWorkController/queryCheckWorkEcharts") + public void queryCheckWorkEcharts(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryCheckWorkEcharts(inputObject, outputObject); + } + + /** + * 获取表格数据详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkwork018", value = "获取表格数据详情信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userId", name = "userId", value = "用户id"), + @ApiImplicitParam(id = "state", name = "state", value = "状态"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "起始时间"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "最后时间"), + @ApiImplicitParam(id = "timeId", name = "timeId", value = "班次id"), + @ApiImplicitParam(id = "day", name = "day", value = "指定日期")}) + @RequestMapping("/post/CheckWorkController/queryReportDetail") + public void queryReportDetail(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryReportDetail(inputObject, outputObject); + } + + /** + * 获取指定天中的工作日 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDayWorkMation", value = "获取指定天中的工作日", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DayWork.class) + @RequestMapping("/post/CheckWorkController/queryDayWorkMation") + public void queryDayWorkMation(InputObject inputObject, OutputObject outputObject) { + checkWorkService.queryDayWorkMation(inputObject, outputObject); + } + + /** + * 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getUserOtherDayMation", value = "获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等)", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = UserOtherDayMation.class) + @RequestMapping("/post/CheckWorkController/getUserOtherDayMation") + public void getUserOtherDayMation(InputObject inputObject, OutputObject outputObject) { + checkWorkService.getUserOtherDayMation(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/dao/CheckWorkDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/dao/CheckWorkDao.java new file mode 100644 index 0000000..0b70a52 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/dao/CheckWorkDao.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.dao; + +import com.skyeye.checkwork.entity.CheckWork; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkDao + * @Description: 考勤打卡管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 15:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkDao extends SkyeyeBaseMapper { + + Map queryStartWorkTime(@Param("timeId") String timeId, @Param("staffId") String staffId); + + CheckWork queryisAlreadyCheck(@Param("checkDate") String checkDate, @Param("createId") String createId, + @Param("timeId") String timeId); + + List> queryCheckWorkList(CommonPageInfo pageInfo); + + /** + * 获取所有昨天没有打卡的用户 + * + * @param timeId 班次id + * @param yesterdayTime 日期信息,格式为:yyyy-MM-dd + * @return + */ + List> queryNotCheckMember(@Param("timeId") String timeId, @Param("yesterdayTime") String yesterdayTime); + + /** + * 新增打卡信息 + * + * @param listBeans + * @return + */ + int insertCheckWorkBySystem(List> listBeans); + + /** + * 获取所有昨天没有打下班卡的用户 + * + * @param timeId 班次id + * @param yesterdayTime 日期信息,格式为:yyyy-MM-dd + * @return + */ + List> queryNotCheckEndWorkId(@Param("timeId") String timeId, @Param("yesterdayTime") String yesterdayTime); + + /** + * 填充下班卡信息 + * + * @param item + * @return + */ + int editCheckWorkBySystem(Map item); + + List> queryCheckWorkIdByAppealType(Map map); + + /** + * 获取指定员工指定班次在指定月份的所有打卡信息 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 月份集合 + * @return + */ + List> queryCheckWorkMationByMonth(@Param("userId") String userId, + @Param("timeId") String timeId, @Param("months") List months); + + List> queryCheckWorkReport(Map map); + + Map queryCheckWorkEcharts(Map beans); + + List> queryReportDetail(Map map); + + /** + * 获取指定月份的假期(type=3) + * + * @param months 指定月,格式["2020-04", "2020-05"...] + * @return 指定月中的所有节假日 + */ + List> queryHolidayScheduleDayMation(@Param("list") List months); + + List> queryStaffCheckWorkTimeRelationByStaffId(@Param("staffId") String staffId); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/entity/CheckWork.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/entity/CheckWork.java new file mode 100644 index 0000000..6ee0265 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/entity/CheckWork.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.worktime.entity.CheckWorkTime; +import lombok.Data; + +/** + * @ClassName: CheckWork + * @Description: 考勤打卡实体类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/24 11:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "checkwork:check", cacheTime = RedisConstants.ONE_WEEK_SECONDS) +@TableName(value = "check_work", autoResultMap = true) +@ApiModel("考勤打卡实体类") +public class CheckWork extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @Property(value = "名称") + private String name; + + @TableField(value = "time_id") + @ApiModelProperty(value = "班次id", required = "required") + private String timeId; + + @TableField(exist = false) + @Property(value = "班次信息") + private CheckWorkTime timeMation; + + @TableField(value = "check_date") + @ApiModelProperty(value = "考勤日期 格式 :yyyy-mm-dd", required = "required") + private String checkDate; + + @TableField(value = "state") + @Property(value = "考勤状态,参考#ClockState") + private Integer state; + + @TableField(value = "clock_in") + @ApiModelProperty(value = "上班打卡时间 格式:hh:mm:ss") + private String clockIn; + + @TableField(value = "clock_in_state") + @ApiModelProperty(value = "上班打卡状态,参考#ClockInTime", required = "required,num") + private Integer clockInState; + + @TableField(value = "clock_out") + @ApiModelProperty(value = "下班打卡时间 格式:hh:mm:ss") + private String clockOut; + + @TableField(value = "clock_out_state") + @ApiModelProperty(value = "下班打卡状态,参考#ClockOutTime", required = "required,num") + private Integer clockOutState; + + @TableField(value = "work_hours") + @Property(value = "工时 格式:4:15:00") + private String workHours; + + @TableField(value = "clock_in_ip") + @ApiModelProperty(value = "上班打卡IP") + private String clockInIp; + + @TableField(value = "clock_out_ip") + @ApiModelProperty(value = "下班打卡IP") + private String clockOutIp; + + @TableField(value = "create_id") + @Property(value = "打卡人id") + private String createId; + + @TableField(exist = false) + @Property("创建人姓名") + private String createName; + + @TableField(value = "clock_in_longitude") + @ApiModelProperty(value = "上班打卡的经度") + private String clockInLongitude; + + @TableField(value = "clock_in_latitude") + @ApiModelProperty(value = "上班打卡的纬度") + private String clockInLatitude; + + @TableField(value = "clock_in_address") + @ApiModelProperty(value = "上班打卡的地址") + private String clockInAddress; + + @TableField(value = "clock_out_longitude") + @ApiModelProperty(value = "下班打卡的经度") + private String clockOutLongitude; + + @TableField(value = "clock_out_latitude") + @ApiModelProperty(value = "下班打卡的纬度") + private String clockOutLatitude; + + @TableField(value = "clock_out_address") + @ApiModelProperty(value = "下班打卡的地址") + private String clockOutAddress; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/CheckWorkService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/CheckWorkService.java new file mode 100644 index 0000000..0afa892 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/CheckWorkService.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.checkwork.entity.CheckWork; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkService + * @Description: 考勤打卡管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/6 15:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkService extends SkyeyeBusinessService { + + void insertCheckWorkStartWork(InputObject inputObject, OutputObject outputObject); + + void editCheckWorkEndWork(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkIdByAppealType(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkTimeToShowButton(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkMationByMonth(InputObject inputObject, OutputObject outputObject); + + void getUserOtherDayMation(InputObject inputObject, OutputObject outputObject); + + /** + * 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,格式["2020-04", "2020-05"...] + * @return + */ + List> getUserOtherDayMation(String userId, String timeId, List months); + + /** + * 获取节假日信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void queryDayWorkMation(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkReport(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkEcharts(InputObject inputObject, OutputObject outputObject); + + void queryReportDetail(InputObject inputObject, OutputObject outputObject); + + void queryDayWorkMation(List> beans, List months, String timeId); + + List> queryNotCheckMember(String timeId, String yesterdayTime); + + List> queryNotCheckEndWorkId(String timeId, String yesterdayTime); + + void editCheckWorkBySystem(Map map); + + List> queryCheckWorkOvertimeWaitSettlement(); + + void insertCheckWorkBySystem(List> beans); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/impl/CheckWorkServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/impl/CheckWorkServiceImpl.java new file mode 100644 index 0000000..4f505b0 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/checkwork/service/impl/CheckWorkServiceImpl.java @@ -0,0 +1,774 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.checkwork.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.checkwork.classenum.CheckTypeFrom; +import com.skyeye.checkwork.classenum.ClockInTime; +import com.skyeye.checkwork.classenum.ClockOutTime; +import com.skyeye.checkwork.classenum.ClockState; +import com.skyeye.checkwork.dao.CheckWorkDao; +import com.skyeye.checkwork.entity.CheckWork; +import com.skyeye.checkwork.service.CheckWorkService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.WeekTypeEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.constants.CheckWorkConstants; +import com.skyeye.eve.centerrest.entity.checkwork.DayWork; +import com.skyeye.eve.centerrest.entity.checkwork.UserOtherDayMation; +import com.skyeye.eve.service.IScheduleDayService; +import com.skyeye.exception.CustomException; +import com.skyeye.leave.service.LeaveService; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.overtime.dao.OvertimeDao; +import com.skyeye.overtime.service.OvertimeService; +import com.skyeye.trip.service.BusinessTripService; +import com.skyeye.worktime.classenum.CheckWorkTimeWeekType; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; +import com.skyeye.worktime.service.CheckWorkTimeService; +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 java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: CheckWorkServiceImpl + * @Description: 考勤打卡管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/24 11:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "考勤打卡管理", groupName = "考勤打卡管理") +public class CheckWorkServiceImpl extends SkyeyeBusinessServiceImpl implements CheckWorkService { + + private static Logger LOGGER = LoggerFactory.getLogger(CheckWorkServiceImpl.class); + + @Autowired + private CheckWorkDao checkWorkDao; + + @Autowired + private BusinessTripService checkWorkBusinessTripService; + + @Autowired + private LeaveService checkWorkLeaveService; + + @Autowired + private OvertimeService checkWorkOvertimeService; + + @Autowired + private OvertimeDao checkWorkOvertimeDao; + + @Autowired + private IScheduleDayService iScheduleDayService; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + /** + * 上班打卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertCheckWorkStartWork(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String timeId = map.get("timeId").toString(); + String staffId = user.get("staffId").toString(); + String userId = user.get("id").toString(); + String todayYMD = DateUtil.getYmdTimeAndToString(); + // 1.获取当前用户的考勤班次信息 + Map workTime = getWorkTime(userId, todayYMD, timeId, staffId); + // 2.获取今天的打卡记录 + String checkInTime = DateUtil.getHmsTimeAndToString(); + CheckWork todayCheckWork = checkWorkDao.queryisAlreadyCheck(DateUtil.getYmdTimeAndToString(), userId, timeId); + if (ObjectUtil.isEmpty(todayCheckWork) && DateUtil.compareTimeHMS(checkInTime, workTime.get("clockOut").toString())) { + // 今日没有打卡,且没有到下班时间,可以进行打卡 + CheckWork checkWork = new CheckWork(); + checkWork.setCheckDate(DateUtil.getYmdTimeAndToString()); + checkWork.setCreateId(userId); + checkWork.setTimeId(timeId); + checkWork.setState(ClockState.START.getKey()); + if (DateUtil.compareTimeHMS(checkInTime, workTime.get("clockIn").toString())) { + // 当前打卡时间是否早于上班时间,视为正常 + checkWork.setClockInState(ClockInTime.NORMAL.getKey()); + } else { + // 迟到 + checkWork.setClockInState(ClockInTime.LATE.getKey()); + } + checkWork.setClockIn(checkInTime); + checkWork.setClockInIp(ToolUtil.getIpByRequest(PutObject.getRequest())); + + String longitude = map.get("longitude").toString(); + String latitude = map.get("latitude").toString(); + String address = map.get("address").toString(); + checkWork.setClockInLongitude(longitude); + checkWork.setClockInLatitude(latitude); + checkWork.setClockInAddress(address); + + createEntity(checkWork, userId); + } else if (ObjectUtil.isNotEmpty(todayCheckWork) && ToolUtil.isBlank(todayCheckWork.getClockOut())) { + // 今日已经打过晚卡,不能打早卡 + outputObject.setreturnMessage("今日已经打过晚卡,现在不能打早卡!"); + } else if (!DateUtil.compareTimeHMS(checkInTime, workTime.get("clockOut").toString())) { + // 今日没有打卡,已是下班时间,不能进行打卡 + outputObject.setreturnMessage("今日打早卡时间已过,不能进行打卡!"); + } else { + outputObject.setreturnMessage("今日早卡已打过卡,请不要重复打卡!"); + } + } + + /** + * 获取指定员工指定班次的考勤信息 + * + * @param timeId 班次id + * @param staffId 员工id + * @return 该班次的上下班时间,时间格式为HH:mm:ss + */ + private Map getWorkTimeByUserMation(String timeId, String staffId) { + // 1.获取指定班次的上下班时间 + Map bean = checkWorkDao.queryStartWorkTime(timeId, staffId); + if (CollectionUtil.isEmpty(bean)) { + // 您不具备该班次的考勤权限 + throw new CustomException("You do not have the attendance authority for this shift."); + } + bean.put("clockIn", bean.get("clockIn").toString() + ":00"); + bean.put("clockOut", bean.get("clockOut").toString() + ":00"); + return bean; + } + + /** + * 下班打卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editCheckWorkEndWork(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String timeId = map.get("timeId").toString(); + String staffId = user.get("staffId").toString(); + String userId = user.get("id").toString(); + String todayYMD = DateUtil.getYmdTimeAndToString(); + // 1.获取当前用户的考勤班次信息 + Map workTime = getWorkTime(userId, todayYMD, timeId, staffId); + // 2.获取今天的打卡记录 + CheckWork todayCheckWork = checkWorkDao.queryisAlreadyCheck(DateUtil.getYmdTimeAndToString(), userId, timeId); + CheckWork checkWork = new CheckWork(); + checkWork.setCheckDate(DateUtil.getYmdTimeAndToString()); + checkWork.setCreateId(userId); + checkWork.setTimeId(timeId); + + String longitude = map.get("longitude").toString(); + String latitude = map.get("latitude").toString(); + String address = map.get("address").toString(); + + if (ObjectUtil.isEmpty(todayCheckWork)) { + // 早卡晚卡都没有打,可以打晚卡【缺早卡】【上班打卡状态-未打卡】 + checkWork.setClockOut(DateUtil.getHmsTimeAndToString()); + checkWork.setState(ClockState.NOT_START.getKey()); + checkWork.setClockInState(ClockInTime.NOTCLOCK.getKey()); + if (DateUtil.compareTimeHMS(checkWork.getClockOut(), workTime.get("clockOut").toString())) { + // 当前打卡时间是否早于下班时间,视为早退 + checkWork.setClockOutState(ClockOutTime.EARLY.getKey()); + } else { + // 正常 + checkWork.setClockOutState(ClockOutTime.NORMAL.getKey()); + } + checkWork.setWorkHours(String.valueOf(CommonNumConstants.NUM_ZERO)); + String ip = ToolUtil.getIpByRequest(PutObject.getRequest()); + checkWork.setClockInIp(ip); + checkWork.setClockOutIp(ip); + checkWork.setClockInLongitude(longitude); + checkWork.setClockInLatitude(latitude); + checkWork.setClockInAddress(address); + createEntity(checkWork, userId); + } else if (!ToolUtil.isBlank(todayCheckWork.getClockIn())) { + // 打过早卡,没有打晚卡 + checkWork.setClockOut(DateUtil.getHmsTimeAndToString()); + // 系统设置的上班时长 + String a = DateUtil.getDistanceHMS(workTime.get("clockOut").toString(), workTime.get("clockIn").toString()); + // 用户的上班时长 + String b = DateUtil.getDistanceHMS(checkWork.getClockOut(), todayCheckWork.getClockIn()); + // 当前打卡时间是否早于下班时间 + if (DateUtil.compareTimeHMS(a, b)) { + // 全勤 + checkWork.setState(ClockState.NORMAL.getKey()); + } else { + // 工时不足 + checkWork.setState(ClockState.IN_SUFFICIENT.getKey()); + } + if (DateUtil.compareTimeHMS(checkWork.getClockOut(), workTime.get("clockOut").toString())) { + // 早退 + checkWork.setClockOutState(ClockOutTime.EARLY.getKey()); + } else { + // 正常 + checkWork.setClockOutState(ClockOutTime.NORMAL.getKey()); + } + checkWork.setWorkHours(b); + checkWork.setClockOutIp(ToolUtil.getIpByRequest(PutObject.getRequest())); + checkWork.setId(todayCheckWork.getId()); + checkWork.setClockOutLongitude(longitude); + checkWork.setClockOutLatitude(latitude); + checkWork.setClockOutAddress(address); + updateEntity(checkWork, userId); + } else { + // 已经打过晚卡 + outputObject.setreturnMessage("今日已打过晚卡,请不要重复打卡!"); + } + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + pageInfo.setState(FlowableStateEnum.PASS.getKey()); + List> beans = skyeyeBaseMapper.queryCheckWorkList(pageInfo); + checkWorkTimeService.setMationForMap(beans, "timeId", "timeMation"); + return beans; + } + + @Override + public CheckWork selectById(String id) { + CheckWork checkWork = super.selectById(id); + checkWorkTimeService.setDataMation(checkWork, CheckWork::getTimeId); + if (ObjectUtil.isNotEmpty(checkWork.getTimeMation())) { + checkWork.setName(checkWork.getCheckDate() + ";班次[" + checkWork.getTimeMation().getName() + "];" + "考勤[" + ClockState.getClockState(checkWork.getState()) + "]"); + } else { + checkWork.setName(checkWork.getCheckDate() + ";考勤[" + ClockState.getClockState(checkWork.getState()) + "]"); + } + return checkWork; + } + + /** + * 当前登录用户可以进行申诉的打卡信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkIdByAppealType(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + List> beans = checkWorkDao.queryCheckWorkIdByAppealType(map); + checkWorkTimeService.setMationForMap(beans, "timeId", "timeMation"); + for (Map bean : beans) { + Integer state = Integer.parseInt(bean.get("state").toString()); + Map timeMation = (Map) bean.get("timeMation"); + if (CollectionUtil.isNotEmpty(timeMation)) { + bean.put("name", bean.get("name").toString() + ";班次[" + timeMation.get("name").toString() + "];" + "考勤[" + ClockState.getClockState(state) + "]"); + } else { + bean.put("name", bean.get("name").toString() + ";考勤[" + ClockState.getClockState(state) + "]"); + } + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 判断显示打上班卡或者下班卡 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkTimeToShowButton(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String today = DateUtil.getYmdTimeAndToString(); + String userId = user.get("id").toString(); + String timeId = map.get("timeId").toString(); + String staffId = user.get("staffId").toString(); + String nowTimeHMS = DateUtil.getHmsTimeAndToString(); + // 1.获取当前用户的考勤班次信息 + Map workTime = getWorkTime(userId, today, timeId, staffId); + if (Integer.parseInt(workTime.get("type").toString()) == CheckTypeFrom.CHECT_BTN_FROM_OVERTIME.getKey()) { + timeId = "-"; + } + // 2.判断显示打上班卡或者下班卡 + Map result = getChectBtn(today, userId, timeId, workTime, nowTimeHMS); + outputObject.setBean(result); + } + + /** + * 获取当前用户的考勤班次信息 + * + * @param userId 用户id + * @param today 指定日期,格式为yyyy-MM-dd(一般为今天的日期) + * @param timeId 班次id + * @param staffId 员工id + * @return + */ + private Map getWorkTime(String userId, String today, String timeId, String staffId) { + Map workTime; + // 判断今天是否是加班日 + List> overTimeMation = checkWorkOvertimeDao.queryPassThisDayAndCreateId(userId, today, FlowableChildStateEnum.ADEQUATE.getKey()); + if (CollectionUtil.isNotEmpty(overTimeMation)) { + // 根据加班日判断显示打上班卡或者下班卡 + workTime = overTimeMation.get(0); + workTime.put("clockIn", workTime.get("clockIn").toString() + ":00"); + workTime.put("clockOut", workTime.get("clockOut").toString() + ":00"); + workTime.put("type", CheckTypeFrom.CHECT_BTN_FROM_OVERTIME.getKey()); + } else { + // 根据考勤班次判断显示打上班卡或者下班卡 + workTime = getWorkTimeByUserMation(timeId, staffId); + workTime.put("type", CheckTypeFrom.CHECT_BTN_FROM_TIMEID.getKey()); + } + return workTime; + } + + /** + * 判断显示打上班卡或者下班卡 + * + * @param today 指定日期,格式为yyyy-MM-dd(一般为今天的日期) + * @param userId 用户id + * @param timeId 班次id + * @param workTime 考勤班次信息 + * @param nowTimeHMS 指定日期,格式为HH:mm:ss(一般为当前时间) + * @return + */ + private Map getChectBtn(String today, String userId, String timeId, Map workTime, String nowTimeHMS) { + // 获取今天的打卡记录 + CheckWork todayCheckWork = checkWorkDao.queryisAlreadyCheck(today, userId, timeId); + Integer checkState = getCheckState(todayCheckWork, nowTimeHMS, workTime, today); + Map result = new HashMap<>(); + result.put("isCheck", checkState); + result.putAll(workTime); + if (ObjectUtil.isNotEmpty(todayCheckWork)) { + result.put("realClockIn", todayCheckWork.getClockIn()); + result.put("realClockOut", todayCheckWork.getClockOut()); + } + return result; + } + + /** + * 获取指定日期在规定班次内的打卡状态 + * + * @param todayCheckWork 今日打卡信息 + * @param nowTimeHMS 指定日期,格式为HH:mm:ss + * @param workTime 班次考勤信息 + * @param today 指定日期,格式为yyyy-MM-dd(一般为今天的日期) + * @return + */ + private Integer getCheckState(CheckWork todayCheckWork, String nowTimeHMS, Map workTime, String today) { + Integer checkState = null; + if (Integer.parseInt(workTime.get("type").toString()) == CheckTypeFrom.CHECT_BTN_FROM_TIMEID.getKey()) { + boolean result = iScheduleDayService.judgeISHoliday(today); + if (result) { + // 今天不是加班日,但是是节假日,则不显示按钮 + checkState = 5; + return checkState; + } + } + if (ObjectUtil.isEmpty(todayCheckWork) && DateUtil.compareTimeHMS(nowTimeHMS, workTime.get("clockOut").toString())) { + // 今日没有打卡,且没有到下班时间,显示早卡按钮 + checkState = 1; + } else if (ObjectUtil.isEmpty(todayCheckWork) && !DateUtil.compareTimeHMS(nowTimeHMS, workTime.get("clockOut").toString())) { + // 今日没有打卡,已是下班时间,不显示按钮 + checkState = 3; + } else if (!ToolUtil.isBlank(todayCheckWork.getClockIn()) && ToolUtil.isBlank(todayCheckWork.getClockOut())) { + // 今日打过早卡没打晚卡,显示晚卡按钮 + checkState = 2; + } else if (!ToolUtil.isBlank(todayCheckWork.getClockIn()) && !ToolUtil.isBlank(todayCheckWork.getClockOut())) { + // 今日打过早卡打过晚卡,不显示按钮 + checkState = 4; + } + return checkState; + } + + /** + * 根据月份查询当月的考勤信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkMationByMonth(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String yearMonth = map.get("monthMation").toString(); + String timeId = map.get("timeId").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + List months = DateUtil.getPointMonthAfterMonthList(yearMonth, 2); + LOGGER.info("需要查询的月份信息:{}", months); + List> beans = checkWorkDao.queryCheckWorkMationByMonth(userId, timeId, months); + beans.forEach(bean -> { + if ("-".equals(bean.get("timeId").toString())) { + // 加班日的打卡信息 + bean.put("title", String.format(Locale.ROOT, "(%s) %s", "加班", bean.get("title").toString())); + } + }); + // 1.判断节假日信息 + queryDayWorkMation(beans, months, timeId); + // 2.获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + beans.addAll(getUserOtherDayMation(userId, timeId, months)); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getUserOtherDayMation(InputObject inputObject, OutputObject outputObject) { + UserOtherDayMation userOtherDayMation = inputObject.getParams(UserOtherDayMation.class); + List> beans = this.getUserOtherDayMation(userOtherDayMation.getUserId(), userOtherDayMation.getTimeId(), userOtherDayMation.getMonths()); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等) + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,格式["2020-04", "2020-05"...] + * @return + */ + @Override + public List> getUserOtherDayMation(String userId, String timeId, List months) { + List> beans = new ArrayList<>(); + // 1.获取审核通过的出差信息 + List> businessTripDay = checkWorkBusinessTripService.queryStateIsSuccessBusinessTripDayByUserIdAndMonths(userId, timeId, months); + beans.addAll(businessTripDay); + // 2.获取审核通过的加班信息 + List> workOvertimeDay = checkWorkOvertimeService.queryStateIsSuccessWorkOvertimeDayByUserIdAndMonths(userId, months); + beans.addAll(workOvertimeDay); + // 3.获取审核通过的请假信息 + List> leaveDay = checkWorkLeaveService.queryStateIsSuccessLeaveDayByUserIdAndMonths(userId, timeId, months); + beans.addAll(leaveDay); + return beans; + } + + @Override + public void queryDayWorkMation(InputObject inputObject, OutputObject outputObject) { + DayWork dayWorkMation = inputObject.getParams(DayWork.class); + List> beans = dayWorkMation.getBeans(); + this.queryDayWorkMation(beans, dayWorkMation.getMonths(), dayWorkMation.getTimeId()); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void queryDayWorkMation(List> beans, List months, String timeId) { + // 获取指定月份的节假日(type=3) + List> holiday = checkWorkDao.queryHolidayScheduleDayMation(months); + beans.addAll(holiday); + // 开始计算上班日期 + calcWorkTime(beans, months, timeId); + // 将节假日时间段转化为每一天 + calcHolidayPartToDay(beans); + } + + /** + * 将节假日时间段转化为每一天 + * + * @param beans 返回前台的参数 + */ + private void calcHolidayPartToDay(List> beans) { + List> newList = new ArrayList<>(); + for (int i = 0; i < beans.size(); i++) { + if (CheckDayType.DAY_IS_HOLIDAY.getKey().equals(beans.get(i).get("type").toString())) { + // 节假日 + List days = DateUtil.getDays(beans.get(i).get("start").toString(), beans.get(i).get("end").toString()); + if (days.size() > 1) { + for (String day : days) { + newList.add(CheckWorkConstants.structureRestMation(day, beans.get(i).get("title").toString())); + } + beans.remove(i); + // 索引减1,否则会报java.util.ConcurrentModificationException + i--; + } + } + } + beans.addAll(newList); + } + + /** + * 计算上班日期 + * + * @param beans 返回前台的参数(type=3--节假日) + * @param months 指定月 + * @param timeId 班次id + */ + private void calcWorkTime(List> beans, List months, String timeId) { + List monthDays = DateUtil.getDaysByMonths(months); + CheckWorkTime checkWorkTime = checkWorkTimeService.selectById(timeId); + LOGGER.info("获取指定班次中的工作日信息,{}", checkWorkTime.getCheckWorkTimeWeekList()); + for (String day : monthDays) { + // 判断该日期在节假日类型中是否包含 + if (!inHolidayScheduleDay(day, beans)) { + // 如果该天不是节假日 + int weekDay = DateUtil.getWeek(day); + int weekType = DateUtil.getWeekType(day); + CheckWorkTimeWeek simpleDay = checkWorkTime.getCheckWorkTimeWeekList() + .stream().filter(item -> item.getWeekNumber() == weekDay).findFirst().orElse(null); + if (ObjectUtil.isEmpty(simpleDay)) { + continue; + } + // 如果今天是需要考勤的日期 + if (weekType == WeekTypeEnum.BIWEEKLY.getKey() && simpleDay.getType().equals(CheckWorkTimeWeekType.SINGLE_DAY.getKey())) { + // 如果获取到的日期是双周,但考勤班次里面是单周,则不做任何操作 + } else { + // 单周或者每周的当天都上班 + beans.add(CheckWorkConstants.structureWorkMation(day)); + continue; + } + beans.add(CheckWorkConstants.structureRestMation(day, "")); + } + } + } + + /** + * 判断指定日期是否属于节假日 + * + * @param day 指定日期,格式为yyyy-MM-dd + * @param beans 包含节假日信息的集合 + * @return true:是节假日,false:不是节假日 + */ + private boolean inHolidayScheduleDay(String day, List> beans) { + List> fillter = beans.stream().filter(bean -> { + // 节假日类型 + if (CheckDayType.DAY_IS_HOLIDAY.getKey().equals(bean.get("type").toString())) { + return DateUtil.compare(bean.get("start").toString(), day + " 00:00:01") && DateUtil.compare(day + " 00:00:01", bean.get("end").toString()); + } + return false; + }).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(fillter)) { + return false; + } + return true; + } + + /** + * 获取考勤报表数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkReport(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 1.获取所有的考勤班次在指定日期内需要上班多少天 + Map timeWorkDay = getAllCheckWorkTime(map.get("startTime").toString(), map.get("endTime").toString()); + // 2.分页获取员工考勤信息 + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = checkWorkDao.queryCheckWorkReport(map); + iCompanyService.setNameForMap(beans, "companyId", "companyName"); + iDepmentService.setNameForMap(beans, "departmentId", "departmentName"); + iCompanyJobService.setNameForMap(beans, "jobId", "jobName"); + setShouldTime(beans, timeWorkDay); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + private void setShouldTime(List> beans, Map timeWorkDay) { + for (Map bean : beans) { + String[] timsIds = bean.get("timsIds").toString().split(","); + // 该员工在指定日期范围内应该上班的天数 + Integer shouldTime = 0; + for (String timeId : timsIds) { + if (!ToolUtil.isBlank(timeId)) { + shouldTime += timeWorkDay.get(timeId) == null ? 0 : timeWorkDay.get(timeId); + } + } + bean.put("shouldTime", shouldTime); + } + } + + /** + * 获取所有的考勤班次在指定日期内需要上班多少天 + * + * @param startTime 开始日期 + * @param endTime 结束日期 + * @return key:考勤班次id,value:指定日期内需要上班的天数 + */ + private Map getAllCheckWorkTime(String startTime, String endTime) { + List workTime = checkWorkTimeService.queryAllData(); + Map timeWorkDay = new HashMap<>(); + for (CheckWorkTime bean : workTime) { + timeWorkDay.put(bean.getId(), 0); + } + // 1.获取范围内的所有日期 + List days = DateUtil.getDays(startTime, endTime); + for (String day : days) { + boolean result = iScheduleDayService.judgeISHoliday(day); + if (result) { + // 如果是法定节假日,则不参与计算 + continue; + } + // 判断日期是周几 + int weekDay = DateUtil.getWeek(day); + // 判断日期是单周还是双周 + int weekType = DateUtil.getWeekType(day); + for (String timeId : timeWorkDay.keySet()) { + if (getTimeWhetherWork(timeId, weekDay, weekType, workTime)) { + timeWorkDay.put(timeId, (timeWorkDay.get(timeId) + 1)); + } + } + } + return timeWorkDay; + } + + /** + * 判断该周天在指定班次是否是上班日 + * + * @param timeId 班次id + * @param weekDay 周几 + * @param weekType 是单周还是双周 + * @param workTime 班次信息 + * @return + */ + private boolean getTimeWhetherWork(String timeId, int weekDay, int weekType, List workTime) { + CheckWorkTime timeMation = workTime.stream().filter(item -> item.getId().equals(timeId)).findFirst().orElse(null); + if (ObjectUtil.isEmpty(timeMation) || CollectionUtil.isEmpty(timeMation.getCheckWorkTimeWeekList())) { + return false; + } + CheckWorkTimeWeek simpleDay = timeMation.getCheckWorkTimeWeekList().stream().filter(item -> item.getWeekNumber() == weekDay).findFirst().orElse(null); + if (ObjectUtil.isEmpty(simpleDay)) { + return false; + } + // 在该班次中找到了指定日期的上班时间 + if (weekType == WeekTypeEnum.ODD_WEEKS.getKey() && simpleDay.getType().equals(CheckWorkTimeWeekType.SINGLE_DAY.getKey())) { + // 该周天是单周并且该班次是单周上班 + return true; + } else if (weekType == WeekTypeEnum.BIWEEKLY.getKey() && simpleDay.getType().equals(CheckWorkTimeWeekType.SINGLE_DAY.getKey())) { + // 该周天是双周并且该班次是单周上班 + return false; + } else { + // 该周天是双周或者单周并且该班次是每周上班 + return true; + } + } + + /** + * 获取考勤图标数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkEcharts(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String arr = map.get("arr").toString(); + String[] dayarr = arr.split(","); + List> beans = new ArrayList<>(); + for (int i = 0, l = dayarr.length; i < l; i++) { + map.put("day", dayarr[i]); + Map bean = checkWorkDao.queryCheckWorkEcharts(map); + beans.add(bean); + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取表格数据详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryReportDetail(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = checkWorkDao.queryReportDetail(map); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取所有昨天没有打卡的用户 + * + * @param timeId 考勤班次 + * @param yesterdayTime 昨天的日期 + */ + @Override + public List> queryNotCheckMember(String timeId, String yesterdayTime) { + List> beans = checkWorkDao.queryNotCheckMember(timeId, yesterdayTime); + return beans; + } + + /** + * 获取所有昨天没有打下班卡的用户 + * + * @param timeId 考勤班次 + * @param yesterdayTime 昨天的日期 + */ + @Override + public List> queryNotCheckEndWorkId(String timeId, String yesterdayTime) { + List> beans = checkWorkDao.queryNotCheckEndWorkId(timeId, yesterdayTime); + return beans; + } + + /** + * 填充下班卡信息 + * + * @param map + */ + @Override + public void editCheckWorkBySystem(Map map) { + checkWorkDao.editCheckWorkBySystem(map); + } + + /** + * 获取所有待结算的加班数据 + * + * @return + */ + @Override + public List> queryCheckWorkOvertimeWaitSettlement() { + List> beans = checkWorkOvertimeDao.queryCheckWorkOvertimeWaitSettlement(FlowableChildStateEnum.ADEQUATE.getKey()); + return beans; + } + + /** + * 新增打卡信息(用于新增旷工的考勤信息) + * + * @param beans + */ + @Override + public void insertCheckWorkBySystem(List> beans) { + checkWorkDao.insertCheckWorkBySystem(beans); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/CheckWorkClock.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/CheckWorkClock.java new file mode 100644 index 0000000..626181f --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/CheckWorkClock.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.entity.checkwork; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: CheckWorkClock + * @Description: 考勤打卡实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 21:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("考勤打卡实体类") +public class CheckWorkClock implements Serializable { + + @ApiModelProperty(value = "考勤id", required = "required") + private String id; + + @ApiModelProperty(value = "状态", required = "required") + private String state; + + @ApiModelProperty(value = "下班打卡状态", required = "required") + private String clockOutState; + + @ApiModelProperty(value = "考勤工时", required = "required") + private String workHours; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/DayWork.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/DayWork.java new file mode 100644 index 0000000..3a99408 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/DayWork.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.entity.checkwork; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DayWorkMationParams + * @Description: 判断节假日信息的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 20:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("判断节假日信息的实体类") +public class DayWork implements Serializable { + + @ApiModelProperty(value = "月份里面的天") + private List> beans; + + @ApiModelProperty(value = "月份", required = "required") + private List months; + + @ApiModelProperty(value = "考勤班次id", required = "required") + private String timeId; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserOtherDayMation.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserOtherDayMation.java new file mode 100644 index 0000000..6941300 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserOtherDayMation.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.entity.checkwork; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: UserOtherDayMationParams + * @Description: 获取用户指定班次在指定月份的其他日期信息[审核通过的](例如 : 请假 , 出差 , 加班等)的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 21:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("获取用户指定班次在指定月份的其他日期信息[审核通过的](例如:请假,出差,加班等)的实体类") +public class UserOtherDayMation implements Serializable { + + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @ApiModelProperty(value = "考勤班次id", required = "required") + private String timeId; + + @ApiModelProperty(value = "月份", required = "required") + private List months; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserStaffHolidayRest.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserStaffHolidayRest.java new file mode 100644 index 0000000..3449a90 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/checkwork/UserStaffHolidayRest.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.entity.checkwork; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: UserStaffHolidayRest + * @Description: 员工假期信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 19:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("员工假期信息实体类") +public class UserStaffHolidayRest implements Serializable { + + @ApiModelProperty(value = "员工id", required = "required") + private String staffId; + + @ApiModelProperty(value = "年假,精确到6位", required = "required") + private String quarterYearHour; + + @ApiModelProperty(value = "员工剩余年假数据刷新日期", required = "required") + private String annualLeaveStatisTime; + + @ApiModelProperty(value = "当前员工剩余补休天数", required = "required") + private String holidayNumber; + + @ApiModelProperty(value = "员工剩余补休数据刷新日期", required = "required") + private String holidayStatisTime; + + @ApiModelProperty(value = "当前员工已休补休天数", required = "required") + private String retiredHolidayNumber; + + @ApiModelProperty(value = "员工已休补休数据刷新日期", required = "required") + private String retiredHolidayStatisTime; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/wages/WagesStaffWorkTimeMationRest.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/wages/WagesStaffWorkTimeMationRest.java new file mode 100644 index 0000000..7c5750e --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/entity/wages/WagesStaffWorkTimeMationRest.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.entity.wages; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.worktime.entity.CheckWorkTime; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: WagesStaffWorkTimeMation + * @Description: 获取应出勤的班次以及小时的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/17 18:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("获取应出勤的班次以及小时的实体类") +public class WagesStaffWorkTimeMationRest implements Serializable { + + @ApiModelProperty(value = "员工对应的考勤班次") + private List staffWorkTime; + + @ApiModelProperty(value = "指定年月,格式为yyyy-MM", required = "required") + private String lastMonthDate; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserService.java new file mode 100644 index 0000000..eb0eed2 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserService.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.user; + +import com.skyeye.common.client.ClientConfiguration; +import com.skyeye.eve.centerrest.entity.checkwork.UserStaffHolidayRest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: SysEveUserService + * @Description: 用户信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 14:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface SysEveUserService { + + /** + * 修改员工剩余年假信息 + * + * @param sysUserStaffHoliday 员工年假信息 + * @return 用户信息 + */ + @PostMapping("/editSysUserStaffAnnualLeaveById") + String editSysUserStaffAnnualLeaveById(UserStaffHolidayRest sysUserStaffHoliday); + + /** + * 修改员工的补休池剩余补休信息 + * + * @param sysUserStaffHoliday 员工年假信息 + * @return 用户信息 + */ + @PostMapping("/updateSysUserStaffHolidayNumberById") + String updateSysUserStaffHolidayNumberById(UserStaffHolidayRest sysUserStaffHoliday); + + /** + * 修改员工的补休池已休补休信息 + * + * @param sysUserStaffHoliday 员工年假信息 + * @return 用户信息 + */ + @PostMapping("/updateSysUserStaffRetiredHolidayNumberById") + String updateSysUserStaffRetiredHolidayNumberById(UserStaffHolidayRest sysUserStaffHoliday); + + /** + * 根据员工id获取该员工的考勤时间段 + * + * @param staffId 员工id + * @return + */ + @GetMapping("/queryStaffCheckWorkTimeRelationNameByStaffId") + String queryStaffCheckWorkTimeRelationNameByStaffId(@RequestParam("staffId") String staffId); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserStaffCapitalService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserStaffCapitalService.java new file mode 100644 index 0000000..fb760eb --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/user/SysEveUserStaffCapitalService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.user; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: SysEveUserStaffCapitalService + * @Description: 员工非工资型的额外资金结算池接口服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 22:27 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface SysEveUserStaffCapitalService { + + /** + * 新增员工待结算资金池信息 + * + * @param params 员工待结算资金池信息,包括:员工id(staffId),企业id(companyId),部门id(departmentId),指定年月(monthTime),格式为:yyyy-MM,该资金来源类型(type),金额(money) + * @return 用户信息 + */ + @PostMapping("/addMonthMoney2StaffCapital") + String addMonthMoney2StaffCapital(Map params); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/wages/WagesStaffMationService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/wages/WagesStaffMationService.java new file mode 100644 index 0000000..e82e0ed --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/centerrest/wages/WagesStaffMationService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.wages; + +import com.skyeye.common.client.ClientConfiguration; +import com.skyeye.eve.centerrest.entity.wages.WagesStaffWorkTimeMationRest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +/** + * @ClassName: WagesStaffMationService + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2022/8/7 22:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface WagesStaffMationService { + + /** + * 获取应出勤的班次以及小时 + * + * @param wagesStaffWorkTimeMationRest 获取应出勤的班次以及小时的实体类 + * @return + */ + @PostMapping("/setLastMonthBe") + String setLastMonthBe(WagesStaffWorkTimeMationRest wagesStaffWorkTimeMationRest); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CalcStaffWaitPayWages.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CalcStaffWaitPayWages.java new file mode 100644 index 0000000..5725832 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CalcStaffWaitPayWages.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.xxljob; + +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.WagesConstant; +import com.skyeye.common.enumeration.OvertimeSettlementType; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.eve.centerrest.entity.wages.WagesStaffWorkTimeMationRest; +import com.skyeye.eve.centerrest.user.SysEveUserStaffCapitalService; +import com.skyeye.eve.centerrest.wages.WagesStaffMationService; +import com.skyeye.checkwork.dao.CheckWorkDao; +import com.skyeye.checkwork.service.CheckWorkService; +import com.skyeye.overtime.classenum.OvertimeSoltSettleState; +import com.skyeye.overtime.service.OverTimeSlotService; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.service.CheckWorkTimeService; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CalcStaffWaitPayWages + * @Description: 定时统计员工待结算其他奖金的数据 + * 1. 加班结算 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/2 15:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class CalcStaffWaitPayWages { + + private static Logger log = LoggerFactory.getLogger(CalcStaffWaitPayWages.class); + + @Autowired + private CheckWorkService checkWorkService; + + @Autowired + private OverTimeSlotService overTimeSlotService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Autowired + private CheckWorkDao checkWorkDao; + + @Autowired + private WagesStaffMationService wagesStaffMationService; + + @Autowired + private SysEveUserStaffCapitalService sysEveUserStaffCapitalService; + + /** + * 定时统计员工待结算其他奖金的数据 凌晨一点半执行 + */ + @XxlJob("calcStaffWaitPayWages") + public void handler() { + log.info("定时统计员工待结算薪资的数据定时任务开始执行"); + try { + calcWaitWages(); + } catch (Exception e) { + log.warn("CalcStaffWaitPayWages error.", e); + } + log.info("定时统计员工待结算薪资的数据定时任务执行完成"); + } + + private void calcWaitWages() { + // 指定年月的考勤信息的缓存 + Map> pointMonthCheckWorkTimeCache = new HashMap<>(); + // 获取所有待结算的加班信息 + List> overTimeWaitSettlementList = checkWorkService.queryCheckWorkOvertimeWaitSettlement(); + log.info("overTimeWaitSettlementList size is: {}", overTimeWaitSettlementList.size()); + Map>> overTimeWaitSettlementByStaffId = overTimeWaitSettlementList.stream() + .collect(Collectors.groupingBy(map -> map.get("staffId").toString() + map.get("overtimeMonth").toString())); + for (Map.Entry>> entry : overTimeWaitSettlementByStaffId.entrySet()) { + List> overTimeList = entry.getValue(); + // 员工薪资 + String actWages = overTimeList.get(0).get("actWages").toString(); + String overtimeMonth = overTimeList.get(0).get("overtimeMonth").toString(); + String staffId = overTimeList.get(0).get("staffId").toString(); + String hourWages = getStaffHourWages(pointMonthCheckWorkTimeCache, actWages, overtimeMonth, staffId); + String resultMoney = getAllOverTimeMoneyThisMonth(overTimeList, hourWages); + + Map params = new HashMap<>(); + params.put("staffId", overTimeList.get(0).get("staffId").toString()); + params.put("companyId", overTimeList.get(0).get("companyId").toString()); + params.put("departmentId", overTimeList.get(0).get("departmentId").toString()); + params.put("monthTime", overtimeMonth); + params.put("type", 1); + params.put("money", resultMoney); + sysEveUserStaffCapitalService.addMonthMoney2StaffCapital(params); + } + } + + private String getAllOverTimeMoneyThisMonth(List> overTimeList, String hourWages) { + String allOverTimeHourThisMonth = "0"; + for (Map bean : overTimeList) { + // 加班工时 + String overtimeHour = bean.get("overtimeHour").toString(); + // 结算类型 + int overtimeSettlementType = Integer.parseInt(bean.get("overtimeSettlementType").toString()); + String money = "0"; + if (overtimeSettlementType == OvertimeSettlementType.SINGLE_SALARY_SETTLEMENT.getKey()) { + // 单倍薪资结算 + money = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, overtimeHour, hourWages, "1"); + } else if (overtimeSettlementType == OvertimeSettlementType.ONE_POINT_FIVE_SALARY_SETTLEMENT.getKey()) { + // 1.5倍薪资结算 + money = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, overtimeHour, hourWages, "1.5"); + } else if (overtimeSettlementType == OvertimeSettlementType.DOUBLE_SALARY_SETTLEMENT.getKey()) { + // 双倍薪资结算 + money = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, overtimeHour, hourWages, "2"); + } + allOverTimeHourThisMonth = CalculationUtil.add(allOverTimeHourThisMonth, money, 2); + // 修改加班电子流的结算状态为已计入统计 + overTimeSlotService.editSettleStateById(bean.get("id").toString(), OvertimeSoltSettleState.RECORDED_IN_STATISTICS.getKey()); + } + return allOverTimeHourThisMonth; + } + + /** + * 获取员工每小时的工资 + * + * @param pointMonthCheckWorkTimeCache 指定年月的考勤信息的缓存 + * @param actWages 员工信息 + * @param overtimeMonth 加班年月,格式为:yyyy-MM + * @param staffId 员工id + * @return hourWages + */ + private String getStaffHourWages(Map> pointMonthCheckWorkTimeCache, String actWages, + String overtimeMonth, String staffId) { + // 考勤日期 + List workTime = getPointMonthCheckWorkTime(pointMonthCheckWorkTimeCache, overtimeMonth); + // 1.获取该员工拥有的考勤班次id集合 + List> staffTimeIdMation = checkWorkDao.queryStaffCheckWorkTimeRelationByStaffId(staffId); + List userTimeIds = staffTimeIdMation.stream() + .map(p -> p.get("timeId").toString()).collect(Collectors.toList()); + List staffWorkTime = workTime.stream() + .filter(bean -> userTimeIds.contains(bean.getId())) + .collect(Collectors.toList()); + // 2.获取应出勤的班次以及小时 + WagesStaffWorkTimeMationRest wagesStaffWorkTimeMationRest = new WagesStaffWorkTimeMationRest(); + wagesStaffWorkTimeMationRest.setStaffWorkTime(staffWorkTime); + wagesStaffWorkTimeMationRest.setLastMonthDate(overtimeMonth); + Map staffModelFieldMap = + ExecuteFeignClient.get(() -> wagesStaffMationService.setLastMonthBe(wagesStaffWorkTimeMationRest)).getBean(); + // 获取每小时的工资 + String hourWages = CalculationUtil.divide(actWages, + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()).toString(), 2); + return hourWages; + } + + private List getPointMonthCheckWorkTime(Map> cache, String pointMonthDate) { + if (cache.containsKey(pointMonthDate)) { + return cache.get(pointMonthDate); + } + // 所有的考勤班次信息 + List workTime = checkWorkTimeService.getAllCheckWorkTime(pointMonthDate); + cache.put(pointMonthDate, workTime); + return workTime; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CheckWorkQuartz.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CheckWorkQuartz.java new file mode 100644 index 0000000..6d0e3d0 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/eve/xxljob/CheckWorkQuartz.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.xxljob; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.enumeration.WeekTypeEnum; +import com.skyeye.common.util.DateAfterSpacePointTime; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.checkwork.service.CheckWorkService; +import com.skyeye.eve.service.IScheduleDayService; +import com.skyeye.leave.service.LeaveService; +import com.skyeye.worktime.classenum.CheckWorkTimeWeekType; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; +import com.skyeye.worktime.service.CheckWorkTimeService; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkQuartz + * @Description: 定时器填充打卡信息, 每天凌晨一点执行一次 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/25 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class CheckWorkQuartz { + + private static Logger log = LoggerFactory.getLogger(CheckWorkQuartz.class); + + @Autowired + private CheckWorkService checkWorkService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Autowired + private LeaveService checkWorkLeaveService; + + @Autowired + private IScheduleDayService iScheduleDayService; + + /** + * 定时器填充打卡信息,每天凌晨一点执行一次 + */ + @XxlJob("checkWorkQuartz") + public void editCheckWorkMation() { + log.info("填充打卡信息定时任务执行"); + try { + // 1.获取所有的考勤班次信息 + List workTime = checkWorkTimeService.queryAllData(); + // 得到昨天的时间 + String yesterdayTime = DateAfterSpacePointTime.getSpecifiedTime( + DateAfterSpacePointTime.ONE_DAY.getType(), DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD, DateAfterSpacePointTime.AroundType.BEFORE); + if (workTime != null && !workTime.isEmpty() && !iScheduleDayService.judgeISHoliday(yesterdayTime)) { + // 班次信息不为空,并且昨天不是节假日 + log.info("Fill in the clocking information for timing task execution time is {}", yesterdayTime); + // 判断昨天的日期是周几 + int weekDay = DateUtil.getWeek(yesterdayTime); + // 判断昨天的日期是单周还是双周 + int weekType = DateUtil.getWeekType(yesterdayTime); + // 2.获取昨天应该打卡的班次信息 + List shouldCheckTime = getShouldCheckTime(weekDay, weekType, workTime); + if (!shouldCheckTime.isEmpty()) { + shouldCheckTime.forEach(bean -> { + try { + // 3.1 处理所有昨天只打早卡没有打晚卡的记录id + handleNotCheckWorkEndMember(yesterdayTime, bean.getId()); + // 3.2 处理所有昨天没有打卡的用户 + handleNotCheckWorkMember(yesterdayTime, bean.getId()); + } catch (Exception e) { + log.info("Handling abnormal attendance information, message is {}.", e); + } + }); + } + } + // 4 处理所有昨天加班只打早卡没有打晚卡的记录id + handleNotCheckWorkEndMember(yesterdayTime, "-"); + } catch (Exception e) { + log.warn("CheckWorkQuartz error.", e); + } + log.info("填充打卡信息定时任务 end"); + } + + /** + * 获取昨天应该打卡的班次信息 + * + * @param weekDay 周几 + * @param weekType 1是双周,0是单周 + * @param workTime 考勤班次 + * @return + */ + private List getShouldCheckTime(int weekDay, int weekType, List workTime) { + List shouldCheckTime = new ArrayList<>(); + for (CheckWorkTime bean : workTime) { + // 该班次中上班的天数 + List days = bean.getCheckWorkTimeWeekList(); + CheckWorkTimeWeek simpleDay = days.stream().filter(item -> item.getWeekNumber() == weekDay).findFirst().orElse(null); + if (ObjectUtil.isNotEmpty(simpleDay)) { + // 在该班次中找到了指定日期的上班时间 + if (weekType == WeekTypeEnum.ODD_WEEKS.getKey() && simpleDay.getType() == CheckWorkTimeWeekType.SINGLE_DAY.getKey()) { + // 单周 + shouldCheckTime.add(bean); + } else if (simpleDay.getType() == CheckWorkTimeWeekType.DAY.getKey()) { + shouldCheckTime.add(bean); + } + } + } + log.info("shouldCheckTime is {}", JSONUtil.toJsonStr(shouldCheckTime)); + return shouldCheckTime; + } + + /** + * 处理所有昨天只打早卡没有打晚卡的记录id + * + * @param yesterdayTime + * @param timeId + */ + private void handleNotCheckWorkEndMember(String yesterdayTime, String timeId) { + List> beans = checkWorkService.queryNotCheckEndWorkId(timeId, yesterdayTime); + if (!beans.isEmpty()) { + for (Map b : beans) { + Map checkWorkMation = new HashMap<>(); + checkWorkMation.put("id", b.get("id").toString()); + checkWorkMation.put("state", "5"); + checkWorkMation.put("clockOutState", "3"); + checkWorkMation.put("workHours", "0:0:0"); + // 填充打晚卡信息 + checkWorkService.editCheckWorkBySystem(checkWorkMation); + } + } + } + + /** + * 处理所有昨天没有打卡的用户 + * + * @param yesterdayTime 昨天的日期,格式为:yyyy-MM-dd + * @param timeId 班次id + */ + private void handleNotCheckWorkMember(String yesterdayTime, String timeId) { + // 获取所有昨天没有打卡的用户 + List> beans = checkWorkService.queryNotCheckMember(timeId, yesterdayTime); + if (CollectionUtil.isEmpty(beans)) { + return; + } + List> listBeans = new ArrayList<>(); + for (Map b : beans) { + String createId = b.get("createId").toString(); + // 判断昨天是否有请假记录,如果有,则不填充这条记录 + Map leaveMation = checkWorkLeaveService.queryCheckWorkLeaveByMation(timeId, createId, yesterdayTime); + if (CollectionUtil.isEmpty(leaveMation)) { + // 找不到该员工这个班次在这一天的请假记录,则记为旷工 + listBeans.add(getNoCheckWorkObject(timeId, createId, yesterdayTime)); + } + } + if (CollectionUtil.isNotEmpty(listBeans)) { + checkWorkService.insertCheckWorkBySystem(listBeans); + } + } + + private Map getNoCheckWorkObject(String timeId, String createId, String yesterdayTime) { + Map item = new HashMap<>(); + item.put("id", ToolUtil.getSurFaceId()); + item.put("createId", createId); + item.put("checkDate", yesterdayTime); + item.put("state", "2"); + item.put("clockInState", "3"); + item.put("clockOutState", "3"); + item.put("timeId", timeId); + item.put("workHours", "0:0:0"); + return item; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/classenum/UseYearHolidayType.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/classenum/UseYearHolidayType.java new file mode 100644 index 0000000..dd01737 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/classenum/UseYearHolidayType.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: UseYearHolidayType + * @Description: 请假是否使用年假/补休的类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UseYearHolidayType implements SkyeyeEnumClass { + + USE_ANNUAL_LEAVE(1, "使用年假", true, false), + USE_COMPENSATORY_LEAVE(2, "使用补休", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (UseYearHolidayType value : UseYearHolidayType.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/controller/LeaveController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/controller/LeaveController.java new file mode 100644 index 0000000..66d1c65 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/controller/LeaveController.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.leave.entity.Leave; +import com.skyeye.leave.service.LeaveService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LeaveController + * @Description: 请假申请控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/4 13:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "请假申请", tags = "请假申请", modelName = "请假申请") +public class LeaveController { + + @Autowired + private LeaveService leaveService; + + /** + * 获取我的请假申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkleave001", value = "获取我的请假申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LeaveController/queryLeaveList") + public void queryLeaveList(InputObject inputObject, OutputObject outputObject) { + leaveService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑请假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLeave", value = "新增/编辑请假申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Leave.class) + @RequestMapping("/post/LeaveController/writeLeave") + public void writeLeave(InputObject inputObject, OutputObject outputObject) { + leaveService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询请假申请信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLeaveById", value = "根据id查询请假申请信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LeaveController/queryLeaveById") + public void queryLeaveById(InputObject inputObject, OutputObject outputObject) { + leaveService.selectById(inputObject, outputObject); + } + + /** + * 请假申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkleave006", value = "请假申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/LeaveController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + leaveService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废请假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkleave007", value = "作废请假申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LeaveController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + leaveService.invalid(inputObject, outputObject); + } + + /** + * 撤销请假申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkleave009", value = "撤销请假申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/LeaveController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + leaveService.revoke(inputObject, outputObject); + } + + /** + * 获取基础设置中的请假类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getLeaveTypeList", value = "获取基础设置中的请假类型", method = "GET", allUse = "2") + @RequestMapping("/post/LeaveController/getLeaveTypeList") + public void getLeaveTypeList(InputObject inputObject, OutputObject outputObject) { + leaveService.getLeaveTypeList(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveDao.java new file mode 100644 index 0000000..bc932ad --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveDao.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.leave.entity.Leave; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LeaveDao + * @Description: 请假申请数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/1 17:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LeaveDao extends SkyeyeBaseMapper { + + List> queryMyCheckWorkLeaveList(CommonPageInfo pageInfo); + + /** + * 获取指定日期已经审核通过的信息 + * + * @param timeId 班次id + * @param createId 创建人 + * @param leaveDay 指定日期,格式为:yyyy-MM-dd + * @return + */ + Map queryCheckWorkLeaveByMation(@Param("timeId") String timeId, @Param("createId") String createId, @Param("leaveDay") String leaveDay); + + /** + * 获取指定员工在指定月份和班次的所有审核通过的请假申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + List> queryStateIsSuccessLeaveDayByUserIdAndMonths(@Param("userId") String userId, @Param("timeId") String timeId, + @Param("months") List months); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveTimeSlotDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveTimeSlotDao.java new file mode 100644 index 0000000..e5eac0f --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/dao/LeaveTimeSlotDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.leave.entity.LeaveTimeSlot; + +/** + * @ClassName: LeaveTimeSlotDao + * @Description: 请假申请请假时间段数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 8:41 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LeaveTimeSlotDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/Leave.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/Leave.java new file mode 100644 index 0000000..42f6356 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/Leave.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.leave.entity.LeaveTimeSlot; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Leave + * @Description: 请假申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:leave", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "check_work_leave", autoResultMap = true) +@ApiModel("请假申请实体类") +public class Leave extends SkyeyeFlowable { + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "请假时间段", required = "required,json") + private List leaveTimeSlotList; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/LeaveTimeSlot.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/LeaveTimeSlot.java new file mode 100644 index 0000000..7cc7543 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/entity/LeaveTimeSlot.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import com.skyeye.worktime.entity.CheckWorkTime; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: LeaveTimeSlot + * @Description: 请假申请请假时间段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "check_work_leave_time_slot", autoResultMap = true) +@ApiModel("请假申请请假时间段实体类") +public class LeaveTimeSlot extends SkyeyeLinkData { + + @TableField(value = "time_id") + @ApiModelProperty(value = "班次id", required = "required") + private String timeId; + + @TableField(exist = false) + @Property(value = "班次信息") + private CheckWorkTime timeMation; + + @TableField(value = "leave_type") + @ApiModelProperty(value = "请假类型", required = "required") + private String leaveType; + + @TableField(exist = false) + @Property(value = "请假类型信息") + private Map leaveTypeMation; + + @TableField(value = "leave_day") + @ApiModelProperty(value = "请假日期,格式:yyyy-MM-dd", required = "required") + private String leaveDay; + + @TableField(value = "leave_start_time") + @ApiModelProperty(value = "请假开始时间,格式:HH:mm:ss", required = "required") + private String leaveStartTime; + + @TableField(value = "leave_end_time") + @ApiModelProperty(value = "请假结束时间,格式:HH:mm:ss", required = "required") + private String leaveEndTime; + + @TableField(value = "leave_hour") + @ApiModelProperty(value = "请假工时", required = "required") + private String leaveHour; + + @TableField(value = "use_year_holiday") + @Property(value = "是否使用年假/补休,参考#UseYearHolidayType") + private Integer useYearHoliday; + + @TableField(exist = false) + @Property(value = "是否使用年假/补休的显示名称") + private String useYearHolidayName; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveService.java new file mode 100644 index 0000000..f3d9652 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.leave.entity.Leave; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: LeaveService + * @Description: 请假申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/4 13:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LeaveService extends SkyeyeFlowableService { + + /** + * 获取指定员工在指定月份和班次的所有审核通过的请假申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + List> queryStateIsSuccessLeaveDayByUserIdAndMonths(String userId, String timeId, List months); + + Map queryCheckWorkLeaveByMation(String timeId, String createId, String leaveDay); + + void getLeaveTypeList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveTimeSlotService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveTimeSlotService.java new file mode 100644 index 0000000..76d98e1 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/LeaveTimeSlotService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.leave.entity.LeaveTimeSlot; + +/** + * @ClassName: LeaveTimeSlotService + * @Description: 请假申请请假时间段服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 8:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LeaveTimeSlotService extends SkyeyeLinkDataService { + + void editStateById(String id, String state, Integer useYearHoliday); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveServiceImpl.java new file mode 100644 index 0000000..976f4c1 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveServiceImpl.java @@ -0,0 +1,300 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.centerrest.entity.checkwork.UserStaffHolidayRest; +import com.skyeye.eve.centerrest.user.SysEveUserService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.exception.CustomException; +import com.skyeye.leave.classenum.UseYearHolidayType; +import com.skyeye.leave.dao.LeaveDao; +import com.skyeye.leave.entity.Leave; +import com.skyeye.leave.entity.LeaveTimeSlot; +import com.skyeye.leave.service.LeaveService; +import com.skyeye.leave.service.LeaveTimeSlotService; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.service.CheckWorkTimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: LeaveServiceImpl + * @Description: 请假申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/14 13:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "请假申请", groupName = "请假申请", flowable = true) +public class LeaveServiceImpl extends SkyeyeFlowableServiceImpl implements LeaveService { + + @Autowired + private LeaveTimeSlotService leaveTimeSlotService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Autowired + private SysEveUserService sysEveUserService; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryMyCheckWorkLeaveList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(Leave entity) { + chectOrderItem(entity.getLeaveTimeSlotList()); + } + + @Override + public void writeChild(Leave entity, String userId) { + leaveTimeSlotService.saveLinkList(entity.getId(), entity.getLeaveTimeSlotList()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List leaveTimeSlots) { + List leaveDays = leaveTimeSlots.stream() + .map(bean -> String.format(Locale.ROOT, "%s-%s", bean.getTimeId(), bean.getLeaveDay())).distinct() + .collect(Collectors.toList()); + if (leaveTimeSlots.size() != leaveDays.size()) { + throw new CustomException("同一班次中不允许出现相同的请假日期"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + leaveTimeSlotService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public Leave getDataFromDb(String id) { + Leave leave = super.getDataFromDb(id); + List leaveTimeSlotList = leaveTimeSlotService.selectByPId(leave.getId()); + leave.setLeaveTimeSlotList(leaveTimeSlotList); + return leave; + } + + @Override + public Leave selectById(String id) { + Leave leave = super.selectById(id); + // 获取考勤班次信息 + List timeIds = leave.getLeaveTimeSlotList().stream() + .map(LeaveTimeSlot::getTimeId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(timeIds)) { + // 请假类型 + List> result = getLeaveTypeList(); + Map> leaveTypeMap = result.stream() + .collect(Collectors.toMap(bean -> bean.get("id").toString(), item -> item)); + // 考勤班次信息 + Map checkWorkTimeMap = checkWorkTimeService.selectMapByIds(timeIds); + leave.getLeaveTimeSlotList().forEach(leaveTimeSlot -> { + leaveTimeSlot.setStateName(FlowableChildStateEnum.getStateName(leaveTimeSlot.getState())); + leaveTimeSlot.setUseYearHolidayName(UseYearHolidayType.getShowName(leaveTimeSlot.getUseYearHoliday())); + leaveTimeSlot.setTimeMation(checkWorkTimeMap.get(leaveTimeSlot.getTimeId())); + leaveTimeSlot.setLeaveTypeMation(leaveTypeMap.get(leaveTimeSlot.getLeaveType())); + }); + } + + leave.setStateName(FlowableStateEnum.getStateName(leave.getState())); + iAuthUserService.setName(leave, "createId", "createName"); + return leave; + } + + @Override + public void revokePostpose(Leave entity) { + super.revokePostpose(entity); + leaveTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(Leave entity) { + calcUserStaffYearMation(entity.getId(), entity.getCreateId()); + } + + @Override + protected void approvalEndIsFailed(Leave entity) { + leaveTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + /** + * 计算请假中关联的年假信息,更新员工年假 + * + * @param leaveId 请假信息id + * @param createId 创建人id + */ + private void calcUserStaffYearMation(String leaveId, String createId) { + // 用户信息 + Map user = iAuthUserService.queryDataMationById(createId); + // 员工id + String staffId = user.get("staffId").toString(); + // 员工当前剩余年假 + String annualLeave = user.get("annualLeave").toString(); + // 员工当前剩余补休 + String holidayNumber = user.get("holidayNumber").toString(); + // 员工当前已休补休 + String retiredHolidayNumber = user.get("retiredHolidayNumber").toString(); + // 获取请假扣薪制度 + List> holidaysTypeMation = getSystemHolidaysTypeJsonMation(); + // 获取请假天数信息 + List leaveTimeSlotList = leaveTimeSlotService.selectByPId(leaveId); + for (LeaveTimeSlot day : leaveTimeSlotList) { + String leaveSoltId = day.getId(); + // 请假时长 + String leaveHour = day.getLeaveHour(); + // 假期类型 + String leaveType = day.getLeaveType(); + Map holiday = holidaysTypeMation.stream() + .filter(bean -> leaveType.equals(bean.get("holidayNo").toString())).findFirst().orElse(null); + if (CollectionUtil.isNotEmpty(holiday)) { + // 是否使用年假 + Integer whetherYearHour = Integer.parseInt(holiday.get("whetherYearHour").toString()); + // 是否使用补休 + Integer whetherComLeave = Integer.parseInt(holiday.get("whetherComLeave").toString()); + if (whetherYearHour.equals(WhetherEnum.ENABLE_USING.getKey())) { + if (annualLeave.equals(CalculationUtil.getMax(annualLeave, leaveHour, CommonNumConstants.NUM_TWO))) { + // 剩余年假够用 + annualLeave = CalculationUtil.subtract(annualLeave, leaveHour, CommonNumConstants.NUM_TWO); + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.ADEQUATE.getKey(), UseYearHolidayType.USE_ANNUAL_LEAVE.getKey()); + } else { + // 剩余年假不够用,则默认审核不通过 + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + continue; + } + if (whetherComLeave.equals(WhetherEnum.ENABLE_USING.getKey())) { + if (holidayNumber.equals(CalculationUtil.getMax(holidayNumber, leaveHour, CommonNumConstants.NUM_TWO))) { + // 剩余补休够用 + holidayNumber = CalculationUtil.subtract(holidayNumber, leaveHour, CommonNumConstants.NUM_TWO); + retiredHolidayNumber = CalculationUtil.add(retiredHolidayNumber, leaveHour, CommonNumConstants.NUM_TWO); + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.ADEQUATE.getKey(), UseYearHolidayType.USE_COMPENSATORY_LEAVE.getKey()); + } else { + // 剩余补休不够用,则默认审核不通过 + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + continue; + } + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.ADEQUATE.getKey()); + } else { + leaveTimeSlotService.editStateById(leaveSoltId, FlowableChildStateEnum.ADEQUATE.getKey()); + } + } + // 修改员工剩余年假信息 + UserStaffHolidayRest sysUserStaffHoliday = new UserStaffHolidayRest(); + sysUserStaffHoliday.setStaffId(staffId); + sysUserStaffHoliday.setQuarterYearHour(annualLeave); + sysUserStaffHoliday.setAnnualLeaveStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.editSysUserStaffAnnualLeaveById(sysUserStaffHoliday)).getBean(); + // 修改员工剩余补休信息 + sysUserStaffHoliday.setHolidayNumber(holidayNumber); + sysUserStaffHoliday.setHolidayStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.updateSysUserStaffHolidayNumberById(sysUserStaffHoliday)).getBean(); + // 修改员工已休补休信息 + sysUserStaffHoliday.setRetiredHolidayNumber(retiredHolidayNumber); + sysUserStaffHoliday.setRetiredHolidayStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.updateSysUserStaffRetiredHolidayNumberById(sysUserStaffHoliday)).getBean(); + + } + + /** + * 获取请假扣薪制度 + * + * @return 请假扣薪制度 + */ + private List> getSystemHolidaysTypeJsonMation() { + Map sysSetting = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String holidaysTypeJson = sysSetting.get("holidaysTypeJson").toString(); + return JSONUtil.toList(holidaysTypeJson, null); + } + + /** + * 获取指定员工在指定月份和班次的所有审核通过的请假申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + @Override + public List> queryStateIsSuccessLeaveDayByUserIdAndMonths(String userId, String timeId, List months) { + List> beans = skyeyeBaseMapper.queryStateIsSuccessLeaveDayByUserIdAndMonths(userId, timeId, months); + beans.forEach(bean -> { + bean.put("title", CheckDayType.DAY_IS_BUSINESS_TRAVEL.getValue()); + bean.put("type", CheckDayType.DAY_IS_LEAVE.getKey()); + bean.put("className", CheckDayType.DAY_IS_LEAVE.getClassName()); + bean.put("allDay", "1"); + bean.put("showBg", "2"); + bean.put("editable", false); + }); + return beans; + } + + /** + * 获取指定日期已经审核通过的请假信息 + * + * @param timeId 班次id + * @param createId 申请人id + * @param leaveDay 申请日期 + * @return + */ + @Override + public Map queryCheckWorkLeaveByMation(String timeId, String createId, String leaveDay) { + // 获取请假日期信息 + Map leaveDayMation = skyeyeBaseMapper.queryCheckWorkLeaveByMation(timeId, createId, leaveDay); + return leaveDayMation; + } + + /** + * 获取基础设置中的请假类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getLeaveTypeList(InputObject inputObject, OutputObject outputObject) { + List> result = getLeaveTypeList(); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + + private List> getLeaveTypeList() { + List> result = new ArrayList<>(); + List> holidaysTypeMation = getSystemHolidaysTypeJsonMation(); + holidaysTypeMation.forEach(holidaysType -> { + Map bean = new HashMap<>(); + bean.put("id", holidaysType.get("holidayNo")); + bean.put("name", holidaysType.get("holidayName")); + result.add(bean); + }); + return result; + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveTimeSlotServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveTimeSlotServiceImpl.java new file mode 100644 index 0000000..640b07e --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/leave/service/impl/LeaveTimeSlotServiceImpl.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.leave.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.leave.dao.LeaveTimeSlotDao; +import com.skyeye.leave.entity.LeaveTimeSlot; +import com.skyeye.leave.service.LeaveTimeSlotService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: LeaveTimeSlotServiceImpl + * @Description: 请假申请请假时间段服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 8:42 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "请假申请请假时间段", groupName = "请假申请", manageShow = false) +public class LeaveTimeSlotServiceImpl extends SkyeyeLinkDataServiceImpl implements LeaveTimeSlotService { + + @Override + public void editStateById(String id, String state, Integer useYearHoliday) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(LeaveTimeSlot::getState), state); + updateWrapper.set(MybatisPlusUtil.toColumns(LeaveTimeSlot::getUseYearHoliday), useYearHoliday); + update(updateWrapper); + } +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/classenum/OvertimeSoltSettleState.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/classenum/OvertimeSoltSettleState.java new file mode 100644 index 0000000..fcaa5c3 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/classenum/OvertimeSoltSettleState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OvertimeSettleState + * @Description: 加班是否计入补休/薪资结算状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OvertimeSoltSettleState implements SkyeyeEnumClass { + + WAIT_STATISTICS(1, "待计入统计", true, false), + RECORDED_IN_STATISTICS(2, "已计入统计", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/controller/OvertimeController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/controller/OvertimeController.java new file mode 100644 index 0000000..e798128 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/controller/OvertimeController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.overtime.entity.OverTime; +import com.skyeye.overtime.service.OvertimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OvertimeController + * @Description: 加班申请控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/8 22:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "加班申请", tags = "加班申请", modelName = "加班申请") +public class OvertimeController { + + @Autowired + private OvertimeService overtimeService; + + /** + * 获取我的加班申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkovertime001", value = "获取我的加班申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OvertimeController/queryOvertimeList") + public void queryOvertimeList(InputObject inputObject, OutputObject outputObject) { + overtimeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑加班申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeOvertime", value = "新增/编辑加班申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = OverTime.class) + @RequestMapping("/post/OvertimeController/writeOvertime") + public void writeOvertime(InputObject inputObject, OutputObject outputObject) { + overtimeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 加班申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkovertime006", value = "加班申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/OvertimeController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + overtimeService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废加班申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkovertime007", value = "作废加班申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OvertimeController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + overtimeService.invalid(inputObject, outputObject); + } + + /** + * 撤销加班申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkovertime009", value = "撤销加班申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/OvertimeController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + overtimeService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OverTimeSlotDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OverTimeSlotDao.java new file mode 100644 index 0000000..f9795c3 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OverTimeSlotDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.overtime.entity.OverTimeSlot; + +/** + * @ClassName: OverTimeSlotDao + * @Description: 加班申请加班时间段数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 21:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OverTimeSlotDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OvertimeDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OvertimeDao.java new file mode 100644 index 0000000..7b23ff0 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/dao/OvertimeDao.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.overtime.entity.OverTime; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OvertimeDao + * @Description: 加班申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/8 22:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface OvertimeDao extends SkyeyeBaseMapper { + + List> queryOvertimeList(CommonPageInfo pageInfo); + + /** + * 获取指定员工在指定天是否有审批通过的数据 + * + * @param createId 创建人 + * @param overtimeDay 指定天 + * @param childState 子对象状态 + * @return + */ + List> queryPassThisDayAndCreateId(@Param("createId") String createId, + @Param("overtimeDay") String overtimeDay, + @Param("childState") String childState); + + /** + * 获取指定员工在指定月份的所有审核通过的加班申请数据 + * + * @param userId 用户id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + List> queryStateIsSuccessWorkOvertimeDayByUserIdAndMonths(@Param("userId") String userId, + @Param("months") List months); + + /** + * 获取所有待结算的加班数据 + * + * @param childState 子对象状态 + * @return + */ + List> queryCheckWorkOvertimeWaitSettlement(@Param("childState") String childState); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTime.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTime.java new file mode 100644 index 0000000..a26e34e --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTime.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: OverTime + * @Description: 加班申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:overTime", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "check_work_overtime", autoResultMap = true) +@ApiModel("加班申请实体类") +public class OverTime extends SkyeyeFlowable { + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField(value = "content") + @ApiModelProperty(value = "加班事由", required = "required") + private String content; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "加班时间段", required = "required,json") + private List overTimeSlotList; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTimeSlot.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTimeSlot.java new file mode 100644 index 0000000..a47a76f --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/entity/OverTimeSlot.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: OverTimeSlot + * @Description: 加班申请加班时间段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "check_work_overtime_time_slot", autoResultMap = true) +@ApiModel("出差申请出差时间段实体类") +public class OverTimeSlot extends SkyeyeLinkData { + + @TableField(value = "overtime_day") + @ApiModelProperty(value = "加班日期,格式:yyyy-MM-dd", required = "required") + private String overtimeDay; + + @TableField(value = "overtime_start_time") + @ApiModelProperty(value = "加班开始时间,格式:HH:mm:ss", required = "required") + private String overtimeStartTime; + + @TableField(value = "overtime_end_time") + @ApiModelProperty(value = "加班结束时间,格式:HH:mm:ss", required = "required") + private String overtimeEndTime; + + @TableField(value = "overtime_hour") + @ApiModelProperty(value = "加班小时", required = "required") + private String overtimeHour; + + @TableField(value = "settle_state") + @Property(value = "加班是否计入补休/薪资结算状态,参考#OvertimeSoltSettleState") + private Integer settleState; + + @TableField(value = "overtime_settlement_type") + @Property(value = "部门加班结算方式,参考#OvertimeSettlementType") + private Integer overtimeSettlementType; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OverTimeSlotService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OverTimeSlotService.java new file mode 100644 index 0000000..c999e31 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OverTimeSlotService.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.overtime.entity.OverTimeSlot; + +/** + * @ClassName: OverTimeSlotService + * @Description: 加班申请加班时间段服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 21:47 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OverTimeSlotService extends SkyeyeLinkDataService { + + /** + * 修改结算状态 + * + * @param id + * @param settleState + */ + void editSettleStateById(String id, Integer settleState); + + /** + * 修改结算类型 + * + * @param id + * @param settlementType + */ + void editSettlementTypeById(String id, Integer settlementType); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OvertimeService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OvertimeService.java new file mode 100644 index 0000000..72c86ee --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/OvertimeService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.overtime.entity.OverTime; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OvertimeService + * @Description: 加班申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 21:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OvertimeService extends SkyeyeFlowableService { + + /** + * 获取指定员工在指定月份的所有审核通过的加班申请数据 + * + * @param userId 用户id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + List> queryStateIsSuccessWorkOvertimeDayByUserIdAndMonths(String userId, List months); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OverTimeSlotServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OverTimeSlotServiceImpl.java new file mode 100644 index 0000000..bea4a2f --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OverTimeSlotServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.overtime.dao.OverTimeSlotDao; +import com.skyeye.overtime.entity.OverTimeSlot; +import com.skyeye.overtime.service.OverTimeSlotService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: OverTimeSlotServiceImpl + * @Description: 加班申请加班时间段服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/5 21:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加班申请加班时间段", groupName = "加班申请", manageShow = false) +public class OverTimeSlotServiceImpl extends SkyeyeLinkDataServiceImpl implements OverTimeSlotService { + + /** + * 修改结算状态 + * + * @param id + * @param settleState + */ + @Override + public void editSettleStateById(String id, Integer settleState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(OverTimeSlot::getSettleState), settleState); + update(updateWrapper); + } + + /** + * 修改结算类型 + * + * @param id + * @param settlementType + */ + @Override + public void editSettlementTypeById(String id, Integer settlementType) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(OverTimeSlot::getOvertimeSettlementType), settlementType); + update(updateWrapper); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OvertimeServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OvertimeServiceImpl.java new file mode 100644 index 0000000..f8e0716 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/overtime/service/impl/OvertimeServiceImpl.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.overtime.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.OvertimeSettlementType; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.centerrest.entity.checkwork.UserStaffHolidayRest; +import com.skyeye.eve.centerrest.user.SysEveUserService; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.overtime.classenum.OvertimeSoltSettleState; +import com.skyeye.overtime.dao.OvertimeDao; +import com.skyeye.overtime.entity.OverTime; +import com.skyeye.overtime.entity.OverTimeSlot; +import com.skyeye.overtime.service.OverTimeSlotService; +import com.skyeye.overtime.service.OvertimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OvertimeServiceImpl + * @Description: 加班申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/8 22:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "加班申请", groupName = "加班申请", flowable = true) +public class OvertimeServiceImpl extends SkyeyeFlowableServiceImpl implements OvertimeService { + + @Autowired + private OverTimeSlotService overTimeSlotService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private SysEveUserService sysEveUserService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryOvertimeList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(OverTime entity) { + chectOrderItem(entity.getOverTimeSlotList()); + } + + @Override + public void writeChild(OverTime entity, String userId) { + entity.getOverTimeSlotList().forEach(overTimeSlot -> { + overTimeSlot.setSettleState(OvertimeSoltSettleState.WAIT_STATISTICS.getKey()); + }); + overTimeSlotService.saveLinkList(entity.getId(), entity.getOverTimeSlotList()); + super.writeChild(entity, userId); + } + + private void chectOrderItem(List overTimeSlots) { + List overtimeDays = overTimeSlots.stream() + .map(OverTimeSlot::getOvertimeDay).distinct() + .collect(Collectors.toList()); + if (overTimeSlots.size() != overtimeDays.size()) { + throw new CustomException("单据中不允许出现同一天的加班日期"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + overTimeSlotService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public OverTime getDataFromDb(String id) { + OverTime overTime = super.getDataFromDb(id); + List overTimeSlotList = overTimeSlotService.selectByPId(overTime.getId()); + overTime.setOverTimeSlotList(overTimeSlotList); + return overTime; + } + + @Override + public OverTime selectById(String id) { + OverTime overTime = super.selectById(id); + overTime.setStateName(FlowableStateEnum.getStateName(overTime.getState())); + iAuthUserService.setName(overTime, "createId", "createName"); + return overTime; + } + + @Override + public void revokePostpose(OverTime entity) { + super.revokePostpose(entity); + overTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(OverTime entity) { + calcUserStaffOvertimeMation(entity.getId(), entity.getCreateId()); + } + + @Override + protected void approvalEndIsFailed(OverTime entity) { + overTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + /** + * 校验该单据中的天数是否符合规则 + * + * @param overtimeId 加班信息id + * @param createId 创建人id + */ + private void calcUserStaffOvertimeMation(String overtimeId, String createId) { + // 用户信息 + Map user = iAuthUserService.queryDataMationById(createId); + // 用户所在部门的加班结算方式 + int overtimeSettlementType = + Integer.parseInt(iDepmentService.queryDataMationById(user.get("departmentId").toString()).get("overtimeSettlementType").toString()); + // 员工id + String staffId = user.get("staffId").toString(); + // 员工当前剩余补休 + String holidayNumber = user.get("holidayNumber").toString(); + // 获取加班天数信息 + List overTimeSlotList = overTimeSlotService.selectByPId(overtimeId); + for (OverTimeSlot overTimeSlot : overTimeSlotList) { + String overtimeSoltId = overTimeSlot.getId(); + String overtimeDay = overTimeSlot.getOvertimeDay(); + String overtimeHour = overTimeSlot.getOvertimeHour(); + List> inData = skyeyeBaseMapper.queryPassThisDayAndCreateId(createId, overtimeDay, FlowableChildStateEnum.ADEQUATE.getKey()); + if (CollectionUtil.isEmpty(inData)) { + // 如果指定天还没有审批通过的记录,则审批通过 + overTimeSlotService.editStateById(overtimeSoltId, FlowableChildStateEnum.ADEQUATE.getKey()); + if (overtimeSettlementType == OvertimeSettlementType.COMPENSATORY_LEAVE_SETTLEMENT.getKey()) { + // 补休结算 + holidayNumber = CalculationUtil.add(holidayNumber, overtimeHour, CommonNumConstants.NUM_TWO); + // 修改加班电子流的结算状态 + overTimeSlotService.editSettleStateById(overtimeSoltId, OvertimeSoltSettleState.RECORDED_IN_STATISTICS.getKey()); + } + // 修改加班电子流的结算类型 + overTimeSlotService.editSettlementTypeById(overtimeSoltId, overtimeSettlementType); + } else { + overTimeSlotService.editStateById(overtimeSoltId, FlowableChildStateEnum.INSUFFICIENT.getKey()); + } + } + // 修改员工剩余补休信息 + UserStaffHolidayRest sysUserStaffHoliday = new UserStaffHolidayRest(); + sysUserStaffHoliday.setStaffId(staffId); + sysUserStaffHoliday.setHolidayNumber(holidayNumber); + sysUserStaffHoliday.setHolidayStatisTime(DateUtil.getTimeAndToString()); + ExecuteFeignClient.get(() -> sysEveUserService.updateSysUserStaffHolidayNumberById(sysUserStaffHoliday)).getBean(); + } + + /** + * 获取指定员工在指定月份的所有审核通过的加班申请数据 + * + * @param userId 用户id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + @Override + public List> queryStateIsSuccessWorkOvertimeDayByUserIdAndMonths(String userId, List months) { + List> beans = skyeyeBaseMapper.queryStateIsSuccessWorkOvertimeDayByUserIdAndMonths(userId, months); + beans.forEach(bean -> { + bean.put("type", CheckDayType.DAY_IS_WORK_OVERTIME.getKey()); + bean.put("className", CheckDayType.DAY_IS_WORK_OVERTIME.getClassName()); + bean.put("allDay", "1"); + bean.put("showBg", "2"); + bean.put("editable", false); + }); + return beans; + } +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/controller/BusinessTripController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/controller/BusinessTripController.java new file mode 100644 index 0000000..6cb3e81 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/controller/BusinessTripController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.trip.entity.BusinessTrip; +import com.skyeye.trip.service.BusinessTripService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BusinessTripController + * @Description: 出差申请 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/6 22:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "出差申请", tags = "出差申请", modelName = "出差申请") +public class BusinessTripController { + + @Autowired + private BusinessTripService businessTripService; + + /** + * 获取我的出差申请列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkbusinesstrip001", value = "获取我的出差申请列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BusinessTripController/queryBusinessTripList") + public void queryBusinessTripList(InputObject inputObject, OutputObject outputObject) { + businessTripService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑出差申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBusinessTrip", value = "新增/编辑出差申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = BusinessTrip.class) + @RequestMapping("/post/BusinessTripController/writeBusinessTrip") + public void writeBusinessTrip(InputObject inputObject, OutputObject outputObject) { + businessTripService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 出差申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkbusinesstrip006", value = "出差申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/BusinessTripController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + businessTripService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废出差申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkbusinesstrip007", value = "作废出差申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/BusinessTripController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + businessTripService.invalid(inputObject, outputObject); + } + + /** + * 撤销出差申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworkbusinesstrip009", value = "撤销出差申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/BusinessTripController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + businessTripService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripDao.java new file mode 100644 index 0000000..9cdda5e --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripDao.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.trip.entity.BusinessTrip; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: BusinessTripDao + * @Description: 出差申请数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/6 22:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface BusinessTripDao extends SkyeyeBaseMapper { + + List> queryBusinessTripList(CommonPageInfo pageInfo); + + /** + * 获取指定员工在指定月份和班次的所有审核通过的出差申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @param childState 子对象状态 + * @return + */ + List> queryStateIsSuccessBusinessTripDay(@Param("userId") String userId, + @Param("timeId") String timeId, @Param("months") List months, + @Param("childState") String childState); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripTimeSlotDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripTimeSlotDao.java new file mode 100644 index 0000000..c088e20 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/dao/BusinessTripTimeSlotDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.trip.entity.BusinessTripTimeSlot; + +/** + * @ClassName: BusinessTripTimeSlotDao + * @Description: 出差申请出差时间段数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 10:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BusinessTripTimeSlotDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTrip.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTrip.java new file mode 100644 index 0000000..b58af53 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTrip.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: BusinessTrip + * @Description: 出差申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:businessTrip", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "check_work_business_travel", autoResultMap = true) +@ApiModel("出差申请实体类") +public class BusinessTrip extends SkyeyeFlowable { + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required") + private String name; + + @TableField(value = "business_trip_address") + @ApiModelProperty(value = "出差地点", required = "required") + private String businessTripAddress; + + @TableField(value = "business_trip_reason") + @ApiModelProperty(value = "出差事由", required = "required") + private String businessTripReason; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "出差时间段", required = "required,json") + private List tripTimeSlotList; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTripTimeSlot.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTripTimeSlot.java new file mode 100644 index 0000000..4c0c68c --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/entity/BusinessTripTimeSlot.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import com.skyeye.worktime.entity.CheckWorkTime; +import lombok.Data; + +/** + * @ClassName: BusinessTripTimeSlot + * @Description: 出差申请出差时间段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "check_work_business_travel_time_slot", autoResultMap = true) +@ApiModel("出差申请出差时间段实体类") +public class BusinessTripTimeSlot extends SkyeyeLinkData { + + @TableField(value = "time_id") + @ApiModelProperty(value = "班次id", required = "required") + private String timeId; + + @TableField(exist = false) + @Property(value = "班次信息") + private CheckWorkTime timeMation; + + @TableField(value = "travel_day") + @ApiModelProperty(value = "出差日期,格式:yyyy-MM-dd", required = "required") + private String travelDay; + + @TableField(value = "start_time") + @ApiModelProperty(value = "出差开始时间,格式:HH:mm:ss", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "出差结束时间,格式:HH:mm:ss", required = "required") + private String endTime; + + @TableField(value = "travel_hour") + @ApiModelProperty(value = "出差小时", required = "required") + private String travelHour; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripService.java new file mode 100644 index 0000000..29605f5 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.trip.entity.BusinessTrip; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkBusinessTripService + * @Description: 出差申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/6 22:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface BusinessTripService extends SkyeyeFlowableService { + + /** + * 获取指定员工在指定月份和班次的所有审核通过的出差申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + List> queryStateIsSuccessBusinessTripDayByUserIdAndMonths(String userId, String timeId, + List months); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripTimeSlotService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripTimeSlotService.java new file mode 100644 index 0000000..81c3d50 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/BusinessTripTimeSlotService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.trip.entity.BusinessTripTimeSlot; + +/** + * @ClassName: BusinessTripTimeSlotService + * @Description: 出差申请出差时间段信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 10:47 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BusinessTripTimeSlotService extends SkyeyeLinkDataService { +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripServiceImpl.java new file mode 100644 index 0000000..c6d0afa --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripServiceImpl.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CheckDayType; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.trip.dao.BusinessTripDao; +import com.skyeye.trip.entity.BusinessTrip; +import com.skyeye.trip.entity.BusinessTripTimeSlot; +import com.skyeye.trip.service.BusinessTripService; +import com.skyeye.trip.service.BusinessTripTimeSlotService; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.service.CheckWorkTimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CheckWorkBusinessTripServiceImpl + * @Description: 出差申请服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/6 22:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "出差申请", groupName = "出差申请", flowable = true) +public class BusinessTripServiceImpl extends SkyeyeFlowableServiceImpl implements BusinessTripService { + + @Autowired + private BusinessTripTimeSlotService businessTripTimeSlotService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryBusinessTripList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(BusinessTrip entity) { + checkOrderItem(entity.getTripTimeSlotList()); + } + + @Override + public void writeChild(BusinessTrip entity, String userId) { + businessTripTimeSlotService.saveLinkList(entity.getId(), entity.getTripTimeSlotList()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(List businessTripTimeSlots) { + List travelDay = businessTripTimeSlots.stream() + .map(bean -> String.format(Locale.ROOT, "%s-%s", bean.getTimeId(), bean.getTravelDay())).distinct() + .collect(Collectors.toList()); + if (businessTripTimeSlots.size() != travelDay.size()) { + throw new CustomException("同一班次中不允许出现相同的出差日期"); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + businessTripTimeSlotService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public BusinessTrip getDataFromDb(String id) { + BusinessTrip businessTrip = super.getDataFromDb(id); + List tripTimeSlotList = businessTripTimeSlotService.selectByPId(businessTrip.getId()); + businessTrip.setTripTimeSlotList(tripTimeSlotList); + return businessTrip; + } + + @Override + public BusinessTrip selectById(String id) { + BusinessTrip businessTrip = super.selectById(id); + // 获取考勤班次信息 + List timeIds = businessTrip.getTripTimeSlotList().stream() + .map(BusinessTripTimeSlot::getTimeId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(timeIds)) { + Map checkWorkTimeMap = checkWorkTimeService.selectMapByIds(timeIds); + businessTrip.getTripTimeSlotList().forEach(businessTripTimeSlot -> { + businessTripTimeSlot.setTimeMation(checkWorkTimeMap.get(businessTripTimeSlot.getTimeId())); + businessTripTimeSlot.setStateName(FlowableChildStateEnum.getStateName(businessTripTimeSlot.getState())); + }); + } + businessTrip.setStateName(FlowableStateEnum.getStateName(businessTrip.getState())); + iAuthUserService.setName(businessTrip, "createId", "createName"); + return businessTrip; + } + + @Override + public void revokePostpose(BusinessTrip entity) { + super.revokePostpose(entity); + businessTripTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(BusinessTrip entity) { + businessTripTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + protected void approvalEndIsFailed(BusinessTrip entity) { + businessTripTimeSlotService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + /** + * 获取指定员工在指定月份和班次的所有审核通过的出差申请数据 + * + * @param userId 用户id + * @param timeId 班次id + * @param months 指定月份,月格式(yyyy-MM) + * @return + */ + @Override + public List> queryStateIsSuccessBusinessTripDayByUserIdAndMonths(String userId, String timeId, List months) { + List> beans = skyeyeBaseMapper.queryStateIsSuccessBusinessTripDay(userId, timeId, months, FlowableChildStateEnum.ADEQUATE.getKey()); + // 获取考勤班次信息 + List timeIds = beans.stream() + .map(bean -> bean.get("timeId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(timeIds)) { + beans.forEach(bean -> { + bean.put("title", CheckDayType.DAY_IS_BUSINESS_TRAVEL.getValue()); + bean.put("type", CheckDayType.DAY_IS_BUSINESS_TRAVEL.getKey()); + bean.put("className", CheckDayType.DAY_IS_BUSINESS_TRAVEL.getClassName()); + bean.put("allDay", "1"); + bean.put("showBg", "2"); + bean.put("editable", false); + }); + return beans; + } + return new ArrayList<>(); + } +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripTimeSlotServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripTimeSlotServiceImpl.java new file mode 100644 index 0000000..ff6f758 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/trip/service/impl/BusinessTripTimeSlotServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.trip.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.trip.dao.BusinessTripTimeSlotDao; +import com.skyeye.trip.entity.BusinessTripTimeSlot; +import com.skyeye.trip.service.BusinessTripTimeSlotService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: BusinessTripTimeSlotServiceImpl + * @Description: 出差申请出差时间段服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 10:48 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "出差时间段", groupName = "出差申请", manageShow = false) +public class BusinessTripTimeSlotServiceImpl extends SkyeyeLinkDataServiceImpl implements BusinessTripTimeSlotService { + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeType.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeType.java new file mode 100644 index 0000000..0dcd62b --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CheckWorkTimeType + * @Description: 考勤班次类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 15:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CheckWorkTimeType implements SkyeyeEnumClass { + + SINGLE_BREAK(1, "单休", true, true), + WEEKEND_BREAK(2, "双休", true, false), + SINGLE_AND_DOUBLE_REST(3, "单双休", true, false), + CUSTOM(4, "自定义", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeWeekType.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeWeekType.java new file mode 100644 index 0000000..5496fba --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/classenum/CheckWorkTimeWeekType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CheckWorkTimeWeekType + * @Description: 考勤班次里的具体时间的类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CheckWorkTimeWeekType implements SkyeyeEnumClass { + + DAY(1, "每周的当天都上班", true, false), + SINGLE_DAY(2, "单周上班,双周休假", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/controller/CheckWorkTimeController.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/controller/CheckWorkTimeController.java new file mode 100644 index 0000000..d6dc09d --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/controller/CheckWorkTimeController.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.service.CheckWorkTimeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CheckWorkTimeController + * @Description: 考勤班次管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "考勤班次", tags = "考勤班次", modelName = "考勤班次") +public class CheckWorkTimeController { + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + /** + * 查询考勤班次列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworktime001", value = "查询考勤班次列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CheckWorkTimeController/queryCheckWorkTimeList") + public void queryCheckWorkTimeList(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑考勤班次信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCheckWorkTime", value = "新增/编辑考勤班次信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CheckWorkTime.class) + @RequestMapping("/post/CheckWorkTimeController/writeCheckWorkTime") + public void writeCheckWorkTime(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 设置线上打卡的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setOnlineCheckWorkTime", value = "设置线上打卡的信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "longitude", name = "longitude", value = "经度", required = "required"), + @ApiImplicitParam(id = "latitude", name = "latitude", value = "纬度", required = "required"), + @ApiImplicitParam(id = "provinceId", name = "provinceId", value = "省", required = "required"), + @ApiImplicitParam(id = "cityId", name = "cityId", value = "市", required = "required"), + @ApiImplicitParam(id = "areaId", name = "areaId", value = "区县", required = "required"), + @ApiImplicitParam(id = "townshipId", name = "townshipId", value = "乡镇", required = "required"), + @ApiImplicitParam(id = "absoluteAddress", name = "absoluteAddress", value = "具体地址", required = "required")}) + @RequestMapping("/post/CheckWorkTimeController/setOnlineCheckWorkTime") + public void setOnlineCheckWorkTime(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.setOnlineCheckWorkTime(inputObject, outputObject); + } + + /** + * 根据id查询考勤班次信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCheckWorkTimeById", value = "根据id查询考勤班次信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CheckWorkTimeController/queryCheckWorkTimeById") + public void queryCheckWorkTimeById(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除考勤班次信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCheckWorkTimeById", value = "根据id删除考勤班次信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CheckWorkTimeController/deleteCheckWorkTimeById") + public void deleteCheckWorkTimeById(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.deleteById(inputObject, outputObject); + } + + /** + * 查询启用的考勤班次列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnableCheckWorkTimeList", value = "查询启用的考勤班次列表", method = "GET", allUse = "2") + @RequestMapping("/post/CheckWorkTimeController/queryEnableCheckWorkTimeList") + public void queryEnableCheckWorkTimeList(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.queryEnableCheckWorkTimeList(inputObject, outputObject); + } + + /** + * 获取当前登陆人的考勤班次 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkworktime007", value = "获取当前登陆人的考勤班次", method = "GET", allUse = "2") + @RequestMapping("/post/CheckWorkTimeController/queryCheckWorkTimeListByLoginUser") + public void queryCheckWorkTimeListByLoginUser(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.queryCheckWorkTimeListByLoginUser(inputObject, outputObject); + } + + /** + * 根据指定年月获取所有的考勤班次的信息以及工作日信息等 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getAllCheckWorkTime", value = "根据指定年月获取所有的考勤班次的信息以及工作日信息等", method = "GET", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "pointMonthDate", name = "pointMonthDate", value = "指定年月,格式为yyyy-MM", required = "required")}) + @RequestMapping("/post/CheckWorkTimeController/getAllCheckWorkTime") + public void getAllCheckWorkTime(InputObject inputObject, OutputObject outputObject) { + checkWorkTimeService.getAllCheckWorkTime(inputObject, outputObject); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeDao.java new file mode 100644 index 0000000..ceab418 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.worktime.entity.CheckWorkTime; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkTimeDao + * @Description: 考勤班次管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkTimeDao extends SkyeyeBaseMapper { + + List> queryCheckWorkTimeList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeWeekDao.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeWeekDao.java new file mode 100644 index 0000000..cc6632a --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/dao/CheckWorkTimeWeekDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; + +/** + * @ClassName: CheckWorkTimeWeekDao + * @Description: 考勤班次里的具体时间数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 15:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkTimeWeekDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTime.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTime.java new file mode 100644 index 0000000..7f6d003 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTime.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.entity.features.AreaInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: CheckWorkTime + * @Description: 考勤班次实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "checkwork:time") +@TableName(value = "check_work_time", autoResultMap = true) +@ApiModel("考勤班次实体类") +public class CheckWorkTime extends AreaInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(value = "start_time") + @ApiModelProperty(value = "考勤开始时间", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "考勤结束时间", required = "required") + private String endTime; + + @TableField(value = "rest_start_time") + @ApiModelProperty(value = "作息开始时间") + private String restStartTime; + + @TableField(value = "rest_end_time") + @ApiModelProperty(value = "作息结束时间") + private String restEndTime; + + @TableField(value = "type") + @ApiModelProperty(value = "时间段类型,参考#CheckWorkTimeType", required = "required,num") + private Integer type; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(exist = false) + @ApiModelProperty(value = "考勤班次关联的时间段", required = "required,json") + private List checkWorkTimeWeekList; + + @TableField(exist = false) + @Property(value = "每个月工作的日期") + private List workDays; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(value = "longitude") + @ApiModelProperty(value = "经度") + private String longitude; + + @TableField(value = "latitude") + @ApiModelProperty(value = "纬度") + private String latitude; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTimeWeek.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTimeWeek.java new file mode 100644 index 0000000..39cc1e0 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/entity/CheckWorkTimeWeek.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: CheckWorkTimeWeek + * @Description: 考勤班次里的具体时间实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:40 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "check_work_time_week") +@ApiModel("考勤班次里的具体时间实体类") +public class CheckWorkTimeWeek extends CommonInfo { + + @TableField(value = "time_id") + @Property(value = "班次id") + private String timeId; + + @TableField(value = "week_number") + @ApiModelProperty(value = "周几", required = "required") + private Integer weekNumber; + + @TableField(value = "type") + @ApiModelProperty(value = "上班类型,参考#CheckWorkTimeWeekType", required = "required,num") + private Integer type; + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeService.java new file mode 100644 index 0000000..5b6b7d7 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.worktime.entity.CheckWorkTime; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkTimeService + * @Description: 考勤班次管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkTimeService extends SkyeyeBusinessService { + + void queryEnableCheckWorkTimeList(InputObject inputObject, OutputObject outputObject); + + void queryCheckWorkTimeListByLoginUser(InputObject inputObject, OutputObject outputObject); + + void getAllCheckWorkTime(InputObject inputObject, OutputObject outputObject); + + /** + * 根据指定年月获取所有的考勤班次的信息以及工作日信息等 + * + * @param pointMonthDate 指定年月,格式为yyyy-MM + * @return + */ + List getAllCheckWorkTime(String pointMonthDate); + + void setOnlineCheckWorkTime(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeWeekService.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeWeekService.java new file mode 100644 index 0000000..14d74bc --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/CheckWorkTimeWeekService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CheckWorkTimeWeekService + * @Description: 考勤班次里的具体时间服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 15:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CheckWorkTimeWeekService extends SkyeyeBusinessService { + + void saveCheckWorkTimeWeekList(String timeId, List beans, String userId); + + void deleteByTimeId(String timeId); + + List selectByTimeId(String timeId); + + Map> selectByTimeId(List timeIds); + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeServiceImpl.java new file mode 100644 index 0000000..df5ca5f --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeServiceImpl.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.enumeration.WeekTypeEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.centerrest.user.SysEveUserService; +import com.skyeye.worktime.classenum.CheckWorkTimeWeekType; +import com.skyeye.worktime.dao.CheckWorkTimeDao; +import com.skyeye.worktime.entity.CheckWorkTime; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; +import com.skyeye.worktime.service.CheckWorkTimeService; +import com.skyeye.worktime.service.CheckWorkTimeWeekService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CheckWorkTimeServiceImpl + * @Description: 考勤班次管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 14:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "考勤班次", groupName = "考勤班次") +public class CheckWorkTimeServiceImpl extends SkyeyeBusinessServiceImpl implements CheckWorkTimeService { + + @Autowired + private CheckWorkTimeWeekService checkWorkTimeWeekService; + + @Autowired + private SysEveUserService sysEveUserService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryCheckWorkTimeList(pageInfo); + return beans; + } + + @Override + protected void writePostpose(CheckWorkTime entity, String userId) { + super.writePostpose(entity, userId); + checkWorkTimeWeekService.saveCheckWorkTimeWeekList(entity.getId(), entity.getCheckWorkTimeWeekList(), userId); + } + + @Override + public CheckWorkTime getDataFromDb(String id) { + CheckWorkTime checkWorkTime = super.getDataFromDb(id); + checkWorkTime.setCheckWorkTimeWeekList(checkWorkTimeWeekService.selectByTimeId(checkWorkTime.getId())); + return checkWorkTime; + } + + @Override + protected List getDataFromDb(List idList) { + List checkWorkTimeList = super.getDataFromDb(idList); + Map> weekMap = checkWorkTimeWeekService.selectByTimeId(idList); + checkWorkTimeList.forEach(checkWorkTime -> { + checkWorkTime.setCheckWorkTimeWeekList(weekMap.get(checkWorkTime.getId())); + }); + return checkWorkTimeList; + } + + /** + * 查询启用的考勤班次列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnableCheckWorkTimeList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CheckWorkTime::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List checkWorkTimeList = list(queryWrapper); + outputObject.setBeans(checkWorkTimeList); + outputObject.settotal(checkWorkTimeList.size()); + } + + /** + * 获取当前登陆人的考勤班次 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCheckWorkTimeListByLoginUser(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + // 获取员工绑定的考勤班次信息 + List> workTime = ExecuteFeignClient.get(() -> sysEveUserService.queryStaffCheckWorkTimeRelationNameByStaffId(staffId)).getRows(); + List timeIds = workTime.stream().map(bean -> bean.get("timeId").toString()).collect(Collectors.toList()); + + List checkWorkTimes = selectByIds(timeIds.toArray(new String[]{})); + outputObject.setBeans(checkWorkTimes); + outputObject.settotal(checkWorkTimes.size()); + } + + /** + * 根据指定年月获取所有的考勤班次的信息以及工作日信息等 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getAllCheckWorkTime(InputObject inputObject, OutputObject outputObject) { + String pointMonthDate = inputObject.getParams().get("pointMonthDate").toString(); + List beans = this.getAllCheckWorkTime(pointMonthDate); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 根据指定年月获取所有的考勤班次的信息以及工作日信息等 + * + * @param pointMonthDate 指定年月,格式为yyyy-MM + * @return + */ + @Override + public List getAllCheckWorkTime(String pointMonthDate) { + List checkWorkTimes = queryAllData(); + // 获取上个月的所有日期 + List lastMonthDays = DateUtil.getMonthFullDay(Integer.parseInt(pointMonthDate.split("-")[0]), Integer.parseInt(pointMonthDate.split("-")[1])); + for (CheckWorkTime bean : checkWorkTimes) { + List days = bean.getCheckWorkTimeWeekList(); + List workDays = new ArrayList<>(); + for (String day : lastMonthDays) { + // 周几 + int weekDay = DateUtil.getWeek(day); + int weekType = DateUtil.getWeekType(day); + CheckWorkTimeWeek simpleDay = days.stream().filter(item -> item.getWeekNumber() == weekDay).findFirst().orElse(null); + if (ObjectUtil.isEmpty(simpleDay)) { + continue; + } + // 如果今天是需要考勤的日期 + if (weekType == WeekTypeEnum.BIWEEKLY.getKey() && simpleDay.getType().equals(CheckWorkTimeWeekType.DAY.getKey())) { + // 如果获取到的日期是双周,但考勤班次里面是单周,则不做任何操作 + } else { + // 单周或者非每周的当天都上班 + workDays.add(day); + } + } + bean.setWorkDays(workDays); + } + return checkWorkTimes; + } + + @Override + public void setOnlineCheckWorkTime(InputObject inputObject, OutputObject outputObject) { + CheckWorkTime checkWorkTime = inputObject.getParams(CheckWorkTime.class); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, checkWorkTime.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getLongitude), checkWorkTime.getLongitude()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getLatitude), checkWorkTime.getLatitude()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getProvinceId), checkWorkTime.getProvinceId()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getCityId), checkWorkTime.getCityId()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getAreaId), checkWorkTime.getAreaId()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getTownshipId), checkWorkTime.getTownshipId()); + updateWrapper.set(MybatisPlusUtil.toColumns(CheckWorkTime::getAbsoluteAddress), checkWorkTime.getAbsoluteAddress()); + update(updateWrapper); + + refreshCache(checkWorkTime.getId()); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeWeekServiceImpl.java b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeWeekServiceImpl.java new file mode 100644 index 0000000..87f6ad2 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/java/com/skyeye/worktime/service/impl/CheckWorkTimeWeekServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worktime.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.worktime.dao.CheckWorkTimeWeekDao; +import com.skyeye.worktime.entity.CheckWorkTimeWeek; +import com.skyeye.worktime.service.CheckWorkTimeWeekService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CheckWorkTimeWeekServiceImpl + * @Description: 考勤班次里的具体时间服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/3 15:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "考勤班次里的具体时间", groupName = "考勤班次", manageShow = false) +public class CheckWorkTimeWeekServiceImpl extends SkyeyeBusinessServiceImpl implements CheckWorkTimeWeekService { + + @Override + public void saveCheckWorkTimeWeekList(String timeId, List beans, String userId) { + deleteByTimeId(timeId); + if (CollectionUtil.isNotEmpty(beans)) { + for (CheckWorkTimeWeek farmProcedure : beans) { + farmProcedure.setTimeId(timeId); + } + createEntity(beans, userId); + } + } + + @Override + public void deleteByTimeId(String timeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CheckWorkTimeWeek::getTimeId), timeId); + remove(queryWrapper); + } + + @Override + public List selectByTimeId(String timeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CheckWorkTimeWeek::getTimeId), timeId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(CheckWorkTimeWeek::getWeekNumber)); + List checkWorkTimeWeekList = list(queryWrapper); + return checkWorkTimeWeekList; + } + + @Override + public Map> selectByTimeId(List timeIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CheckWorkTimeWeek::getTimeId), timeIds); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(CheckWorkTimeWeek::getWeekNumber)); + List checkWorkTimeWeekList = list(queryWrapper); + return checkWorkTimeWeekList.stream().collect(Collectors.groupingBy(CheckWorkTimeWeek::getTimeId)); + } + +} diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/appeal/AppealMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/appeal/AppealMapper.xml new file mode 100644 index 0000000..8fa16ef --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/appeal/AppealMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/cancleleave/CancelLeaveMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/cancleleave/CancelLeaveMapper.xml new file mode 100644 index 0000000..e02bdc4 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/cancleleave/CancelLeaveMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/checkwork/CheckWorkMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/checkwork/CheckWorkMapper.xml new file mode 100644 index 0000000..6049d15 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/checkwork/CheckWorkMapper.xml @@ -0,0 +1,352 @@ + + + + + + + + INSERT into check_work + (id, check_date, create_id, state, clock_in_state, clock_out_state, work_hours, time_id) + VALUES + + (#{item.id}, #{item.checkDate}, #{item.createId}, #{item.state}, #{item.clockInState}, #{item.clockOutState}, #{item.workHours}, #{item.timeId}) + + + + + + + update check_work + + state = #{state}, + clock_out_state = #{clockOutState}, + work_hours = #{workHours} + + WHERE id = #{id} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/leave/LeaveMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/leave/LeaveMapper.xml new file mode 100644 index 0000000..c065c94 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/leave/LeaveMapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/overtime/OvertimeMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/overtime/OvertimeMapper.xml new file mode 100644 index 0000000..f04711d --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/overtime/OvertimeMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/trip/BusinessTripMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/trip/BusinessTripMapper.xml new file mode 100644 index 0000000..0ff3187 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/trip/BusinessTripMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/worktime/CheckWorkTimeMapper.xml b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/worktime/CheckWorkTimeMapper.xml new file mode 100644 index 0000000..cfb32f6 --- /dev/null +++ b/skyeye-checkwork/checkwork-pro/src/main/resources/mapper/worktime/CheckWorkTimeMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-web/.gitignore b/skyeye-checkwork/checkwork-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-checkwork/checkwork-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-web/pom.xml b/skyeye-checkwork/checkwork-web/pom.xml new file mode 100644 index 0000000..ce32b76 --- /dev/null +++ b/skyeye-checkwork/checkwork-web/pom.xml @@ -0,0 +1,88 @@ + + + + skyeye-checkwork + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + checkwork-web + + + + + com.skyeye + checkwork-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-web/src/main/java/com/CheckWorkApplication.java b/skyeye-checkwork/checkwork-web/src/main/java/com/CheckWorkApplication.java new file mode 100644 index 0000000..8f6a640 --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/java/com/CheckWorkApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class CheckWorkApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(CheckWorkApplication.class, args); + } + +} diff --git a/skyeye-checkwork/checkwork-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-checkwork/checkwork-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..9fa4417 --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.*.dao", + "com.skyeye.eve.dao", + "com.skyeye.eve.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-checkwork/checkwork-web/src/main/resources/banner.txt b/skyeye-checkwork/checkwork-web/src/main/resources/banner.txt new file mode 100644 index 0000000..3414bb7 --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev checkwork-web.jar >> /opt/service/project/nohup-checkwork.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-checkwork/checkwork-web/src/main/resources/bootstrap.yml b/skyeye-checkwork/checkwork-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..eebd82d --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +server: + port: 8105 + +spring: + application: + name: skyeye-checkwork-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: localhost:9000 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: localhost:9000 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-checkwork/checkwork-web/src/main/resources/jvm调优参数配置 b/skyeye-checkwork/checkwork-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-checkwork/checkwork-web/src/main/resources/log4j.properties b/skyeye-checkwork/checkwork-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-checkwork/checkwork-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-checkwork/pom.xml b/skyeye-checkwork/pom.xml new file mode 100644 index 0000000..a36a138 --- /dev/null +++ b/skyeye-checkwork/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + checkwork-common + checkwork-pro + checkwork-web + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-checkwork + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-crm/.gitignore b/skyeye-crm/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-crm/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-crm/crm-common/.gitignore b/skyeye-crm/crm-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-crm/crm-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-crm/crm-common/pom.xml b/skyeye-crm/crm-common/pom.xml new file mode 100644 index 0000000..cc73827 --- /dev/null +++ b/skyeye-crm/crm-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-crm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + crm-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-pro/.gitignore b/skyeye-crm/crm-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-crm/crm-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-crm/crm-pro/pom.xml b/skyeye-crm/crm-pro/pom.xml new file mode 100644 index 0000000..8967631 --- /dev/null +++ b/skyeye-crm/crm-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-crm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + crm-pro + + + + + com.skyeye + crm-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractAuthEnum.java new file mode 100644 index 0000000..fd846cf --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractAuthEnum.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmContractAuthEnum + * @Description: 客户合同权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmContractAuthEnum implements SkyeyeEnumClass { + + LIST("list", "查看列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false), + PERFORM("perform", "执行", true, false), + CLOSE("close", "关闭", true, false), + LAY_ASIDE("layAside", "搁置", true, false), + RECOVERY("recovery", "恢复", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractChildStateEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractChildStateEnum.java new file mode 100644 index 0000000..531cc22 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractChildStateEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmContractChildStateEnum + * @Description: 合同产品状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmContractChildStateEnum implements SkyeyeEnumClass { + + PENDING_ORDER("pendingOrder", "待下达订单", true, false), + PARTIAL_RELEASE("partialRelease", "部分下达", true, false), + ALL_ISSUED("allIssued", "全部下达", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractFromType.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractFromType.java new file mode 100644 index 0000000..beb3dd8 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmContractFromType + * @Description: 客户合同来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmContractFromType implements SkyeyeEnumClass { + + PURCHASE_REQUEST(1, "TODO 待定", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractStateEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractStateEnum.java new file mode 100644 index 0000000..2318480 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/classenum/CrmContractStateEnum.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: CrmContractStateEnum + * @Description: 合同状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmContractStateEnum implements SkyeyeEnumClass { + + EXECUTING("executing", "执行中", true, false), + CLOSE("close", "关闭", true, false), + LAY_ASIDE("layAside", "搁置", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/controller/CrmContractController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/controller/CrmContractController.java new file mode 100644 index 0000000..d73a831 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/controller/CrmContractController.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.CrmContract; +import com.skyeye.contract.service.CrmContractService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CrmContractController + * @Description: 合同管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 16:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "合同管理", tags = "合同管理", modelName = "合同管理") +public class CrmContractController { + + @Autowired + private CrmContractService crmContractService; + + /** + * 获取合同列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCrmContractList", value = "获取合同列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CrmContractController/queryCrmContractList") + public void queryCrmContractList(InputObject inputObject, OutputObject outputObject) { + crmContractService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCrmContract", value = "新增/编辑合同信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CrmContract.class) + @RequestMapping("/post/CrmContractController/writeCrmContract") + public void writeCrmContract(InputObject inputObject, OutputObject outputObject) { + crmContractService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCrmContractById", value = "删除合同信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/deleteCrmContractById") + public void deleteCrmContractById(InputObject inputObject, OutputObject outputObject) { + crmContractService.deleteById(inputObject, outputObject); + } + + /** + * 根据id批量获取客户合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCrmContractByIds", value = "根据id批量获取客户合同信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/queryCrmContractByIds") + public void queryCrmContractById(InputObject inputObject, OutputObject outputObject) { + crmContractService.selectByIds(inputObject, outputObject); + } + + /** + * 根据客户id获取合同管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract008", value = "根据客户id获取合同管理列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id")}) + @RequestMapping("/post/CrmContractController/queryCrmContractListByObjectId") + public void queryCrmContractListByObjectId(InputObject inputObject, OutputObject outputObject) { + crmContractService.queryCrmContractListByObjectId(inputObject, outputObject); + } + + /** + * 合同提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract009", value = "合同提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/CrmContractController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + crmContractService.submitToApproval(inputObject, outputObject); + } + + /** + * 合同执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract010", value = "合同执行", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/performCrmContract") + public void performCrmContract(InputObject inputObject, OutputObject outputObject) { + crmContractService.performCrmContract(inputObject, outputObject); + } + + /** + * 合同关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract011", value = "合同关闭", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/closeCrmContract") + public void closeCrmContract(InputObject inputObject, OutputObject outputObject) { + crmContractService.closeCrmContract(inputObject, outputObject); + } + + /** + * 合同搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract012", value = "合同搁置", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/shelveCrmContract") + public void shelveCrmContract(InputObject inputObject, OutputObject outputObject) { + crmContractService.shelveCrmContract(inputObject, outputObject); + } + + /** + * 合同恢复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract013", value = "合同恢复", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/recoveryCrmContract") + public void recoveryCrmContract(InputObject inputObject, OutputObject outputObject) { + crmContractService.recoveryCrmContract(inputObject, outputObject); + } + + /** + * 作废合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract015", value = "作废合同信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmContractController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + crmContractService.invalid(inputObject, outputObject); + } + + /** + * 撤销合同审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mycrmcontract016", value = "撤销合同审批", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/CrmContractController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + crmContractService.revoke(inputObject, outputObject); + } + + /** + * 修改合同产品状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editCrmContractChildState", value = "修改合同产品状态", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "childState", name = "childState", value = "合同产品状态,参考#CrmContractChildStateEnum", required = "required")}) + @RequestMapping("/post/CrmContractController/editChildState") + public void editChildState(InputObject inputObject, OutputObject outputObject) { + crmContractService.editChildState(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractChildDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractChildDao.java new file mode 100644 index 0000000..a40827c --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.dao; + +import com.skyeye.contract.entity.CrmContractChild; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CrmContractChildDao + * @Description: 客户合同-商品明细数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/12 14:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmContractChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractDao.java new file mode 100644 index 0000000..2224819 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/dao/CrmContractDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.dao; + +import com.skyeye.contract.entity.CrmContract; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CrmContractDao + * @Description: 客户合同管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/14 14:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmContractDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContract.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContract.java new file mode 100644 index 0000000..f6e0c41 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContract.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmContract + * @Description: 合同信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "title"}) +@RedisCacheField(name = CacheConstants.CRM_CONTRACT_CACHE_KEY, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "crm_contract", autoResultMap = true) +@ApiModel("合同信息实体类") +public class CrmContract extends SkyeyeFlowable { + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(value = "title") + @ApiModelProperty(value = "合同名称", required = "required", fuzzyLike = true) + private String title; + + @TableField(exist = false) + @Property(value = "合同名称") + private String name; + + @TableField(value = "price") + @ApiModelProperty(value = "合同金额", required = "double", defaultValue = "0") + private String price; + + @TableField(value = "material_total_price") + @ApiModelProperty(value = "产品明细总金额", required = "double", defaultValue = "0") + private String materialTotalPrice; + + @TableField(value = "signing_time") + @ApiModelProperty(value = "签约日期", required = "required") + private String signingTime; + + @TableField(value = "effect_time") + @ApiModelProperty(value = "生效日期") + private String effectTime; + + @TableField(value = "service_end_time") + @ApiModelProperty(value = "服务结束日期") + private String serviceEndTime; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人ID", required = "required") + private String contacts; + + @TableField(exist = false) + @Property(value = "联系人") + private Map contactsMation; + + @TableField(value = "technical_terms") + @ApiModelProperty(value = "主要技术条款") + private String technicalTerms; + + @TableField(value = "business_terms") + @ApiModelProperty(value = "主要商务条款") + private String businessTerms; + + @TableField(value = "department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Map departmentMation; + + @TableField(value = "relation_user_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "关联人员", required = "required,json") + private List relationUserId; + + @TableField(exist = false) + @Property(value = "关联人员") + private List> relationUserMation; + + @TableField(value = "payment_price") + @Property(value = "已回款金额") + private String paymentPrice; + + @TableField(value = "invoice_price") + @Property(value = "已开票金额") + private String invoicePrice; + + @TableField(exist = false) + @ApiModelProperty(value = "商品明细信息", required = "json") + private List crmContractChildList; + + @TableField("from_type_id") + @ApiModelProperty(value = "来源单据类型,参考#CrmContractFromType") + private Integer fromTypeId; + + @TableField("from_id") + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("child_state") + @Property(value = "合同产品状态,参考#CrmContractChildStateEnum") + private String childState; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContractChild.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContractChild.java new file mode 100644 index 0000000..bc61588 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/entity/CrmContractChild.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: CrmContractChild + * @Description: 客户合同-商品明细实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "crm_contract_child") +@ApiModel("客户合同-商品明细实体类") +public class CrmContractChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Map materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractChildService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractChildService.java new file mode 100644 index 0000000..bf2f079 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractChildService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.contract.entity.CrmContractChild; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmContractChildService + * @Description: 客户合同-商品明细服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/12 14:50 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmContractChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + Map> selectByParentId(List parentIds); + + List getCrmContractChildList(List parentIds); + + String calcOrderAllTotalPrice(List supplierContractChildList); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractService.java new file mode 100644 index 0000000..c5dd307 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/CrmContractService.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.CrmContract; + +import java.util.List; + +/** + * @ClassName: CrmContractService + * @Description: 客户合同管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 22:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmContractService extends SkyeyeFlowableService { + + void queryCrmContractListByObjectId(InputObject inputObject, OutputObject outputObject); + + void performCrmContract(InputObject inputObject, OutputObject outputObject); + + void closeCrmContract(InputObject inputObject, OutputObject outputObject); + + void shelveCrmContract(InputObject inputObject, OutputObject outputObject); + + void recoveryCrmContract(InputObject inputObject, OutputObject outputObject); + + /** + * 根据所属第三方业务数据id查询合同信息 + * + * @param objectId 所属第三方业务数据id + * @return + */ + List queryCrmContractListByObjectId(String objectId); + + /** + * 修改已回款金额 + * + * @param id + * @param paymentPrice + */ + void updatePaymentPrice(String id, String paymentPrice); + + /** + * 修改已开票金额 + * + * @param id + * @param invoicePrice + */ + void updateInvoicePrice(String id, String invoicePrice); + + void editChildState(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractChildServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractChildServiceImpl.java new file mode 100644 index 0000000..1ab3d96 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractChildServiceImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.dao.CrmContractChildDao; +import com.skyeye.contract.entity.CrmContractChild; +import com.skyeye.contract.service.CrmContractChildService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CrmContractChildServiceImpl + * @Description: 客户合同-商品明细服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/12 14:50 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "客户合同-商品明细", groupName = "合同管理", manageShow = false) +public class CrmContractChildServiceImpl extends SkyeyeBusinessServiceImpl implements CrmContractChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (CrmContractChild supplierContractChild : beans) { + supplierContractChild.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContractChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContractChild::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public Map> selectByParentId(List parentIds) { + List list = getCrmContractChildList(parentIds); + return list.stream().collect(Collectors.groupingBy(CrmContractChild::getParentId)); + } + + @Override + public List getCrmContractChildList(List parentIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CrmContractChild::getParentId), parentIds); + List list = list(queryWrapper); + return list; + } + + @Override + public String calcOrderAllTotalPrice(List supplierContractChildList) { + String totalPrice = "0"; + for (CrmContractChild supplierContractChild : supplierContractChildList) { + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(supplierContractChild.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(supplierContractChild.getOperNumber())); + supplierContractChild.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(supplierContractChild.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(supplierContractChild.getOperNumber())); + supplierContractChild.setTaxLastMoney(taxUnitPrice.toString()); + totalPrice = CalculationUtil.add(totalPrice, supplierContractChild.getTaxLastMoney()); + } + return totalPrice; + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractServiceImpl.java new file mode 100644 index 0000000..e620d1d --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/contract/service/impl/CrmContractServiceImpl.java @@ -0,0 +1,432 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.classenum.CrmContractAuthEnum; +import com.skyeye.contract.classenum.CrmContractChildStateEnum; +import com.skyeye.contract.classenum.CrmContractStateEnum; +import com.skyeye.contract.dao.CrmContractDao; +import com.skyeye.contract.entity.CrmContract; +import com.skyeye.contract.entity.CrmContractChild; +import com.skyeye.contract.service.CrmContractChildService; +import com.skyeye.contract.service.CrmContractService; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.eve.contacts.service.IContactsService; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CrmContractServiceImpl + * @Description: 客户合同管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "合同管理", groupName = "合同管理", flowable = true, teamAuth = true) +public class CrmContractServiceImpl extends SkyeyeFlowableServiceImpl implements CrmContractService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IContactsService iContactsService; + + @Autowired + private CrmContractChildService crmContractChildService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Override + public Class getAuthEnumClass() { + return CrmContractAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmContractAuthEnum.ADD.getKey(), CrmContractAuthEnum.EDIT.getKey(), CrmContractAuthEnum.DELETE.getKey(), + CrmContractAuthEnum.REVOKE.getKey(), CrmContractAuthEnum.INVALID.getKey(), CrmContractAuthEnum.SUBMIT_TO_APPROVAL.getKey(), CrmContractAuthEnum.LIST.getKey(), + CrmContractAuthEnum.PERFORM.getKey(), CrmContractAuthEnum.CLOSE.getKey(), CrmContractAuthEnum.LAY_ASIDE.getKey(), CrmContractAuthEnum.RECOVERY.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getObjectId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContract::getObjectId), commonPageInfo.getObjectId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContract::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + return beans; + } + + @Override + public void validatorEntity(CrmContract entity) { + super.validatorEntity(entity); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(CrmContract entity) { + getTotalPrice(entity); + if (CollectionUtil.isNotEmpty(entity.getCrmContractChildList())) { + entity.setChildState(CrmContractChildStateEnum.PENDING_ORDER.getKey()); + } + super.createPrepose(entity); + } + + @Override + public void updatePrepose(CrmContract entity) { + getTotalPrice(entity); + if (CollectionUtil.isNotEmpty(entity.getCrmContractChildList())) { + entity.setChildState(CrmContractChildStateEnum.PENDING_ORDER.getKey()); + } + } + + private void checkMaterialNorms(CrmContract entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + if (CollectionUtil.isEmpty(entity.getCrmContractChildList())) { + throw new CustomException("合同下无商品信息,请确认."); + } + // TODO 后续关联单据来源查询判断 + } + + private void getTotalPrice(CrmContract entity) { + // 计算关联的产品总价 + String totalPrice = crmContractChildService.calcOrderAllTotalPrice(entity.getCrmContractChildList()); + entity.setMaterialTotalPrice(totalPrice); + } + + @Override + public void writeChild(CrmContract entity, String userId) { + crmContractChildService.saveList(entity.getId(), entity.getCrmContractChildList()); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + crmContractChildService.deleteByParentId(id); + } + + @Override + public CrmContract getDataFromDb(String id) { + CrmContract crmContract = super.getDataFromDb(id); + // 设置合同商品信息 + List crmContractChildList = crmContractChildService.selectByParentId(crmContract.getId()); + crmContract.setCrmContractChildList(crmContractChildList); + return crmContract; + } + + @Override + public CrmContract selectById(String id) { + CrmContract crmContract = super.selectById(id); + Map department = iDepmentService.queryDataMationById(crmContract.getDepartmentId()); + crmContract.setDepartmentMation(department); + // 联系人信息 + iContactsService.setDataMation(crmContract, CrmContract::getContacts); + // 设置关联人员 + crmContract.setRelationUserMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(crmContract.getRelationUserId()))); + // 设置合同商品详情信息 + iMaterialService.setDataMation(crmContract.getCrmContractChildList(), CrmContractChild::getMaterialId); + iMaterialNormsService.setDataMation(crmContract.getCrmContractChildList(), CrmContractChild::getNormsId); + return crmContract; + } + + @Override + public List getDataFromDb(List idList) { + List crmContractList = super.getDataFromDb(idList); + // 设置合同商品信息 + Map> childMap = crmContractChildService.selectByParentId(idList); + crmContractList.forEach(crmContract -> { + crmContract.setCrmContractChildList(childMap.get(crmContract.getId())); + }); + return crmContractList; + } + + @Override + public List selectByIds(String... ids) { + List crmContractList = super.selectByIds(ids); + iDepmentService.setDataMation(crmContractList, CrmContract::getDepartmentId); + // 联系人信息 + iContactsService.setDataMation(crmContractList, CrmContract::getContacts); + // 设置关联人员 + List relationUserIds = crmContractList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getRelationUserId())) + .flatMap(norms -> norms.getRelationUserId().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(relationUserIds)) { + Map> userMap = iAuthUserService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(relationUserIds)); + crmContractList.forEach(crmContract -> { + if (CollectionUtil.isEmpty(crmContract.getRelationUserId())) { + return; + } + List> userMation = new ArrayList<>(); + crmContract.getRelationUserId().forEach(operatorId -> { + if (!userMap.containsKey(operatorId)) { + return; + } + userMation.add(userMap.get(operatorId)); + }); + crmContract.setRelationUserMation(userMation); + }); + } + + // 设置合同商品详情信息 + List materialIds = crmContractList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getCrmContractChildList())) + .flatMap(farm -> farm.getCrmContractChildList().stream().map(CrmContractChild::getMaterialId)).distinct().collect(Collectors.toList()); + List normsIds = crmContractList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getCrmContractChildList())) + .flatMap(farm -> farm.getCrmContractChildList().stream().map(CrmContractChild::getNormsId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(materialIds)) { + Map> materialMap = iMaterialService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(materialIds)); + Map> normsMap = iMaterialNormsService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIds)); + crmContractList.forEach(crmContract -> { + if (CollectionUtil.isNotEmpty(crmContract.getCrmContractChildList())) { + // 合同商品明细不为空 + crmContract.getCrmContractChildList().forEach(crmContractChild -> { + crmContractChild.setMaterialMation(materialMap.get(crmContractChild.getMaterialId())); + crmContractChild.setNormsMation(normsMap.get(crmContractChild.getNormsId())); + }); + } + }); + } + + return crmContractList; + } + + /** + * 根据客户id获取合同列表用于下拉框选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCrmContractListByObjectId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContract::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContract::getState), CrmContractStateEnum.EXECUTING.getKey()); + List crmContractList = list(queryWrapper); + crmContractList.forEach(crmContract -> { + crmContract.setName(crmContract.getTitle()); + }); + outputObject.setBeans(crmContractList); + outputObject.settotal(crmContractList.size()); + } + + /** + * 合同执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void performCrmContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmContract crmContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmContract, userId, CommonNumConstants.NUM_SEVEN); + if (crmContract.getState().equals(FlowableStateEnum.PASS.getKey())) { + // 审核通过可以执行 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getState), CrmContractStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void closeCrmContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmContract crmContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmContract, userId, CommonNumConstants.NUM_EIGHT); + if (crmContract.getState().equals(CrmContractStateEnum.EXECUTING.getKey())) { + // 执行中可以关闭 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getState), CrmContractStateEnum.CLOSE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void shelveCrmContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmContract crmContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmContract, userId, CommonNumConstants.NUM_NINE); + if (crmContract.getState().equals(CrmContractStateEnum.EXECUTING.getKey())) { + // 执行中可以搁置 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getState), CrmContractStateEnum.LAY_ASIDE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同恢复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void recoveryCrmContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmContract crmContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmContract, userId, CommonNumConstants.NUM_TEN); + if (crmContract.getState().equals(CrmContractStateEnum.LAY_ASIDE.getKey())) { + // 搁置中可以恢复 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getState), CrmContractStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据所属第三方业务数据id查询合同信息 + * + * @param objectId 所属第三方业务数据id + * @return + */ + @Override + public List queryCrmContractListByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmContract::getObjectId), objectId); + return list(queryWrapper); + } + + @Override + public void updatePaymentPrice(String id, String paymentPrice) { + CrmContract crmContract = selectById(id); + if (StrUtil.equals(crmContract.getState(), CrmContractStateEnum.EXECUTING.getKey())) { + // 只有执行中的合同才可以进行回款 + paymentPrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, + StrUtil.isEmpty(crmContract.getPaymentPrice()) ? "0" : crmContract.getPaymentPrice(), + paymentPrice); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getPaymentPrice), paymentPrice); + update(updateWrapper); + refreshCache(id); + } else { + throw new CustomException("只有执行中的合同才可以进行回款操作。"); + } + } + + @Override + public void updateInvoicePrice(String id, String invoicePrice) { + CrmContract crmContract = selectById(id); + invoicePrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, + StrUtil.isEmpty(crmContract.getInvoicePrice()) ? "0" : crmContract.getInvoicePrice(), + invoicePrice); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getInvoicePrice), invoicePrice); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void approvalEndIsSuccess(CrmContract entity) { + entity = selectById(entity.getId()); + checkMaterialNorms(entity, true); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editChildState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String childState = params.get("childState").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmContract::getChildState), childState); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/controller/CustomerController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/controller/CustomerController.java new file mode 100644 index 0000000..a8e5ba6 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/controller/CustomerController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.customer.entity.CustomerMation; +import com.skyeye.customer.entity.CustomerQueryDo; +import com.skyeye.customer.service.CustomerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CustomerController + * @Description: 客户信息管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/23 17:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "客户管理", tags = "客户管理", modelName = "客户管理") +public class CustomerController { + + @Autowired + private CustomerService customerService; + + /** + * 获取客户管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "customer001", value = "获取客户管理列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CustomerController/queryCustomerList") + public void queryCustomerList(InputObject inputObject, OutputObject outputObject) { + customerService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑客户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCustomerMation", value = "新增/编辑客户信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CustomerMation.class) + @RequestMapping("/post/CustomerController/writeCustomerMation") + public void writeCustomerMation(InputObject inputObject, OutputObject outputObject) { + customerService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除客户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCustomerMationById", value = "根据id删除客户信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CustomerController/deleteCustomerMationById") + public void deleteCustomerMationById(InputObject inputObject, OutputObject outputObject) { + customerService.deleteById(inputObject, outputObject); + } + + /** + * 根据id批量获取客户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCustomerListByIds", value = "根据id批量获取客户信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/CustomerController/queryCustomerListByIds") + public void queryCustomerListByIds(InputObject inputObject, OutputObject outputObject) { + customerService.selectByIds(inputObject, outputObject); + } + + /** + * 获取公海客户群列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "customer012", value = "获取公海客户群列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CustomerQueryDo.class) + @RequestMapping("/post/CustomerController/queryInternationalCustomerList") + public void queryInternationalCustomerList(InputObject inputObject, OutputObject outputObject) { + customerService.queryInternationalCustomerList(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/dao/CustomerDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/dao/CustomerDao.java new file mode 100644 index 0000000..4e5cbc2 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/dao/CustomerDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.dao; + +import com.skyeye.customer.entity.CustomerMation; +import com.skyeye.customer.entity.CustomerQueryDo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CustomerDao + * @Description: 客户信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CustomerDao extends SkyeyeBaseMapper { + + List> queryInternationalCustomerList(CustomerQueryDo customerQuery); +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerMation.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerMation.java new file mode 100644 index 0000000..0fc3083 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerMation.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: CustomerMation + * @Description: 客户信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.CRM_CUSTOMER_CACHE_KEY) +@TableName(value = "crm_customer", autoResultMap = true) +@ApiModel("客户信息实体类") +public class CustomerMation extends BaseGeneralInfo { + + @TableField(value = "combine") + @ApiModelProperty(value = "拼音") + private String combine; + + @TableField(value = "type_id") + @ApiModelProperty(value = "客户所属分类ID", required = "required") + private String typeId; + + @TableField(value = "from_id") + @ApiModelProperty(value = "客户来源ID", required = "required") + private String fromId; + + @TableField(value = "group_id") + @ApiModelProperty(value = "客户所属分组ID", required = "required") + private String groupId; + + @TableField(value = "industry_id") + @ApiModelProperty(value = "客户所属行业ID", required = "required") + private String industryId; + + @TableField(value = "cus_url") + @ApiModelProperty(value = "客户网址") + private String cusUrl; + + @TableField(value = "country") + @ApiModelProperty(value = "国家/地区") + private String country; + + @TableField(value = "city") + @ApiModelProperty(value = "所在城市") + private String city; + + @TableField(value = "detail_address") + @ApiModelProperty(value = "详细地址") + private String detailAddress; + + @TableField(value = "postal_code") + @ApiModelProperty(value = "邮政编码") + private String postalCode; + + @TableField(value = "fax") + @ApiModelProperty(value = "传真") + private String fax; + + @TableField(value = "cor_representative") + @ApiModelProperty(value = "法人代表") + private String corRepresentative; + + @TableField(value = "reg_capital") + @ApiModelProperty(value = "注册资本") + private String regCapital; + + @TableField(value = "bank_account") + @ApiModelProperty(value = "银行账号") + private String bankAccount; + + @TableField(value = "account_name") + @ApiModelProperty(value = "开户名称") + private String accountName; + + @TableField(value = "bank_name") + @ApiModelProperty(value = "开户银行名称") + private String bankName; + + @TableField(value = "bank_address") + @ApiModelProperty(value = "开户银行地址") + private String bankAddress; + + @TableField(value = "duty_paragraph") + @ApiModelProperty(value = "税号") + private String dutyParagraph; + + @TableField(value = "finance_phone") + @ApiModelProperty(value = "财务电话") + private String financePhone; + + @TableField(value = "team_template_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "团队模板id") + private String teamTemplateId; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerQueryDo.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerQueryDo.java new file mode 100644 index 0000000..662bd84 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/entity/CustomerQueryDo.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: CustomerQueryDo + * @Description: 客户列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("客户列表查询条件实体类") +public class CustomerQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "根据不同的参数查询不同类型的客户。例如:我创建的,我负责的等") + private String type; + + /** + * 团队模板id + */ + private List teamTemplateIds; + + /** + * 未跟单天数 + */ + private String noDocumentaryDayNum; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/CustomerService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/CustomerService.java new file mode 100644 index 0000000..a937e05 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/CustomerService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.customer.entity.CustomerMation; + +public interface CustomerService extends SkyeyeBusinessService { + + void queryInternationalCustomerList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/impl/CustomerServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/impl/CustomerServiceImpl.java new file mode 100644 index 0000000..0fb8df2 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/customer/service/impl/CustomerServiceImpl.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.customer.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.entity.CrmContract; +import com.skyeye.contract.service.CrmContractService; +import com.skyeye.customer.dao.CustomerDao; +import com.skyeye.customer.entity.CustomerMation; +import com.skyeye.customer.entity.CustomerQueryDo; +import com.skyeye.customer.service.CustomerService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.exception.CustomException; +import com.skyeye.opportunity.entity.CrmOpportunity; +import com.skyeye.opportunity.service.CrmOpportunityService; +import com.skyeye.sdk.catalog.service.CatalogSdkService; +import com.skyeye.team.service.ITeamBusinessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CustomerServiceImpl + * @Description: 客户信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "客户管理", groupName = "客户管理") +public class CustomerServiceImpl extends SkyeyeBusinessServiceImpl implements CustomerService, CatalogSdkService { + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Autowired + private ITeamBusinessService iTeamBusinessService; + + @Autowired + private CrmOpportunityService crmOpportunityService; + + @Autowired + private CrmContractService crmContractService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "myCreate")) { + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(CustomerMation::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + } else if (StrUtil.equals(commonPageInfo.getType(), "myCharge")) { + // 我负责的 + List teamTemplateIds = iTeamBusinessService.getMyTeamIds(); + queryWrapper.in(MybatisPlusUtil.toColumns(CustomerMation::getTeamTemplateId), teamTemplateIds); + } + return queryWrapper; + } + + @Override + public void createPostpose(CustomerMation entity, String userId) { + // 创建团队信息 + iTeamBusinessService.createTeamBusiness(entity.getTeamTemplateId(), entity.getId(), getServiceClassName()); + } + + @Override + public void deletePreExecution(String id) { + // 获取与客户相关的合同列表 + List beans = crmContractService.queryCrmContractListByObjectId(id); + if (CollectionUtil.isNotEmpty(beans)) { + throw new CustomException("存在合同信息,无法删除."); + } + // 获取与客户相关的商机列表 + List list = crmOpportunityService.queryCrmOpportunityListByObjectId(id); + if (CollectionUtil.isNotEmpty(list)) { + throw new CustomException("存在商机信息,无法删除."); + } + } + + @Override + public void deletePostpose(String id) { + iTeamBusinessService.deleteTeamBusiness(id, getServiceClassName()); + } + + /** + * 获取公海客户群列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInternationalCustomerList(InputObject inputObject, OutputObject outputObject) { + CustomerQueryDo customerQuery = inputObject.getParams(CustomerQueryDo.class); + Map settings = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + customerQuery.setNoDocumentaryDayNum(settings.get("noDocumentaryDayNum").toString()); + customerQuery.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + Page pages = PageHelper.startPage(customerQuery.getPage(), customerQuery.getLimit()); + + List> beans = skyeyeBaseMapper.queryInternationalCustomerList(customerQuery); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + String serviceClassName = getServiceClassName(); + beans.forEach(bean -> { + bean.put("serviceClassName", serviceClassName); + }); + outputObject.setBean(customerQuery); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/classenum/CrmDocumentaryAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/classenum/CrmDocumentaryAuthEnum.java new file mode 100644 index 0000000..6724d46 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/classenum/CrmDocumentaryAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmDocumentaryAuthEnum + * @Description: 客户跟单权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmDocumentaryAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/controller/CrmDocumentaryController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/controller/CrmDocumentaryController.java new file mode 100644 index 0000000..e20a4d1 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/controller/CrmDocumentaryController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.documentary.entity.Documentary; +import com.skyeye.documentary.service.CrmDocumentaryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CrmDocumentaryController + * @Description: 跟单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 19:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "跟单管理", tags = "跟单管理", modelName = "跟单管理") +public class CrmDocumentaryController { + + @Autowired + private CrmDocumentaryService customerService; + + /** + * 获取跟单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDocumentaryList", value = "获取跟单列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DocumentaryController/queryDocumentaryList") + public void queryDocumentaryList(InputObject inputObject, OutputObject outputObject) { + customerService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑跟单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCrmDocumentary", value = "新增/编辑跟单信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Documentary.class) + @RequestMapping("/post/DocumentaryController/writeCrmDocumentary") + public void writeCrmDocumentary(InputObject inputObject, OutputObject outputObject) { + customerService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除跟单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDocumentaryById", value = "删除跟单信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DocumentaryController/deleteDocumentaryById") + public void deleteDocumentaryById(InputObject inputObject, OutputObject outputObject) { + customerService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/dao/CrmDocumentaryDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/dao/CrmDocumentaryDao.java new file mode 100644 index 0000000..83c7c4b --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/dao/CrmDocumentaryDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.documentary.entity.Documentary; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmDocumentaryDao + * @Description: 跟单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 19:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmDocumentaryDao extends SkyeyeBaseMapper { + + List> queryDocumentaryList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/entity/Documentary.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/entity/Documentary.java new file mode 100644 index 0000000..dda2053 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/entity/Documentary.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.opportunity.entity.CrmOpportunity; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Documentary + * @Description: 跟单信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/27 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "crm:documentary", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "crm_documentary") +@ApiModel("客户跟单信息实体类") +public class Documentary extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField(value = "content") + @ApiModelProperty(value = "详细内容", required = "required") + private String content; + + @TableField(value = "type_id") + @ApiModelProperty(value = "跟单分类ID", required = "required") + private String typeId; + + @TableField(value = "opportunity_id") + @ApiModelProperty(value = "关联商机id", required = "required") + private String opportunityId; + + @TableField(exist = false) + @Property(value = "关联商机信息") + private CrmOpportunity opportunityMation; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人ID", required = "required") + private String contacts; + + @TableField(exist = false) + @Property(value = "联系人") + private Map contactsMation; + + @TableField(value = "documentary_time") + @ApiModelProperty(value = "跟单时间", required = "required") + private String documentaryTime; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/CrmDocumentaryService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/CrmDocumentaryService.java new file mode 100644 index 0000000..36c6c3e --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/CrmDocumentaryService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.documentary.entity.Documentary; + +/** + * @ClassName: CrmDocumentaryService + * @Description: 跟单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 19:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmDocumentaryService extends SkyeyeTeamAuthService { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/impl/CrmDocumentaryServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/impl/CrmDocumentaryServiceImpl.java new file mode 100644 index 0000000..bc86b00 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/documentary/service/impl/CrmDocumentaryServiceImpl.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.documentary.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.documentary.classenum.CrmDocumentaryAuthEnum; +import com.skyeye.documentary.dao.CrmDocumentaryDao; +import com.skyeye.documentary.entity.Documentary; +import com.skyeye.documentary.service.CrmDocumentaryService; +import com.skyeye.eve.contacts.service.IContactsService; +import com.skyeye.exception.CustomException; +import com.skyeye.opportunity.classenum.CrmOpportunityStateEnum; +import com.skyeye.opportunity.entity.CrmOpportunity; +import com.skyeye.opportunity.service.CrmOpportunityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmDocumentaryServiceImpl + * @Description: 服务跟单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "跟单管理", groupName = "跟单管理", teamAuth = true) +public class CrmDocumentaryServiceImpl extends SkyeyeTeamAuthServiceImpl implements CrmDocumentaryService { + + @Autowired + private IContactsService iContactsService; + + @Autowired + private CrmOpportunityService crmOpportunityService; + + @Override + public Class getAuthEnumClass() { + return CrmDocumentaryAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmDocumentaryAuthEnum.ADD.getKey(), CrmDocumentaryAuthEnum.EDIT.getKey(), CrmDocumentaryAuthEnum.DELETE.getKey()); + } + + @Override + public void createPrepose(Documentary entity) { + CrmOpportunity crmOpportunity = crmOpportunityService.selectById(entity.getOpportunityId()); + if (ObjectUtil.isEmpty(crmOpportunity) || StrUtil.isEmpty(crmOpportunity.getId())) { + throw new CustomException("关联的商机不存在。"); + } + // 只有以下状态的商机才可以进行跟单 + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey(), + CrmOpportunityStateEnum.STRIKE_BARGAIN.getKey(), CrmOpportunityStateEnum.LAY_ASIDE.getKey()}); + if (preposeState.indexOf(crmOpportunity.getState()) == -1) { + throw new CustomException("关联的商机状态不可进行跟单。"); + } + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryDocumentaryList(pageInfo); + return beans; + } + + @Override + public Documentary selectById(String id) { + Documentary documentary = super.selectById(id); + // 联系人信息 + iContactsService.setDataMation(documentary, Documentary::getContacts); + // 商机信息 + crmOpportunityService.setDataMation(documentary, Documentary::getOpportunityId); + return documentary; + } +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/classenum/CrmFollowUpAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/classenum/CrmFollowUpAuthEnum.java new file mode 100644 index 0000000..7fb6cf6 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/classenum/CrmFollowUpAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmFollowUpAuthEnum + * @Description: 客户回访权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmFollowUpAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/controller/FollowUpController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/controller/FollowUpController.java new file mode 100644 index 0000000..e032d60 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/controller/FollowUpController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.follow.entity.FollowUp; +import com.skyeye.follow.service.FollowUpService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FollowUpController + * @Description: 客户回访控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "回访管理", tags = "回访管理", modelName = "回访管理") +public class FollowUpController { + + @Autowired + private FollowUpService followUpService; + + /** + * 获取回访列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFollowUpList", value = "获取回访列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FollowUpController/queryFollowUpList") + public void queryFollowUpList(InputObject inputObject, OutputObject outputObject) { + followUpService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑回访信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCrmFollowUp", value = "新增/编辑回访信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = FollowUp.class) + @RequestMapping("/post/FollowUpController/writeCrmFollowUp") + public void writeCrmFollowUp(InputObject inputObject, OutputObject outputObject) { + followUpService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除回访信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFollowUpById", value = "删除回访信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FollowUpController/deleteFollowUpById") + public void deleteFollowUpById(InputObject inputObject, OutputObject outputObject) { + followUpService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/dao/FollowUpDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/dao/FollowUpDao.java new file mode 100644 index 0000000..bdd8126 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/dao/FollowUpDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.follow.entity.FollowUp; + +/** + * @ClassName: FollowUpDao + * @Description: 客户回访数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 10:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FollowUpDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/entity/FollowUp.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/entity/FollowUp.java new file mode 100644 index 0000000..22ee459 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/entity/FollowUp.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: FollowUp + * @Description: 客户回访实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 10:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "crm:follow", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_follow_up") +@ApiModel("客户回访实体类") +public class FollowUp extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property(value = "回访编号", fuzzyLike = true) + private String oddNumber; + + @TableField(value = "follow_time") + @ApiModelProperty(value = "回访时间", required = "required") + private String followTime; + + @TableField(value = "follow_user_id") + @ApiModelProperty(value = "回访人ID", required = "required") + private String followUserId; + + @TableField(exist = false) + @Property(value = "回访人") + private Map followUserMation; + + @TableField(value = "type_id") + @ApiModelProperty(value = "回访形式,参考数据字典") + private String typeId; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人ID", required = "required") + private String contacts; + + @TableField(exist = false) + @Property(value = "联系人") + private Map contactsMation; + + @TableField(value = "contract_id") + @ApiModelProperty(value = "合同ID", required = "required") + private String contractId; + + @TableField(exist = false) + @Property(value = "合同") + private Map contractMation; + + @TableField(value = "satisfaction") + @ApiModelProperty(value = "客户满意度,参考数据字典") + private String satisfaction; + + @TableField(value = "content") + @ApiModelProperty(value = "反馈内容") + private String content; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/FollowUpService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/FollowUpService.java new file mode 100644 index 0000000..9134473 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/FollowUpService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.follow.entity.FollowUp; + +/** + * @ClassName: FollowUpService + * @Description: 客户回访服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 10:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FollowUpService extends SkyeyeTeamAuthService { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/impl/FollowUpServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/impl/FollowUpServiceImpl.java new file mode 100644 index 0000000..66abcaf --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/follow/service/impl/FollowUpServiceImpl.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.follow.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.service.CrmContractService; +import com.skyeye.eve.contacts.service.IContactsService; +import com.skyeye.follow.classenum.CrmFollowUpAuthEnum; +import com.skyeye.follow.dao.FollowUpDao; +import com.skyeye.follow.entity.FollowUp; +import com.skyeye.follow.service.FollowUpService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FollowUpServiceImpl + * @Description: 客户回访服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 10:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "回访管理", groupName = "回访管理", teamAuth = true) +public class FollowUpServiceImpl extends SkyeyeTeamAuthServiceImpl implements FollowUpService { + + @Autowired + private IContactsService iContactsService; + + @Autowired + private CrmContractService crmContractService; + + @Override + public Class getAuthEnumClass() { + return CrmFollowUpAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmFollowUpAuthEnum.ADD.getKey(), CrmFollowUpAuthEnum.EDIT.getKey(), CrmFollowUpAuthEnum.DELETE.getKey()); + } + + @Override + public void createPrepose(FollowUp entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(this.getClass().getName(), business); + entity.setOddNumber(oddNumber); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(FollowUp::getObjectId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iContactsService.setMationForMap(beans, "contacts", "contactsMation"); + crmContractService.setMationForMap(beans, "contractId", "contractMation"); + iAuthUserService.setMationForMap(beans, "followUserId", "followUserMation"); + return beans; + } + + @Override + public FollowUp selectById(String id) { + FollowUp followUp = super.selectById(id); + // 回访人 + iAuthUserService.setDataMation(followUp, FollowUp::getFollowUserId); + // 联系人信息 + iContactsService.setDataMation(followUp, FollowUp::getContacts); + // 合同信息 + crmContractService.setDataMation(followUp, FollowUp::getContractId); + return followUp; + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceAuthEnum.java new file mode 100644 index 0000000..81ebb68 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceAuthEnum.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmInvoiceAuthEnum + * @Description: 客户发票权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmInvoiceAuthEnum implements SkyeyeEnumClass { + + LIST("list", "查看列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceHeaderAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceHeaderAuthEnum.java new file mode 100644 index 0000000..82e1022 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/classenum/CrmInvoiceHeaderAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmInvoiceHeaderAuthEnum + * @Description: 客户发票抬头权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmInvoiceHeaderAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceController.java new file mode 100644 index 0000000..216d55f --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceController.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.invoice.entity.Invoice; +import com.skyeye.invoice.service.InvoiceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InvoiceController + * @Description: 发票控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 19:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "发票管理", tags = "发票管理", modelName = "发票管理") +public class InvoiceController { + + @Autowired + private InvoiceService invoiceService; + + /** + * 获取发票列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInvoiceList", value = "获取发票列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InvoiceController/queryInvoiceList") + public void queryInvoiceList(InputObject inputObject, OutputObject outputObject) { + invoiceService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑发票信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeInvoice", value = "新增/编辑发票信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Invoice.class) + @RequestMapping("/post/InvoiceController/writeInvoice") + public void writeInvoice(InputObject inputObject, OutputObject outputObject) { + invoiceService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除发票信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteInvoiceById", value = "删除发票信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InvoiceController/deleteInvoiceById") + public void deleteInvoiceById(InputObject inputObject, OutputObject outputObject) { + invoiceService.deleteById(inputObject, outputObject); + } + + /** + * 发票提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitInvoiceToApproval", value = "发票提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/InvoiceController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + invoiceService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废发票信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidInvoice", value = "作废发票信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InvoiceController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + invoiceService.invalid(inputObject, outputObject); + } + + /** + * 撤销发票审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeInvoice", value = "撤销发票审批", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/InvoiceController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + invoiceService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceHeaderController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceHeaderController.java new file mode 100644 index 0000000..3bd2e44 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/controller/InvoiceHeaderController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.invoice.entity.InvoiceHeader; +import com.skyeye.invoice.service.InvoiceHeaderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InvoiceHeaderController + * @Description: 发票抬头控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 14:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "发票抬头管理", tags = "发票抬头管理", modelName = "发票抬头管理") +public class InvoiceHeaderController { + + @Autowired + private InvoiceHeaderService invoiceHeaderService; + + /** + * 获取发票抬头列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInvoiceHeaderList", value = "获取发票抬头列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InvoiceHeaderController/queryInvoiceHeaderList") + public void queryInvoiceHeaderList(InputObject inputObject, OutputObject outputObject) { + invoiceHeaderService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑发票抬头信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCrmInvoiceHeader", value = "新增/编辑发票抬头信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = InvoiceHeader.class) + @RequestMapping("/post/InvoiceHeaderController/writeCrmInvoiceHeader") + public void writeCrmInvoiceHeader(InputObject inputObject, OutputObject outputObject) { + invoiceHeaderService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除发票抬头信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteInvoiceHeaderById", value = "删除发票抬头信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InvoiceHeaderController/deleteInvoiceHeaderById") + public void deleteInvoiceHeaderById(InputObject inputObject, OutputObject outputObject) { + invoiceHeaderService.deleteById(inputObject, outputObject); + } + + /** + * 根据客户id获取发票抬头列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInvoiceHeaderByObjectId", value = "根据客户id获取发票抬头列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id")}) + @RequestMapping("/post/InvoiceHeaderController/queryInvoiceHeaderByObjectId") + public void queryInvoiceHeaderByObjectId(InputObject inputObject, OutputObject outputObject) { + invoiceHeaderService.queryInvoiceHeaderByObjectId(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceDao.java new file mode 100644 index 0000000..38febd8 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.invoice.entity.Invoice; + +/** + * @ClassName: InvoiceDao + * @Description: 发票数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 19:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InvoiceDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceHeaderDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceHeaderDao.java new file mode 100644 index 0000000..f68e4cb --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/dao/InvoiceHeaderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.invoice.entity.InvoiceHeader; + +/** + * @ClassName: InvoiceHeaderDao + * @Description: 发票抬头数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 14:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InvoiceHeaderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/Invoice.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/Invoice.java new file mode 100644 index 0000000..eef7f9d --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/Invoice.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.payment.entity.PaymentCollection; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Invoice + * @Description: 发票实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 19:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "crm:invoice", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_invoice", autoResultMap = true) +@ApiModel("发票实体类") +public class Invoice extends SkyeyeFlowable { + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(value = "contract_id") + @ApiModelProperty(value = "合同ID", required = "required") + private String contractId; + + @TableField(exist = false) + @Property(value = "合同") + private Map contractMation; + + @TableField(value = "invoic_time") + @ApiModelProperty(value = "开票日期", required = "required") + private String invoicTime; + + @TableField(value = "type_id") + @ApiModelProperty(value = "开票类型,参考数据字典") + private String typeId; + + @TableField(value = "price") + @ApiModelProperty(value = "开票金额", required = "double", defaultValue = "0") + private String price; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "invoice_header_id") + @ApiModelProperty(value = "发票抬头id", required = "required") + private String invoiceHeaderId; + + @TableField(exist = false) + @Property(value = "发票抬头") + private InvoiceHeader invoiceHeaderMation; + + @TableField(value = "payment_collection_id") + @ApiModelProperty(value = "回款id", required = "required") + private String paymentCollectionId; + + @TableField(exist = false) + @Property(value = "回款") + private PaymentCollection paymentCollectionMation; + + @TableField("mail_contacts_name") + @ApiModelProperty(value = "邮寄-联系人名字") + private String mailContactsName; + + @TableField("mail_phone") + @ApiModelProperty(value = "邮寄-联系方式") + private String mailPhone; + + @TableField("province_id") + @ApiModelProperty(value = "邮寄-省ID") + private String provinceId; + + @TableField(exist = false) + @Property(value = "省信息") + private Map provinceMation; + + @TableField("city_id") + @ApiModelProperty(value = "邮寄-市ID") + private String cityId; + + @TableField(exist = false) + @Property(value = "市信息") + private Map cityMation; + + @TableField("area_id") + @ApiModelProperty(value = "邮寄-区县ID") + private String areaId; + + @TableField(exist = false) + @Property(value = "区/县信息") + private Map areaMation; + + @TableField("township_id") + @ApiModelProperty(value = "邮寄-乡镇ID") + private String townshipId; + + @TableField(exist = false) + @Property(value = "乡镇信息") + private Map townshipMation; + + @TableField("absolute_address") + @ApiModelProperty(value = "邮寄-具体地址") + private String absoluteAddress; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/InvoiceHeader.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/InvoiceHeader.java new file mode 100644 index 0000000..e5c70b3 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/entity/InvoiceHeader.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: InvoiceHeader + * @Description: 发票抬头实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 14:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "crm:invoiceHeader", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_invoice_header") +@ApiModel("发票抬头实体类") +public class InvoiceHeader extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "发票抬头", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "identification_number") + @ApiModelProperty(value = "纳税识别号", fuzzyLike = true) + private String identificationNumber; + + @TableField(value = "opening_bank") + @ApiModelProperty(value = "开户行") + private String openingBank; + + @TableField(value = "opening_account") + @ApiModelProperty(value = "开户帐号") + private String openingAccount; + + @TableField(value = "billing_address") + @ApiModelProperty(value = "开票地址") + private String billingAddress; + + @TableField(value = "phone") + @ApiModelProperty(value = "电话") + private String phone; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceHeaderService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceHeaderService.java new file mode 100644 index 0000000..f6c2750 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceHeaderService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.invoice.entity.InvoiceHeader; + +/** + * @ClassName: InvoiceHeaderService + * @Description: 发票抬头服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 14:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InvoiceHeaderService extends SkyeyeTeamAuthService { + + void queryInvoiceHeaderByObjectId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceService.java new file mode 100644 index 0000000..b9969c7 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/InvoiceService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.invoice.entity.Invoice; + +/** + * @ClassName: InvoiceService + * @Description: 发票服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 19:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InvoiceService extends SkyeyeFlowableService { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceHeaderServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceHeaderServiceImpl.java new file mode 100644 index 0000000..768303b --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceHeaderServiceImpl.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.invoice.classenum.CrmInvoiceHeaderAuthEnum; +import com.skyeye.invoice.dao.InvoiceHeaderDao; +import com.skyeye.invoice.entity.InvoiceHeader; +import com.skyeye.invoice.service.InvoiceHeaderService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InvoiceHeaderServiceImpl + * @Description: 发票抬头服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 14:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "发票抬头管理", groupName = "发票抬头管理", teamAuth = true) +public class InvoiceHeaderServiceImpl extends SkyeyeTeamAuthServiceImpl implements InvoiceHeaderService { + + @Override + public Class getAuthEnumClass() { + return CrmInvoiceHeaderAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmInvoiceHeaderAuthEnum.ADD.getKey(), CrmInvoiceHeaderAuthEnum.EDIT.getKey(), CrmInvoiceHeaderAuthEnum.DELETE.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(InvoiceHeader::getObjectId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public void queryInvoiceHeaderByObjectId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(InvoiceHeader::getObjectId), objectId); + List invoiceHeaders = list(queryWrapper); + outputObject.setBeans(invoiceHeaders); + outputObject.settotal(invoiceHeaders.size()); + } +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceServiceImpl.java new file mode 100644 index 0000000..c0662f6 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/invoice/service/impl/InvoiceServiceImpl.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.invoice.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.service.CrmContractService; +import com.skyeye.eve.service.IAreaService; +import com.skyeye.invoice.classenum.CrmInvoiceAuthEnum; +import com.skyeye.invoice.dao.InvoiceDao; +import com.skyeye.invoice.entity.Invoice; +import com.skyeye.invoice.service.InvoiceHeaderService; +import com.skyeye.invoice.service.InvoiceService; +import com.skyeye.payment.service.PaymentCollectionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InvoiceServiceImpl + * @Description: 发票服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/3 19:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "发票管理", groupName = "发票管理", teamAuth = true, flowable = true) +public class InvoiceServiceImpl extends SkyeyeFlowableServiceImpl implements InvoiceService { + + @Autowired + private CrmContractService crmContractService; + + @Autowired + private PaymentCollectionService paymentCollectionService; + + @Autowired + private InvoiceHeaderService invoiceHeaderService; + + @Autowired + private IAreaService iAreaService; + + @Override + public Class getAuthEnumClass() { + return CrmInvoiceAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmInvoiceAuthEnum.ADD.getKey(), CrmInvoiceAuthEnum.EDIT.getKey(), CrmInvoiceAuthEnum.DELETE.getKey(), + CrmInvoiceAuthEnum.REVOKE.getKey(), CrmInvoiceAuthEnum.INVALID.getKey(), CrmInvoiceAuthEnum.SUBMIT_TO_APPROVAL.getKey(), + CrmInvoiceAuthEnum.LIST.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Invoice::getObjectId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + crmContractService.setMationForMap(beans, "contractId", "contractMation"); + paymentCollectionService.setMationForMap(beans, "paymentCollectionId", "paymentCollectionMation"); + invoiceHeaderService.setMationForMap(beans, "invoiceHeaderId", "invoiceHeaderMation"); + return beans; + } + + @Override + public Invoice selectById(String id) { + Invoice invoice = super.selectById(id); + // 合同信息 + crmContractService.setDataMation(invoice, Invoice::getContractId); + // 回款信息 + paymentCollectionService.setDataMation(invoice, Invoice::getPaymentCollectionId); + // 发票抬头 + invoiceHeaderService.setDataMation(invoice, Invoice::getInvoiceHeaderId); + iAreaService.setDataMation(invoice, Invoice::getProvinceId); + iAreaService.setDataMation(invoice, Invoice::getCityId); + iAreaService.setDataMation(invoice, Invoice::getAreaId); + iAreaService.setDataMation(invoice, Invoice::getTownshipId); + return invoice; + } + + @Override + public void approvalEndIsSuccess(Invoice entity) { + // 修改回款的开票金额 + paymentCollectionService.updateInvoicePrice(entity.getPaymentCollectionId(), entity.getPrice()); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityAuthEnum.java new file mode 100644 index 0000000..b22212a --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityAuthEnum.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmOpportunityAuthEnum + * @Description: 客户商机权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmOpportunityAuthEnum implements SkyeyeEnumClass { + + LIST("list", "查看列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false), + + CONMUNICATE("conmunicate", "初期沟通", true, false), + QUOTED_PRICE("quotedPrice", "方案与报价", true, false), + TENDER("tender", "竞争与投标", true, false), + NEGOTIATE("negotiate", "商务谈判", true, false), + TURNOVER("turnover", "成交", true, false), + LOSING_TABLE("losingTable", "丢单", true, false), + LAY_ASIDE("layAside", "搁置", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityStateEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityStateEnum.java new file mode 100644 index 0000000..b2ba431 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/classenum/CrmOpportunityStateEnum.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: CrmOpportunityStateEnum + * @Description: 客户商机状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmOpportunityStateEnum implements SkyeyeEnumClass { + + INITIAL_COMMUNICATION("initialCommunication", "初期沟通", true, false), + SCHEME_AND_QUOTATION("schemeAndQuotation", "方案与报价", true, false), + COMPETITION_AND_BIDDING("competitionAndBidding", "竞争与投标", true, false), + BUSINESS_NEGOTIATION("businessNegotiation", "商务谈判", true, false), + STRIKE_BARGAIN("strikeBargain", "成交", true, false), + LOST_ORDER("lostOrder", "丢单", true, false), + LAY_ASIDE("layAside", "搁置", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/controller/CrmOpportunityController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/controller/CrmOpportunityController.java new file mode 100644 index 0000000..cbe28ed --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/controller/CrmOpportunityController.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.opportunity.entity.CrmOpportunity; +import com.skyeye.opportunity.service.CrmOpportunityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CrmOpportunityController + * @Description: 商机管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商机管理", tags = "商机管理", modelName = "商机管理") +public class CrmOpportunityController { + + @Autowired + private CrmOpportunityService crmOpportunityService; + + /** + * 获取商机列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCrmOpportunityList", value = "获取商机列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CrmOpportunityController/queryCrmOpportunityList") + public void queryCrmOpportunityList(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑商机信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCrmOpportunity", value = "新增/编辑商机信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CrmOpportunity.class) + @RequestMapping("/post/CrmOpportunityController/writeCrmOpportunity") + public void writeCrmOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除商机信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCrmOpportunityById", value = "删除商机信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/deleteCrmOpportunityById") + public void deleteCrmOpportunityById(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.deleteById(inputObject, outputObject); + } + + /** + * 根据客户id获取指定状态的商机列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCrmOpportunityListByObjectId", value = "根据客户id获取指定状态的商机列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id")}) + @RequestMapping("/post/CrmOpportunityController/queryCrmOpportunityListByObjectId") + public void queryCrmOpportunityListByObjectId(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.queryCrmOpportunityListByObjectId(inputObject, outputObject); + } + + /** + * 作废商机信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity013", value = "作废商机信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.invalid(inputObject, outputObject); + } + + /** + * 商机提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity017", value = "商机提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销商机审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity027", value = "撤销商机审批", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.revoke(inputObject, outputObject); + } + + /** + * 根据商机Id初期沟通 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity019", value = "根据商机Id初期沟通", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/conmunicateOpportunity") + public void conmunicateOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.conmunicateOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id方案与报价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity020", value = "根据商机Id方案与报价", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/quotedPriceOpportunity") + public void quotedPriceOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.quotedPriceOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id竞争与投标 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity021", value = "根据商机Id竞争与投标", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/tenderOpportunity") + public void tenderOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.tenderOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id商务谈判 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity022", value = "根据商机Id商务谈判", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/negotiateOpportunity") + public void negotiateOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.negotiateOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id成交 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity023", value = "根据商机Id成交", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/turnoverOpportunity") + public void turnoverOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.turnoverOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id丢单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity024", value = "根据商机Id丢单", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/losingTableOpportunity") + public void losingTableOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.losingTableOpportunity(inputObject, outputObject); + } + + /** + * 根据商机Id搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "opportunity025", value = "根据商机Id搁置", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CrmOpportunityController/layAsideOpportunity") + public void layAsideOpportunity(InputObject inputObject, OutputObject outputObject) { + crmOpportunityService.layAsideOpportunity(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/dao/CrmOpportunityDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/dao/CrmOpportunityDao.java new file mode 100644 index 0000000..a3a7ed5 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/dao/CrmOpportunityDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.opportunity.entity.CrmOpportunity; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmOpportunityDao + * @Description: 客户商机管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmOpportunityDao extends SkyeyeBaseMapper { + + List> queryCrmOpportunityList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/entity/CrmOpportunity.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/entity/CrmOpportunity.java new file mode 100644 index 0000000..da2e36b --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/entity/CrmOpportunity.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CrmOpportunity + * @Description: 商机实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "title"}) +@RedisCacheField(name = "crm:opportunity", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "crm_opportunity", autoResultMap = true) +@ApiModel("商机实体类") +public class CrmOpportunity extends SkyeyeFlowable { + + @TableField(value = "object_id", fill = FieldFill.INSERT) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", fill = FieldFill.INSERT) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(value = "title") + @ApiModelProperty(value = "商机名称", required = "required") + private String title; + + @TableField(value = "from_id") + @ApiModelProperty(value = "商机来源ID", required = "required") + private String fromId; + + @TableField(value = "estimate_price") + @ApiModelProperty(value = "预计成交金额", required = "required,double") + private String estimatePrice; + + @TableField(value = "estimate_end_time") + @ApiModelProperty(value = "预计结单日期") + private String estimateEndTime; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人ID", required = "required") + private String contacts; + + @TableField(exist = false) + @Property(value = "联系人") + private Map contactsMation; + + @TableField(value = "business_need") + @ApiModelProperty(value = "主要业务需求") + private String businessNeed; + + @TableField(value = "department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Map departmentMation; + + @TableField(value = "respons_id") + @ApiModelProperty(value = "商机负责人ID", required = "required") + private String responsId; + + @TableField(exist = false) + @Property(value = "商机负责人") + private Map responsMation; + + @TableField(value = "part_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "商机参与人ID") + private List partId; + + @TableField(exist = false) + @Property(value = "商机参与人") + private List> partMation; + + @TableField(value = "follow_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "商机关注人ID") + private List followId; + + @TableField(exist = false) + @Property(value = "商机关注人") + private List> followMation; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/CrmOpportunityService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/CrmOpportunityService.java new file mode 100644 index 0000000..2893b88 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/CrmOpportunityService.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.opportunity.entity.CrmOpportunity; + +import java.util.List; + +/** + * @ClassName: CrmOpportunityService + * @Description: 商机管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CrmOpportunityService extends SkyeyeFlowableService { + + void conmunicateOpportunity(InputObject inputObject, OutputObject outputObject); + + void quotedPriceOpportunity(InputObject inputObject, OutputObject outputObject); + + void tenderOpportunity(InputObject inputObject, OutputObject outputObject); + + void negotiateOpportunity(InputObject inputObject, OutputObject outputObject); + + void turnoverOpportunity(InputObject inputObject, OutputObject outputObject); + + void losingTableOpportunity(InputObject inputObject, OutputObject outputObject); + + void layAsideOpportunity(InputObject inputObject, OutputObject outputObject); + + List queryCrmOpportunityListByObjectId(String objectId); + + void queryCrmOpportunityListByObjectId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/impl/CrmOpportunityServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/impl/CrmOpportunityServiceImpl.java new file mode 100644 index 0000000..b2ed7e0 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/opportunity/service/impl/CrmOpportunityServiceImpl.java @@ -0,0 +1,339 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.opportunity.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.contacts.service.IContactsService; +import com.skyeye.opportunity.classenum.CrmOpportunityAuthEnum; +import com.skyeye.opportunity.classenum.CrmOpportunityStateEnum; +import com.skyeye.opportunity.dao.CrmOpportunityDao; +import com.skyeye.opportunity.entity.CrmOpportunity; +import com.skyeye.opportunity.service.CrmOpportunityService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CrmOpportunityServiceImpl + * @Description: 客户商机管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "商机管理", groupName = "商机管理", flowable = true, teamAuth = true) +public class CrmOpportunityServiceImpl extends SkyeyeFlowableServiceImpl implements CrmOpportunityService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IContactsService iContactsService; + + @Override + public Class getAuthEnumClass() { + return CrmOpportunityAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmOpportunityAuthEnum.ADD.getKey(), CrmOpportunityAuthEnum.EDIT.getKey(), CrmOpportunityAuthEnum.DELETE.getKey(), + CrmOpportunityAuthEnum.REVOKE.getKey(), CrmOpportunityAuthEnum.INVALID.getKey(), CrmOpportunityAuthEnum.SUBMIT_TO_APPROVAL.getKey(), CrmOpportunityAuthEnum.LIST.getKey(), + CrmOpportunityAuthEnum.CONMUNICATE.getKey(), CrmOpportunityAuthEnum.QUOTED_PRICE.getKey(), CrmOpportunityAuthEnum.TENDER.getKey(), CrmOpportunityAuthEnum.NEGOTIATE.getKey(), + CrmOpportunityAuthEnum.TURNOVER.getKey(), CrmOpportunityAuthEnum.LOSING_TABLE.getKey(), CrmOpportunityAuthEnum.LAY_ASIDE.getKey()); + } + + @Override + public List> queryPageData(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryCrmOpportunityList(pageInfo); + return beans; + } + + @Override + public CrmOpportunity selectById(String id) { + CrmOpportunity crmOpportunity = super.selectById(id); + Map department = iDepmentService.queryDataMationById(crmOpportunity.getDepartmentId()); + crmOpportunity.setDepartmentMation(department); + + // 联系人信息 + iContactsService.setDataMation(crmOpportunity, CrmOpportunity::getContacts); + + crmOpportunity.setFollowMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(crmOpportunity.getFollowId()))); + crmOpportunity.setPartMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(crmOpportunity.getPartId()))); + crmOpportunity.setResponsMation(iAuthUserService.queryDataMationById(crmOpportunity.getResponsId())); + + return crmOpportunity; + } + + /** + * 根据商机Id初期沟通 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void conmunicateOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_SEVEN); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), + CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey(), CrmOpportunityStateEnum.LAY_ASIDE.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、方案与报价、竞争与投标、商务谈判、搁置状态下可以初期沟通 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id方案与报价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void quotedPriceOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_EIGHT); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、竞争与投标、商务谈判状态下可以方案与报价 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id竞争与投标 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void tenderOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_NINE); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、方案与报价、商务谈判状态下可以竞争与投标 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id商务谈判 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void negotiateOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_TEN); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、方案与报价、竞争与投标状态下可以商务谈判 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id成交 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void turnoverOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_ELEVEN); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、方案与报价、竞争与投标、商务谈判状态下可以成交 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.STRIKE_BARGAIN.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id丢单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void losingTableOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_TWELVE); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey(), + CrmOpportunityStateEnum.LAY_ASIDE.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、方案与报价、竞争与投标、商务谈判、搁置状态下可以丢单 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.LOST_ORDER.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据商机Id搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void layAsideOpportunity(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + CrmOpportunity crmOpportunity = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(crmOpportunity, userId, CommonNumConstants.NUM_THIRTEEN); + + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey()}); + if (preposeState.contains(crmOpportunity.getState())) { + // 审核通过、初期沟通、方案与报价、竞争与投标、商务谈判状态下可以搁置 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(CrmOpportunity::getState), CrmOpportunityStateEnum.LAY_ASIDE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据所属第三方业务数据id查询商机 + * + * @param objectId 所属第三方业务数据id + * @return + */ + @Override + public List queryCrmOpportunityListByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CrmOpportunity::getObjectId), objectId); + return list(queryWrapper); + } + + /** + * 根据客户id获取指定状态的商机列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCrmOpportunityListByObjectId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + List crmOpportunityList = queryCrmOpportunityListByObjectId(objectId); + // 过滤状态 + List preposeState = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), CrmOpportunityStateEnum.INITIAL_COMMUNICATION.getKey(), + CrmOpportunityStateEnum.SCHEME_AND_QUOTATION.getKey(), CrmOpportunityStateEnum.COMPETITION_AND_BIDDING.getKey(), CrmOpportunityStateEnum.BUSINESS_NEGOTIATION.getKey(), + CrmOpportunityStateEnum.STRIKE_BARGAIN.getKey(), CrmOpportunityStateEnum.LAY_ASIDE.getKey()}); + + List> results = crmOpportunityList.stream() + .filter(crmOpportunity -> preposeState.indexOf(crmOpportunity.getState()) >= 0) + .map(crmOpportunity -> BeanUtil.beanToMap(crmOpportunity)).collect(Collectors.toList()); + results.forEach(bean -> { + bean.put("name", bean.get("title")); + }); + outputObject.setBeans(results); + outputObject.settotal(results.size()); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/classenum/CrmPaymentCollectionAuthEnum.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/classenum/CrmPaymentCollectionAuthEnum.java new file mode 100644 index 0000000..93bbfd3 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/classenum/CrmPaymentCollectionAuthEnum.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CrmPaymentCollectionAuthEnum + * @Description: 客户回款权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CrmPaymentCollectionAuthEnum implements SkyeyeEnumClass { + + LIST("list", "查看列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/controller/PaymentCollectionController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/controller/PaymentCollectionController.java new file mode 100644 index 0000000..251714d --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/controller/PaymentCollectionController.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.payment.entity.PaymentCollection; +import com.skyeye.payment.service.PaymentCollectionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PaymentCollectionController + * @Description: 回款管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 20:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "回款管理", tags = "回款管理", modelName = "回款管理") +public class PaymentCollectionController { + + @Autowired + private PaymentCollectionService paymentCollectionService; + + /** + * 获取回款列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPaymentCollectionList", value = "获取回款列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PaymentCollectionController/queryPaymentCollectionList") + public void queryPaymentCollectionList(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑回款信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePaymentCollection", value = "新增/编辑回款信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = PaymentCollection.class) + @RequestMapping("/post/PaymentCollectionController/writePaymentCollection") + public void writePaymentCollection(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除回款信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePaymentCollectionById", value = "删除回款信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PaymentCollectionController/deletePaymentCollectionById") + public void deletePaymentCollectionById(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.deleteById(inputObject, outputObject); + } + + /** + * 回款提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitPaymentCollectionToApproval", value = "回款提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/PaymentCollectionController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废回款信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidPaymentCollection", value = "作废回款信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PaymentCollectionController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.invalid(inputObject, outputObject); + } + + /** + * 撤销回款审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokePaymentCollection", value = "撤销回款审批", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/PaymentCollectionController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.revoke(inputObject, outputObject); + } + + /** + * 根据合同id获取回款列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPaymentCollectionByContractId", value = "根据合同id获取回款列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "contractId", name = "contractId", value = "合同id")}) + @RequestMapping("/post/PaymentCollectionController/queryPaymentCollectionByContractId") + public void queryPaymentCollectionByContractId(InputObject inputObject, OutputObject outputObject) { + paymentCollectionService.queryPaymentCollectionByContractId(inputObject, outputObject); + } +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/dao/PaymentCollectionDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/dao/PaymentCollectionDao.java new file mode 100644 index 0000000..f85bbbe --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/dao/PaymentCollectionDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.payment.entity.PaymentCollection; + +/** + * @ClassName: PaymentCollectionDao + * @Description: 回款数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 20:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PaymentCollectionDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/entity/PaymentCollection.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/entity/PaymentCollection.java new file mode 100644 index 0000000..e5d2fd2 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/entity/PaymentCollection.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: PaymentCollection + * @Description: 回款实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 20:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "crm:payment", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_payment_collection", autoResultMap = true) +@ApiModel("回款实体类") +public class PaymentCollection extends SkyeyeFlowable { + + @TableField(exist = false) + @Property(value = "单号,仅用于展示使用") + private String name; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(value = "collection_time") + @ApiModelProperty(value = "回款日期", required = "required") + private String collectionTime; + + @TableField(value = "contract_id") + @ApiModelProperty(value = "合同ID", required = "required") + private String contractId; + + @TableField(exist = false) + @Property(value = "合同") + private Map contractMation; + + @TableField(value = "type_id") + @ApiModelProperty(value = "回款方式,参考数据字典") + private String typeId; + + @TableField(value = "price") + @ApiModelProperty(value = "回款金额", required = "double", defaultValue = "0") + private String price; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "invoice_price") + @Property(value = "已开票金额") + private String invoicePrice; + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/PaymentCollectionService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/PaymentCollectionService.java new file mode 100644 index 0000000..b5e0121 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/PaymentCollectionService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.payment.entity.PaymentCollection; + +/** + * @ClassName: PaymentCollectionService + * @Description: 回款服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 20:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PaymentCollectionService extends SkyeyeFlowableService { + + void queryPaymentCollectionByContractId(InputObject inputObject, OutputObject outputObject); + + /** + * 修改已开票金额 + * + * @param id + * @param invoicePrice + */ + void updateInvoicePrice(String id, String invoicePrice); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/impl/PaymentCollectionServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/impl/PaymentCollectionServiceImpl.java new file mode 100644 index 0000000..656b1ff --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/payment/service/impl/PaymentCollectionServiceImpl.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.payment.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.service.CrmContractService; +import com.skyeye.payment.classenum.CrmPaymentCollectionAuthEnum; +import com.skyeye.payment.dao.PaymentCollectionDao; +import com.skyeye.payment.entity.PaymentCollection; +import com.skyeye.payment.service.PaymentCollectionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PaymentCollectionServiceImpl + * @Description: 回款服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/2 20:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "回款管理", groupName = "回款管理", flowable = true, teamAuth = true) +public class PaymentCollectionServiceImpl extends SkyeyeFlowableServiceImpl implements PaymentCollectionService { + + @Autowired + private CrmContractService crmContractService; + + @Override + public Class getAuthEnumClass() { + return CrmPaymentCollectionAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(CrmPaymentCollectionAuthEnum.ADD.getKey(), CrmPaymentCollectionAuthEnum.EDIT.getKey(), CrmPaymentCollectionAuthEnum.DELETE.getKey(), + CrmPaymentCollectionAuthEnum.REVOKE.getKey(), CrmPaymentCollectionAuthEnum.INVALID.getKey(), CrmPaymentCollectionAuthEnum.SUBMIT_TO_APPROVAL.getKey(), + CrmPaymentCollectionAuthEnum.LIST.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(PaymentCollection::getObjectId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + crmContractService.setMationForMap(beans, "contractId", "contractMation"); + return beans; + } + + @Override + public PaymentCollection selectById(String id) { + PaymentCollection paymentCollection = super.selectById(id); + paymentCollection.setName(paymentCollection.getOddNumber()); + // 合同信息 + crmContractService.setDataMation(paymentCollection, PaymentCollection::getContractId); + return paymentCollection; + } + + @Override + public void queryPaymentCollectionByContractId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String contractId = map.get("contractId").toString(); + if (StrUtil.isEmpty(contractId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PaymentCollection::getContractId), contractId); + queryWrapper.eq(MybatisPlusUtil.toColumns(PaymentCollection::getState), FlowableStateEnum.PASS.getKey()); + List paymentCollections = list(queryWrapper); + paymentCollections.forEach(paymentCollection -> { + paymentCollection.setName(paymentCollection.getOddNumber()); + }); + outputObject.setBeans(paymentCollections); + outputObject.settotal(paymentCollections.size()); + } + + @Override + public void approvalEndIsSuccess(PaymentCollection entity) { + // 修改合同的回款金额 + crmContractService.updatePaymentPrice(entity.getContractId(), entity.getPrice()); + } + + @Override + public void updateInvoicePrice(String id, String invoicePrice) { + PaymentCollection paymentCollection = selectById(id); + String newInvoicePrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, + StrUtil.isEmpty(paymentCollection.getInvoicePrice()) ? "0" : paymentCollection.getInvoicePrice(), + invoicePrice); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(PaymentCollection::getInvoicePrice), newInvoicePrice); + update(updateWrapper); + refreshCache(id); + // 修改合同的开票金额 + crmContractService.updateInvoicePrice(paymentCollection.getContractId(), invoicePrice); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/controller/CrmPageController.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/controller/CrmPageController.java new file mode 100644 index 0000000..dab4e56 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/controller/CrmPageController.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.statis.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.statis.service.CrmPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "CRM统计", tags = "CRM统计", modelName = "统计模块") +public class CrmPageController { + + @Autowired + private CrmPageService crmPageService; + + /** + * 获取指定年度的客户新增量,联系人新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "crmpage001", value = "获取指定年度的客户新增量,联系人新增量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "year", name = "year", value = "指定年度", required = "required")}) + @RequestMapping("/post/CrmPageController/queryInsertNumByYear") + public void queryInsertNumByYear(InputObject inputObject, OutputObject outputObject) { + crmPageService.queryInsertNumByYear(inputObject, outputObject); + } + + /** + * 根据客户分类,客户来源,所属行业,客户分组统计客户数量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "crmpage002", value = "根据客户分类,客户来源,所属行业,客户分组统计客户数量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "crmCustomerType", name = "crmCustomerType", value = "客户分类的code", required = "required"), + @ApiImplicitParam(id = "crmCustomerFrom", name = "crmCustomerFrom", value = "客户来源的code", required = "required"), + @ApiImplicitParam(id = "crmCustomerIndustry", name = "crmCustomerIndustry", value = "所属行业的code", required = "required"), + @ApiImplicitParam(id = "crmCustomerGroup", name = "crmCustomerGroup", value = "客户分组的code", required = "required")}) + @RequestMapping("/post/CrmPageController/queryCustomNumByOtherType") + public void queryCustomNumByOtherType(InputObject inputObject, OutputObject outputObject) { + crmPageService.queryCustomNumByOtherType(inputObject, outputObject); + } + + /** + * 客户跟单方式分析 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "crmpage003", value = "客户跟单方式分析", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "year", name = "year", value = "指定年度", required = "required"), + @ApiImplicitParam(id = "crmDocumentaryType", name = "crmDocumentaryType", value = "跟单方式code", required = "required")}) + @RequestMapping("/post/CrmPageController/queryCustomDocumentaryType") + public void queryCustomDocumentaryType(InputObject inputObject, OutputObject outputObject) { + crmPageService.queryCustomDocumentaryType(inputObject, outputObject); + } + + /** + * 获取合同在指定年度的月新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "crmpage004", value = "获取合同在指定年度的月新增量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "year", name = "year", value = "指定年度", required = "required")}) + @RequestMapping("/post/CrmPageController/queryNewContractNum") + public void queryNewContractNum(InputObject inputObject, OutputObject outputObject) { + crmPageService.queryNewContractNum(inputObject, outputObject); + } + + /** + * 获取员工跟单在指定年度的月新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "crmpage005", value = "获取员工跟单在指定年度的月新增量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "year", name = "year", value = "指定年度", required = "required")}) + @RequestMapping("/post/CrmPageController/queryNewDocumentaryNum") + public void queryNewDocumentaryNum(InputObject inputObject, OutputObject outputObject) { + crmPageService.queryNewDocumentaryNum(inputObject, outputObject); + } + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/dao/CrmPageDao.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/dao/CrmPageDao.java new file mode 100644 index 0000000..00e58ae --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/dao/CrmPageDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.statis.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface CrmPageDao { + + List> queryInsertNumByYear(@Param("year") String year); + + List> queryCustomNumByType(); + + List> queryCustomNumByFrom(); + + List> queryCustomNumByIndustry(); + + List> queryCustomNumByGroup(); + + List> queryCustomDocumentaryType(@Param("year") String year); + + List> queryNewContractNum(@Param("year") String year); + + List> queryNewDocumentaryNum(@Param("year") String year); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/CrmPageService.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/CrmPageService.java new file mode 100644 index 0000000..3606112 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/CrmPageService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.statis.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CrmPageService { + + void queryInsertNumByYear(InputObject inputObject, OutputObject outputObject); + + void queryCustomNumByOtherType(InputObject inputObject, OutputObject outputObject); + + void queryCustomDocumentaryType(InputObject inputObject, OutputObject outputObject); + + void queryNewContractNum(InputObject inputObject, OutputObject outputObject); + + void queryNewDocumentaryNum(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/impl/CrmPageServiceImpl.java b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/impl/CrmPageServiceImpl.java new file mode 100644 index 0000000..32a5973 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/java/com/skyeye/statis/service/impl/CrmPageServiceImpl.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.statis.service.impl; + +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.service.ISysDictDataService; +import com.skyeye.statis.dao.CrmPageDao; +import com.skyeye.statis.service.CrmPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class CrmPageServiceImpl implements CrmPageService { + + @Autowired + private CrmPageDao crmPageDao; + + @Autowired + private ISysDictDataService iSysDictDataService; + + /** + * 获取指定年度的客户新增量,联系人新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInsertNumByYear(InputObject inputObject, OutputObject outputObject) { + String year = inputObject.getParams().get("year").toString(); + List> beans = crmPageDao.queryInsertNumByYear(year); + outputObject.setBeans(beans); + } + + /** + * 根据客户分类,客户来源,所属行业,客户分组统计客户数量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCustomNumByOtherType(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String crmCustomerType = params.get("crmCustomerType").toString(); + String crmCustomerFrom = params.get("crmCustomerFrom").toString(); + String crmCustomerIndustry = params.get("crmCustomerIndustry").toString(); + String crmCustomerGroup = params.get("crmCustomerGroup").toString(); + // 1.根据客户分类统计客户数量 + List> numType = this.getDictDataNun(crmCustomerType, crmPageDao.queryCustomNumByType()); + // 2.根据客户来源统计客户数量 + List> numFrom = this.getDictDataNun(crmCustomerFrom, crmPageDao.queryCustomNumByFrom()); + // 3.根据所属行业统计客户数量 + List> numIndustry = this.getDictDataNun(crmCustomerIndustry, crmPageDao.queryCustomNumByIndustry()); + // 4.根据客户分组统计客户数量 + List> numGroup = this.getDictDataNun(crmCustomerGroup, crmPageDao.queryCustomNumByGroup()); + Map map = new HashMap<>(); + map.put("numType", numType); + map.put("numFrom", numFrom); + map.put("numIndustry", numIndustry); + map.put("numGroup", numGroup); + outputObject.setBean(map); + } + + private List> getDictDataNun(String code, List> numDataFrom) { + List> dictDataList = iSysDictDataService.queryDictDataListByDictTypeCode(code); + Map numDataMap = numDataFrom.stream() + .collect(Collectors.toMap(bean -> bean.get("dictDataId").toString(), bean -> bean.get("number").toString())); + if (!CollectionUtils.isEmpty(dictDataList)) { + dictDataList.forEach(bean -> { + String num = numDataMap.get(bean.get("id").toString()); + if (!ToolUtil.isBlank(num)) { + bean.put("number", num); + } else { + bean.put("number", CommonNumConstants.NUM_ZERO); + } + }); + } + return dictDataList; + } + + /** + * 客户跟单方式分析 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCustomDocumentaryType(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String year = params.get("year").toString(); + String crmDocumentaryType = params.get("crmDocumentaryType").toString(); + List> beans = this.getDictDataNun(crmDocumentaryType, crmPageDao.queryCustomDocumentaryType(year)); + outputObject.setBeans(beans); + } + + /** + * 获取合同在指定年度的月新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryNewContractNum(InputObject inputObject, OutputObject outputObject) { + String year = inputObject.getParams().get("year").toString(); + List> beans = crmPageDao.queryNewContractNum(year); + outputObject.setBeans(beans); + } + + /** + * 获取员工跟单在指定年度的月新增量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryNewDocumentaryNum(InputObject inputObject, OutputObject outputObject) { + String year = inputObject.getParams().get("year").toString(); + List> beans = crmPageDao.queryNewDocumentaryNum(year); + outputObject.setBeans(beans); + } + + +} diff --git a/skyeye-crm/crm-pro/src/main/resources/mapper/customer/CrmCustomerMapper.xml b/skyeye-crm/crm-pro/src/main/resources/mapper/customer/CrmCustomerMapper.xml new file mode 100644 index 0000000..2b7be22 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/resources/mapper/customer/CrmCustomerMapper.xml @@ -0,0 +1,36 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-pro/src/main/resources/mapper/documentary/CrmDocumentaryMapper.xml b/skyeye-crm/crm-pro/src/main/resources/mapper/documentary/CrmDocumentaryMapper.xml new file mode 100644 index 0000000..a5339b4 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/resources/mapper/documentary/CrmDocumentaryMapper.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-pro/src/main/resources/mapper/opportunity/CrmOpportunityMapper.xml b/skyeye-crm/crm-pro/src/main/resources/mapper/opportunity/CrmOpportunityMapper.xml new file mode 100644 index 0000000..fde8797 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/resources/mapper/opportunity/CrmOpportunityMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-pro/src/main/resources/mapper/statis/CrmPageMapper.xml b/skyeye-crm/crm-pro/src/main/resources/mapper/statis/CrmPageMapper.xml new file mode 100644 index 0000000..88dbe44 --- /dev/null +++ b/skyeye-crm/crm-pro/src/main/resources/mapper/statis/CrmPageMapper.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-web/.gitignore b/skyeye-crm/crm-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-crm/crm-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-crm/crm-web/pom.xml b/skyeye-crm/crm-web/pom.xml new file mode 100644 index 0000000..2bd86d0 --- /dev/null +++ b/skyeye-crm/crm-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-crm + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + crm-web + + + 8 + 8 + + + + + + com.skyeye + crm-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-crm/crm-web/src/main/java/com/CrmApplication.java b/skyeye-crm/crm-web/src/main/java/com/CrmApplication.java new file mode 100644 index 0000000..c29a3b8 --- /dev/null +++ b/skyeye-crm/crm-web/src/main/java/com/CrmApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class CrmApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(CrmApplication.class, args); + } + +} diff --git a/skyeye-crm/crm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-crm/crm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..049e97f --- /dev/null +++ b/skyeye-crm/crm-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-crm/crm-web/src/main/resources/banner.txt b/skyeye-crm/crm-web/src/main/resources/banner.txt new file mode 100644 index 0000000..ee9fb99 --- /dev/null +++ b/skyeye-crm/crm-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev crm-web.jar >> /opt/service/project/nohup-crm.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-crm/crm-web/src/main/resources/bootstrap.yml b/skyeye-crm/crm-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..f579fe7 --- /dev/null +++ b/skyeye-crm/crm-web/src/main/resources/bootstrap.yml @@ -0,0 +1,48 @@ +server: + port: 8102 + +spring: + application: + name: skyeye-crm-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # 总工程服务 + skyeye-pro: skyeye-pro-${spring.profiles.active} + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-crm/crm-web/src/main/resources/jvm调优参数配置 b/skyeye-crm/crm-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-crm/crm-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-crm/crm-web/src/main/resources/log4j.properties b/skyeye-crm/crm-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-crm/crm-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-crm/pom.xml b/skyeye-crm/pom.xml new file mode 100644 index 0000000..c63a271 --- /dev/null +++ b/skyeye-crm/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + crm-common + crm-pro + crm-web + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-crm + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-deploy/.gitignore b/skyeye-deploy/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-deploy/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-centre/.gitignore b/skyeye-deploy/deploy-centre/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-deploy/deploy-centre/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-centre/pom.xml b/skyeye-deploy/deploy-centre/pom.xml new file mode 100644 index 0000000..1226011 --- /dev/null +++ b/skyeye-deploy/deploy-centre/pom.xml @@ -0,0 +1,29 @@ + + + + skyeye-deploy + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + deploy-centre + + + 8 + 8 + + + + + + com.skyeye + deploy-entity + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/controller/DeployJarController.java b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/controller/DeployJarController.java new file mode 100644 index 0000000..8414c4f --- /dev/null +++ b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/controller/DeployJarController.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.deploy.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.deploy.entity.deploy.JavaWebDeployInfo; +import com.skyeye.deploy.service.DeployJarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DeployJarController + * @Description: 部署jar控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/20 9:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "项目部署管理", tags = "项目部署管理", modelName = "部署平台模块") +public class DeployJarController { + + @Autowired + private DeployJarService deployJarService; + + /** + * 添加项目 + * + * @param inputObject + * @param outputObject + * @throws Exception + */ + @ApiOperation(id = "insertDeployProject", value = "添加项目", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = JavaWebDeployInfo.class) + @RequestMapping("/post/DeployJarController/insertDeployProject") + public void insertDeployProject(InputObject inputObject, OutputObject outputObject) throws Exception{ + deployJarService.insertDeployProject(inputObject, outputObject); + } + + /** + * 项目详情 + * + * @param inputObject + * @param outputObject + * @throws Exception + */ + @ApiOperation(id = "queryDeployProject", value = "项目详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "项目id", required = "required")}) + @RequestMapping("/post/DeployJarController/queryDeployProject") + public void queryDeployProject(InputObject inputObject, OutputObject outputObject) throws Exception{ + deployJarService.queryDeployProject(inputObject, outputObject); + } + +} diff --git a/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/dao/DeployJarDao.java b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/dao/DeployJarDao.java new file mode 100644 index 0000000..e2d5133 --- /dev/null +++ b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/dao/DeployJarDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.deploy.dao; + +import com.skyeye.deploy.entity.deploy.JavaWebDeployInfo; +import org.apache.ibatis.annotations.Param; + +/** + * @ClassName: DeployJarDao + * @Description: 部署jar数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/20 9:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DeployJarDao { + + void insert(JavaWebDeployInfo javaWebDeployInfo); + + JavaWebDeployInfo queryDeployProjectById(@Param("id") String id); + +} diff --git a/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/DeployJarService.java b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/DeployJarService.java new file mode 100644 index 0000000..fa0d17f --- /dev/null +++ b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/DeployJarService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.deploy.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: DeployJarService + * @Description: 部署jar服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/20 9:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DeployJarService { + + void insertDeployProject(InputObject inputObject, OutputObject outputObject); + + void queryDeployProject(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/impl/DeployJarServiceImpl.java b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/impl/DeployJarServiceImpl.java new file mode 100644 index 0000000..a22b932 --- /dev/null +++ b/skyeye-deploy/deploy-centre/src/main/java/com/skyeye/deploy/service/impl/DeployJarServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.deploy.service.impl; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.deploy.dao.DeployJarDao; +import com.skyeye.deploy.entity.deploy.JavaWebDeployInfo; +import com.skyeye.deploy.service.DeployJarService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.UUID; + +/** + * @ClassName: DeployJarServiceImpl + * @Description: 部署jar服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/20 9:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DeployJarServiceImpl implements DeployJarService { + + @Autowired + private DeployJarDao deployJarDao; + + /** + * 添加项目 + * + * @param inputObject + * @param outputObject + */ + @Override + public void insertDeployProject(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + JavaWebDeployInfo javaWebDeployInfo = JSONUtil.toBean(JSON.toJSONString(params), JavaWebDeployInfo.class); + if (StringUtils.isNotBlank(javaWebDeployInfo.getGitFolderName())) { + javaWebDeployInfo.setGitFolderId(UUID.randomUUID().toString()); + } + deployJarDao.insert(javaWebDeployInfo); + } + + /** + * 项目详情 + * + * @param inputObject + * @param outputObject + */ + @Override + public void queryDeployProject(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + JavaWebDeployInfo javaWebDeployInfo = deployJarDao.queryDeployProjectById(id); + outputObject.setBean(javaWebDeployInfo); + outputObject.settotal(1); + } + +} diff --git a/skyeye-deploy/deploy-centre/src/main/resources/mapper/centre/DeployJarMapper.xml b/skyeye-deploy/deploy-centre/src/main/resources/mapper/centre/DeployJarMapper.xml new file mode 100644 index 0000000..6f7985b --- /dev/null +++ b/skyeye-deploy/deploy-centre/src/main/resources/mapper/centre/DeployJarMapper.xml @@ -0,0 +1,16 @@ + + + + + + INSERT INTO java_web_deploy + (uuid, name, url, context_path, port, type, profile, module, branch, start_params, git_folder_name, git_folder_id) + VALUES + (#{uuid}, #{name}, #{url}, #{contextPath}, #{port}, #{type}, #{profile}, #{module}, #{branch}, #{startParams}, #{gitFolderName}, #{gitFolderId}) + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-common/.gitignore b/skyeye-deploy/deploy-common/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-deploy/deploy-common/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-common/pom.xml b/skyeye-deploy/deploy-common/pom.xml new file mode 100644 index 0000000..94419a0 --- /dev/null +++ b/skyeye-deploy/deploy-common/pom.xml @@ -0,0 +1,30 @@ + + + + skyeye-deploy + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + deploy-common + + + 8 + 8 + + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-common/src/main/java/com/skyeye/common/constans/Constants.java b/skyeye-deploy/deploy-common/src/main/java/com/skyeye/common/constans/Constants.java new file mode 100644 index 0000000..2d837b7 --- /dev/null +++ b/skyeye-deploy/deploy-common/src/main/java/com/skyeye/common/constans/Constants.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.constans; + +import java.util.Locale; + +/** + * + * @ClassName: Constants + * @Description: 系统公共常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 23:22 + * + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class Constants { + + + +} diff --git a/skyeye-deploy/deploy-entity/.gitignore b/skyeye-deploy/deploy-entity/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-deploy/deploy-entity/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-entity/pom.xml b/skyeye-deploy/deploy-entity/pom.xml new file mode 100644 index 0000000..a84a274 --- /dev/null +++ b/skyeye-deploy/deploy-entity/pom.xml @@ -0,0 +1,29 @@ + + + + skyeye-deploy + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + deploy-entity + + + 8 + 8 + + + + + + com.skyeye + deploy-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-entity/src/main/java/com/skyeye/deploy/entity/deploy/JavaWebDeployInfo.java b/skyeye-deploy/deploy-entity/src/main/java/com/skyeye/deploy/entity/deploy/JavaWebDeployInfo.java new file mode 100644 index 0000000..dbf63e1 --- /dev/null +++ b/skyeye-deploy/deploy-entity/src/main/java/com/skyeye/deploy/entity/deploy/JavaWebDeployInfo.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.deploy.entity.deploy; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * + * @ClassName: JavaWebDeployInfo + * @Description: 项目工程实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/20 9:36 + * + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("项目工程实体类") +public class JavaWebDeployInfo implements Serializable { + + private String uuid; + + @ApiModelProperty(value = "项目名称", required = "required") + private String name; + + @ApiModelProperty(value = "版本控制工具类型(1.SVN;2.GIT)", required = "required") + private int type; + + @ApiModelProperty(value = "svn/git地址", required = "required") + private String url; + + @ApiModelProperty(value = "Web项目contextPath", required = "required", defaultValue = "/") + private String contextPath; + + @ApiModelProperty(value = "项目端口", required = "required") + private int port; + + @ApiModelProperty(value = "Maven profile") + private String profile; + + @ApiModelProperty(value = "模块名称,多模块工程时,为主jar包所在的模块名称") + private String module; + + @ApiModelProperty(value = "git分支") + private String branch; + + @ApiModelProperty(value = "启动参数") + private String startParams; + + @ApiModelProperty(value = "如果一个git地址上有多个项目,则为目录节点") + private String gitFolderName; + + @ApiModelProperty(value = "如果一个git地址上有多个项目,当有目录节点时,重新生成子节点id") + private String gitFolderId; + +} diff --git a/skyeye-deploy/deploy-web/.gitignore b/skyeye-deploy/deploy-web/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-deploy/deploy-web/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/pom.xml b/skyeye-deploy/deploy-web/pom.xml new file mode 100644 index 0000000..de02928 --- /dev/null +++ b/skyeye-deploy/deploy-web/pom.xml @@ -0,0 +1,130 @@ + + + + skyeye-deploy + com.skyeye + 1.0-SNAPSHOT + + war + 4.0.0 + + deploy-web + + + 8 + 8 + + + + + + com.skyeye + deploy-centre + 1.0-SNAPSHOT + + + + org.apache.commons + commons-exec + 1.3 + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + jstl + jstl + 1.2 + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + + ${basedir}/src/main/webapp + META-INF/resources + + **/** + + + + ${basedir}/src/main/resources + + **/** + + + + ${basedir}/src/main/java + + **/*.xml + + false + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/java/com/SkyeyeDeployApplication.java b/skyeye-deploy/deploy-web/src/main/java/com/SkyeyeDeployApplication.java new file mode 100644 index 0000000..a0e7964 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/SkyeyeDeployApplication.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * @ClassName: SkyeyeDeployApplication + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2022/3/5 14:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@SpringBootApplication +@EnableAutoConfiguration(exclude={ + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableDiscoveryClient +@EnableFeignClients +public class SkyeyeDeployApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyeyeDeployApplication.class, args); + } + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..4e4b3b6 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.jdeploy.mapper", + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + * @throws Exception + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) throws Exception { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/GlobalConfig.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/GlobalConfig.java new file mode 100644 index 0000000..779a1fc --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/GlobalConfig.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jdeploy; + +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.File; + +/** + * @ClassName: GlobalConfig + * @Description: 如果是单独的项目,已经可以正常运行和访问,但是我用的时候,是在父项目的子模块中使用的,因此需要添加一个配置类,否则会出现404 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/5 15:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +public class GlobalConfig { + @Bean + public WebServerFactoryCustomizer customizer() { + return (factory) -> { + factory.addContextCustomizers((context) -> { //模块中webapp相对路径 + // 下面是子项目的module名称,而不是你修改的application name这点需要注意; + String relativePath = "deploy-web/src/main/webapp"; + File docBaseFile = new File(relativePath); // 如果路径不存在,则把这个路径加入进去 + if (docBaseFile.exists()) { + context.setDocBase(docBaseFile.getAbsolutePath()); + } + }); + }; + } +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/IndexController.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/IndexController.java new file mode 100644 index 0000000..3e184bc --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/IndexController.java @@ -0,0 +1,37 @@ +package com.skyeye.jdeploy.controller; + +import com.skyeye.jdeploy.service.JavaWebDeployService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.ModelAndView; + +import java.util.Arrays; +import java.util.List; + +@Controller +public class IndexController { + + @Autowired + private JavaWebDeployService javaWebDeployService; + + @Value("${modules}") + private String modules; + + /** + * 列表展示页面 + */ + @RequestMapping(value = "/", method = RequestMethod.GET) + public ModelAndView index() { + ModelAndView mv = new ModelAndView("index"); + List moduleList = Arrays.asList(modules.split(",")); + mv.addObject("moduleList", moduleList); + if(moduleList.contains("javaweb")) { + mv.addObject("javaWebDeployList", javaWebDeployService.getList()); + } + return mv; + } + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/JavaWebDeployController.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/JavaWebDeployController.java new file mode 100644 index 0000000..c528b01 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/controller/JavaWebDeployController.java @@ -0,0 +1,98 @@ +package com.skyeye.jdeploy.controller; + +import com.skyeye.jdeploy.domain.JavaWebDeployInfo; +import com.skyeye.jdeploy.service.JavaWebDeployService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.util.HtmlUtils; + +import java.io.IOException; +import java.util.UUID; + +/** + * 线上环境的后台服务自动化部署 + * @author wucao + */ +@Controller +@RequestMapping("javawebdeploy") +public class JavaWebDeployController { + + @Autowired + private JavaWebDeployService javaWebDeployService; + + /** + * 添加项目页面 + */ + @RequestMapping(value = "new", method = RequestMethod.GET) + public ModelAndView newService() { + ModelAndView mv = new ModelAndView("javawebdeploy/new"); + return mv; + } + + /** + * 添加项目请求 + */ + @RequestMapping(value = "insert", method = RequestMethod.POST) + public String insert(JavaWebDeployInfo javaWebDeployInfo) { + String uuid = UUID.randomUUID().toString(); + javaWebDeployInfo.setUuid(uuid); + if(StringUtils.isNotBlank(javaWebDeployInfo.getGitFolderName())){ + javaWebDeployInfo.setGitFolderId(UUID.randomUUID().toString()); + } + javaWebDeployService.insert(javaWebDeployInfo); + return "redirect:/javawebdeploy/detail/" + uuid; + } + + /** + * 详情页面 + */ + @RequestMapping(value = "detail/{uuid}", method = RequestMethod.GET) + public ModelAndView detail(@PathVariable String uuid) { + ModelAndView mv = new ModelAndView("javawebdeploy/detail"); + mv.addObject("detail", javaWebDeployService.getDetail(uuid)); + return mv; + } + + /** + * ajax查看运行状态 + */ + @ResponseBody + @RequestMapping(value = "status", produces = "text/plain;charset=UTF-8", method = RequestMethod.POST) + public String ajaxStatus(String uuid) throws IOException { + return javaWebDeployService.getStatus(uuid); + } + + /** + * ajax部署 + */ + @ResponseBody + @RequestMapping(value = "deploy", produces = "text/plain;charset=UTF-8", method = RequestMethod.POST) + public String ajaxDeploy(String uuid) throws IOException { + return HtmlUtils.htmlEscape(javaWebDeployService.deploy(uuid)); + } + + /** + * ajax重启 + */ + @ResponseBody + @RequestMapping(value = "restart", produces = "text/plain;charset=UTF-8", method = RequestMethod.POST) + public String ajaxRestart(String uuid) throws IOException { + return HtmlUtils.htmlEscape(javaWebDeployService.restart(uuid)); + } + + /** + * ajax停止 + */ + @ResponseBody + @RequestMapping(value = "stop", produces = "text/plain;charset=UTF-8", method = RequestMethod.POST) + public String ajaxStop(String uuid) throws IOException { + return HtmlUtils.htmlEscape(javaWebDeployService.stop(uuid)); + } + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/domain/JavaWebDeployInfo.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/domain/JavaWebDeployInfo.java new file mode 100644 index 0000000..a700fa5 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/domain/JavaWebDeployInfo.java @@ -0,0 +1,41 @@ +package com.skyeye.jdeploy.domain; + +import lombok.Data; + +@Data +public class JavaWebDeployInfo { + + private String uuid; + + private String name; + + private int type; + + private String url; + + private String contextPath; + + private int port; + + private String profile; + + private String module; + + private String branch; + + /** + * 启动参数 + */ + private String startParams; + + /** + * 如果一个git地址上有多个项目,则为目录节点 + */ + private String gitFolderName; + + /** + * 如果一个git地址上有多个项目,当有目录节点时,重新生成子节点id + */ + private String gitFolderId; + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/mapper/JavaWebDeployMapper.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/mapper/JavaWebDeployMapper.java new file mode 100644 index 0000000..56320db --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/mapper/JavaWebDeployMapper.java @@ -0,0 +1,25 @@ +package com.skyeye.jdeploy.mapper; + +import com.skyeye.jdeploy.domain.JavaWebDeployInfo; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +public interface JavaWebDeployMapper { + + @Select("select uuid,name,url,context_path as contextPath,port,type,start_params as startParams," + + "git_folder_name as gitFolderName, git_folder_id as gitFolderId from java_web_deploy") + List getList(); + + @Select("select uuid,name,url,context_path as contextPath,port,type,profile,module,branch,start_params as startParams," + + "git_folder_name as gitFolderName, git_folder_id as gitFolderId from java_web_deploy where uuid=#{uuid}") + JavaWebDeployInfo getDetail(String uuid); + + @Insert("insert into java_web_deploy " + + "(uuid,name,url,context_path,port,type,profile,module,branch,start_params, git_folder_name, git_folder_id) " + + "values " + + "(#{uuid},#{name},#{url},#{contextPath},#{port},#{type},#{profile},#{module},#{branch}, #{startParams}, #{gitFolderName}, #{gitFolderId})") + void insert(JavaWebDeployInfo javaWebDeployInfo); + +} \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/service/JavaWebDeployService.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/service/JavaWebDeployService.java new file mode 100644 index 0000000..dd6429b --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/service/JavaWebDeployService.java @@ -0,0 +1,211 @@ +package com.skyeye.jdeploy.service; + +import com.skyeye.jdeploy.domain.JavaWebDeployInfo; +import com.skyeye.jdeploy.mapper.JavaWebDeployMapper; +import com.skyeye.jdeploy.util.ShellUtil; +import org.apache.commons.io.FileUtils; +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.Service; +import org.springframework.util.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +@Service +public class JavaWebDeployService { + + private static Logger LOGGER = LoggerFactory.getLogger(JavaWebDeployService.class); + + @Autowired + private JavaWebDeployMapper javaWebDeployMapper; + + @Value("${IMAGES_PATH}${shell.javawebdeploy}") + private String shellFileFolder; + + @Value("${javawebdeploy.basepath}") + private String basePath; + + public List getList() { + return javaWebDeployMapper.getList(); + } + + public JavaWebDeployInfo getDetail(String uuid) { + return javaWebDeployMapper.getDetail(uuid); + } + + public void insert(JavaWebDeployInfo javaWebDeployInfo) { + javaWebDeployMapper.insert(javaWebDeployInfo); + } + + public String getStatus(String uuid) throws IOException { + JavaWebDeployInfo info = javaWebDeployMapper.getDetail(uuid); + if(info != null) { + String out; + if(org.apache.commons.lang.StringUtils.isNotBlank(info.getGitFolderName())){ + out = ShellUtil.exec("sh " + shellFileFolder + "/isrunning.sh " + info.getGitFolderId()); + }else{ + out = ShellUtil.exec("sh " + shellFileFolder + "/isrunning.sh " + info.getUuid()); + } + LOGGER.info(out); + return String.valueOf(StringUtils.hasText(out) && out.contains("java -jar")); + } else { + return "false"; + } + } + + public String deploy(String uuid) throws IOException { + JavaWebDeployInfo info = javaWebDeployMapper.getDetail(uuid); + if(info != null) { + StringBuilder sb = new StringBuilder(); + + // kill进程 + sb.append(killShRun(info)); + // 打包 + sb.append(packageShRun(info)); + + String finalName = getFinalName(getOldFilePath(info)); + if(finalName != null) { + FileUtils.copyFile( + new File(getOldFileNamePath(info, finalName)), + new File(getNewFilePath(info))); + // 启动程序 + sb.append(startShRun(info)); + } else { + sb.append("打包失败"); + } + LOGGER.info("result is {}", sb.toString()); + return sb.toString(); + } else { + return uuid + "对应的项目不存在!"; + } + } + + private String killShRun(JavaWebDeployInfo info) throws IOException { + StringBuilder execStr = new StringBuilder(); + execStr.append("sh " + shellFileFolder + "/kill.sh"); + if(org.apache.commons.lang.StringUtils.isNotBlank(info.getGitFolderName())){ + execStr.append(" " + info.getGitFolderId()); + }else{ + execStr.append(" " + info.getUuid()); + } + + String killRunStr = ShellUtil.exec(execStr.toString()); + LOGGER.info("killRunStr is {}", killRunStr); + return killRunStr; + } + + private String getOldFilePath(JavaWebDeployInfo info){ + String module = ""; + if(StringUtils.hasText(info.getModule())) { + module = "/" + info.getModule(); + } + if(org.apache.commons.lang3.StringUtils.isNotEmpty(info.getGitFolderName())){ + return basePath + "/" + info.getUuid() + "/" + info.getGitFolderName() + "/" + module + "/target"; + }else{ + return basePath + "/" + info.getUuid() + module + "/target"; + } + } + + private String getOldFileNamePath(JavaWebDeployInfo info, String finalName){ + String module = ""; + if(StringUtils.hasText(info.getModule())) { + module = "/" + info.getModule(); + } + if(org.apache.commons.lang3.StringUtils.isNotEmpty(info.getGitFolderName())){ + return basePath + "/" + info.getUuid() + "/" + info.getGitFolderName() + "/" + module + "/target/" + finalName; + }else{ + return basePath + "/" + info.getUuid() + module + "/target/" + finalName; + } + } + + private String getNewFilePath(JavaWebDeployInfo info){ + if(org.apache.commons.lang3.StringUtils.isNotEmpty(info.getGitFolderName())){ + return basePath + "/" + info.getUuid() + "/" + info.getGitFolderName() + "/webapps/" + info.getGitFolderId() + ".jar"; + }else{ + return basePath + "/" + info.getUuid() + "/webapps/" + info.getUuid() + ".jar"; + } + } + + private String packageShRun(JavaWebDeployInfo info) throws IOException { + String[] execStr = new String[]{"sh " + shellFileFolder + "/package.sh", + info.getUuid(), + info.getUrl(), + basePath, + String.valueOf(info.getType()), + (org.apache.commons.lang.StringUtils.isNotBlank(info.getProfile()) ? info.getProfile() : null), + info.getBranch(), + info.getGitFolderName()}; + String packageRunStr = ShellUtil.exec(execStr); + LOGGER.info("pachageStr is {}", packageRunStr); + return packageRunStr; + } + + public String restart(String uuid) throws IOException { + JavaWebDeployInfo info = javaWebDeployMapper.getDetail(uuid); + if(info != null) { + StringBuilder sb = new StringBuilder(); + // kill进程 + sb.append(killShRun(info)); + // 启动程序 + sb.append(startShRun(info)); + return sb.toString(); + } else { + return uuid + "对应的项目不存在!"; + } + } + + private String startShRun(JavaWebDeployInfo info) throws IOException { + String[] execStr = new String[]{"sh " + shellFileFolder + "/start.sh", + info.getUuid(), + String.valueOf(info.getPort()), + basePath, + info.getStartParams(), + info.getGitFolderName(), + info.getGitFolderId()}; + String startRunStr = ShellUtil.exec(execStr); + LOGGER.info("startRunStr is {}", startRunStr); + return startRunStr; + } + + public String stop(String uuid) throws IOException { + JavaWebDeployInfo info = javaWebDeployMapper.getDetail(uuid); + if(info != null) { + return killShRun(info); + } else { + return uuid + "对应的项目不存在!"; + } + } + + public String showLog(String uuid) throws IOException { + JavaWebDeployInfo info = javaWebDeployMapper.getDetail(uuid); + if(info != null) { + String[] execStr = new String[]{"sh " + shellFileFolder + "/showlog.sh", + info.getUuid(), + basePath, + info.getGitFolderName(), + info.getGitFolderId()}; + return org.apache.commons.lang3.StringUtils.join(execStr, " "); + } else { + return "echo \"对应的项目不存在!\""; + } + } + + private String getFinalName(String folderPath) { + LOGGER.info("folderPath is {}", folderPath); + File dir = new File(folderPath); + File[] files = dir.listFiles(); + + String fileName = null; + for(File file : files) { + String name = file.getName(); + if(file.isFile() && name.endsWith(".jar")) { + fileName = name; + } + } + return fileName; + } +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/QueryStringParser.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/QueryStringParser.java new file mode 100644 index 0000000..cbf6deb --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/QueryStringParser.java @@ -0,0 +1,24 @@ +package com.skyeye.jdeploy.util; + +import java.util.HashMap; +import java.util.Map; + +public class QueryStringParser { + + public static Map parse(String queryString) { + + Map map = new HashMap(); + + String[] pairs = queryString.split("&"); + for (String pair : pairs) { + String[] keyValue = pair.split("="); + if(keyValue.length > 1) { + map.put(keyValue[0], keyValue[1]); + } else { + map.put(keyValue[0], null); + } + } + + return map; + } +} \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/ShellUtil.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/ShellUtil.java new file mode 100644 index 0000000..581cf6a --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/util/ShellUtil.java @@ -0,0 +1,43 @@ +package com.skyeye.jdeploy.util; + +import org.apache.commons.exec.CommandLine; +import org.apache.commons.exec.DefaultExecutor; +import org.apache.commons.exec.ExecuteWatchdog; +import org.apache.commons.exec.PumpStreamHandler; +import org.springframework.util.StringUtils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ShellUtil { + + public static String exec(String... cmd) throws IOException { + + CommandLine cmdLine = CommandLine.parse(cmd[0]); + for(int i = 1; i < cmd.length; i++) { + if(StringUtils.hasText(cmd[i])) { + cmdLine.addArgument(cmd[i], false); + }else { + cmdLine.addArgument("null", false); + } + } + + DefaultExecutor executor = new DefaultExecutor(); + + // 防止抛出异常 + executor.setExitValues(null); + + // 命令执行的超时时间 + ExecuteWatchdog watchdog = new ExecuteWatchdog(600000); + executor.setWatchdog(watchdog); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream); + executor.setStreamHandler(streamHandler); + + executor.execute(cmdLine); + + return outputStream.toString(); + } + +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogThread.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogThread.java new file mode 100644 index 0000000..9eb9344 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogThread.java @@ -0,0 +1,48 @@ +package com.skyeye.jdeploy.websocket; + +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.util.HtmlUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; + +/** + * Created by wucao on 16-5-30. + */ +public class LogThread implements Runnable { + + + private Process process; + private BufferedReader reader; + private WebSocketSession session; + + public LogThread(Process process, WebSocketSession session) throws UnsupportedEncodingException { + this.process = process; + this.reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); + this.session = session; + } + + public void close() throws IOException { + try { + reader.close(); + } finally { + process.destroy(); + } + } + + @Override + public void run() { + String line; + try { + while((line = reader.readLine()) != null) { + // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行 + session.sendMessage(new TextMessage(HtmlUtils.htmlEscape(line) + "
")); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogWebSocketHandle.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogWebSocketHandle.java new file mode 100644 index 0000000..d56eed6 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/LogWebSocketHandle.java @@ -0,0 +1,56 @@ +package com.skyeye.jdeploy.websocket; + +import com.skyeye.jdeploy.service.JavaWebDeployService; +import com.skyeye.jdeploy.util.QueryStringParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.AbstractWebSocketHandler; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by wucao on 16-5-30. + */ +public class LogWebSocketHandle extends AbstractWebSocketHandler { + + private ConcurrentHashMap map = new ConcurrentHashMap<>(); + + @Autowired + private JavaWebDeployService javaWebDeployService; + + @Autowired + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + String type = QueryStringParser.parse(session.getUri().getQuery()).get("type"); + String uuid = QueryStringParser.parse(session.getUri().getQuery()).get("uuid"); + + String command = "echo \"参数错误\""; + if("javaweb".equals(type)) { + command = javaWebDeployService.showLog(uuid); + } + + Process process = Runtime.getRuntime().exec(command); + LogThread thread = new LogThread(process, session); + threadPoolTaskExecutor.execute(thread); + + map.put(session.getId(), thread); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + LogThread thread = map.get(session.getId()); + map.remove(session.getId()); + thread.close(); + + System.out.println("Now Websocket Connection: " + map.size()); + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { + exception.printStackTrace(); + } +} \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/WebSocketConfig.java b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/WebSocketConfig.java new file mode 100644 index 0000000..de99138 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/java/com/skyeye/jdeploy/websocket/WebSocketConfig.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.jdeploy.websocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +/** + * @ClassName: WebSocketConfig + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2022/3/5 23:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer{ + @Bean + public LogWebSocketHandle socketHander(){ + return new LogWebSocketHandle(); + } + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(socketHander(), "/log").setAllowedOrigins("*"); + } + + @Bean + public ThreadPoolTaskExecutor taskExecutor() { + ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); + // 线程池维护线程的最少数量 + pool.setCorePoolSize(5); + // 线程池维护线程的最大数量 + pool.setMaxPoolSize(2000); + // 当调度器shutdown被调用时等待当前被调度的任务完成 + pool.setWaitForTasksToCompleteOnShutdown(true); + return pool; + } +} diff --git a/skyeye-deploy/deploy-web/src/main/resources/banner.txt b/skyeye-deploy/deploy-web/src/main/resources/banner.txt new file mode 100644 index 0000000..59c3456 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/resources/banner.txt @@ -0,0 +1,35 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=175.27.188.37:8848 -Dspring.cloud.nacos.config.server-addr=175.27.188.37:8848 deploy-web.war & +*/ \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/resources/bootstrap.yml b/skyeye-deploy/deploy-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..3e554f8 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/resources/bootstrap.yml @@ -0,0 +1,34 @@ + +server: + port: 8083 + +spring: + application: + name: skyeye-deploy-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: localhost:9000 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: localhost:9000 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false diff --git a/skyeye-deploy/deploy-web/src/main/resources/log4j.properties b/skyeye-deploy/deploy-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/index.jsp b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/index.jsp new file mode 100644 index 0000000..469c4cc --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/index.jsp @@ -0,0 +1,143 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + + +Skyeye-JDeploy自动化部署平台 + + + + + + + + + + +
+
+
+ +
+
+ + + +
+
+
+ +
+
+ 创建 +
+
+ + + + + + + + + + + + + + + + + +
项目名称UUID详情
${item.name}${item.uuid}详情
+
+
+
+ + + +
+
+
+ +
+
+ 创建 +
+
+ + + + + + + + + + + + + + + + + + + + + +
项目名称UUIDcontextPath端口号详情
${item.name}${item.uuid}${item.contextPath}${item.port}详情
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/detail.jsp b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/detail.jsp new file mode 100644 index 0000000..ae8825e --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/detail.jsp @@ -0,0 +1,170 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + + +Skyeye-JDeploy自动化部署平台 + + + + + + + + + + + +
+ +
+
+
+
+ ${detail.name} +

名称:${detail.name}

+

UUID:${detail.uuid}

+

Maven profile:${detail.profile}

+

Maven module:${detail.module}

+

contextPath:${detail.contextPath}

+

端口号:${detail.port}

+ +

SVN地址:${detail.url}

+
+ +

GIT地址:${detail.url}

+

GIT分支:${detail.branch}

+

GIT目录节点:${detail.gitFolderName}

+
+

启动参数:${detail.startParams}

+
+
+

+ 部署 + 重启 + 停止 +

+
+
+
+
+
+
+
+
+ 运行状态 +

+ + + 获取中... +

+
+ +
+
+
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/new.jsp b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/new.jsp new file mode 100644 index 0000000..7d755bb --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/WEB-INF/jsp/javawebdeploy/new.jsp @@ -0,0 +1,112 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + + +Skyeye-JDeploy自动化部署平台 + + + + + + + + + + +
+
+ +
+
+
+
+ 新建项目 + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + +
+ + +
+ + +
+
+ +
+
+

+ +

+
+
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/login.jsp b/skyeye-deploy/deploy-web/src/main/webapp/login.jsp new file mode 100644 index 0000000..c0d8a7a --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/login.jsp @@ -0,0 +1,63 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + + +Skyeye-JDeploy自动化部署平台 + + + + + + + + + +
+
+
+
+
+ 登录 +
用户名或密码错误!
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/resources/css/icon.css b/skyeye-deploy/deploy-web/src/main/webapp/resources/css/icon.css new file mode 100644 index 0000000..d442589 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/resources/css/icon.css @@ -0,0 +1,20 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: local('Material Icons'), local('MaterialIcons-Regular'), url(icon.woff2) format('woff2'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; + line-height: 1; + letter-spacing: normal; + text-transform: none; + display: inline-block; + word-wrap: normal; + -webkit-font-feature-settings: 'liga'; + -webkit-font-smoothing: antialiased; +} diff --git a/skyeye-deploy/deploy-web/src/main/webapp/resources/css/icon.woff2 b/skyeye-deploy/deploy-web/src/main/webapp/resources/css/icon.woff2 new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-deploy/deploy-web/src/main/webapp/resources/js/detail.js b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/detail.js new file mode 100644 index 0000000..ca8b15e --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/detail.js @@ -0,0 +1,110 @@ +$(document).ready(function() { + + var uuid = $("#text-uuid").html(); + + // 初始化刷新运行状态 + refreshStatus(); + + // 部署按钮 + $("#btn-deploy").click(function () { + ajaxShell("../deploy", {uuid: uuid}, function() { + refreshStatus(); + }); + }); + + // 重启按钮 + $("#btn-restart").click(function () { + ajaxShell("../restart", {uuid: uuid}, function() { + refreshStatus(); + }); + }); + + // 停止按钮 + $("#btn-stop").click(function () { + ajaxShell("../stop", {uuid: uuid}, function() { + refreshStatus(); + }); + }); + + // 查看日志 + $(".btn-showlog").click(function () { + + var url = $(this).attr("data-wsurl"); + var websocket = new WebSocket(url); + websocket.onmessage = function(event) { + var msg = event.data; + $("#layer-modal .modal-content>div").append(msg); + $("#layer-modal .modal-content").scrollTop($("#layer-modal .modal-content>div").height() - $("#layer-modal .modal-content").height()); + }; + + $("#layer-modal .modal-content").html("
"); + $("#layer-modal").openModal({ + dismissible: false, + complete: function () { + websocket.close(); + } + }); + + }); + + + /** + * ajax请求后台运行脚本 + */ + function ajaxShell(url, postData, successCallback) { + $("#loader-modal").openModal({dismissible: false}); + $.ajax({ + url: url, + type: "POST", + data: postData, + cache: false, + dataType: "text", + success: function (data) { + $("#loader-modal").closeModal(); + $("#layer-modal .modal-content").html(data.replace(/\n/g,"
")); + $("#layer-modal").openModal({dismissible: false}); + if(successCallback) { + successCallback(); + } + }, + error: function () { + $("#loader-modal").closeModal(); + layerAlert("发生异常,请重试!"); + } + }); + } + + /** + * 刷新服务器运行状态 + */ + function refreshStatus() { + $.ajax({ + url: "../status", + type: "POST", + data: {uuid: uuid}, + cache: false, + dataType: "text", + success: function (data) { + $(".service-status").children("span").hide(); + if(data === "true") { + $(".service-status").find(".green-text").show(); + } else { + $(".service-status").find(".red-text").show(); + } + }, + error: function () { + layerAlert("发生异常,请重试!"); + } + }); + } + + /** + * 用于代替alert + * @param text + */ + function layerAlert(text) { + $("#alert-modal .text-alert").html(text); + $("#alert-modal").openModal({dismissible: false}); + } + +}); \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/resources/js/index.js b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/index.js new file mode 100644 index 0000000..1da4307 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/index.js @@ -0,0 +1,36 @@ +$(document).ready(function() { + + $("#java-deploy-search").change(function() { + var val = $(this).val().toUpperCase(); + $("#java-deploy tbody tr").each(function() { + var name = $(this).children().get(0).innerHTML.toUpperCase(); + var uuid = $(this).children().get(1).innerHTML.toUpperCase(); + if(name.indexOf(val) != -1 || uuid.indexOf(val) != -1) { + $(this).show(); + } else { + $(this).hide(); + } + }); + }); + + $("#java-web-deploy-search").change(function() { + var val = $(this).val().toUpperCase(); + $("#java-web-deploy tbody tr").each(function() { + var name = $(this).children().get(0).innerHTML.toUpperCase(); + var uuid = $(this).children().get(1).innerHTML.toUpperCase(); + var contextPath = $(this).children().get(2).innerHTML.toUpperCase(); + var port = $(this).children().get(3).innerHTML; + if(name.indexOf(val) != -1 || uuid.indexOf(val) != -1 + || contextPath.indexOf(val) != -1 || port.indexOf(val) != -1) { + $(this).show(); + } else { + $(this).hide(); + } + }); + }); + + $("form").submit(function() { + return false; + }); + +}); \ No newline at end of file diff --git a/skyeye-deploy/deploy-web/src/main/webapp/resources/js/javawebdeploy/new.js b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/javawebdeploy/new.js new file mode 100644 index 0000000..4d36239 --- /dev/null +++ b/skyeye-deploy/deploy-web/src/main/webapp/resources/js/javawebdeploy/new.js @@ -0,0 +1,40 @@ +$(document).ready(function() { + + $("#form-new").submit(function() { + var name = $("#input-name").val(); + var url = $("#input-url").val(); + var port = $("#input-port").val(); + + if(name.length === 0) { + layerAlert("请填写项目名称!") + return false; + } + if(url.length === 0) { + layerAlert("请填写SVN地址!") + return false; + } + if(parseInt(port).toString() !== port || parseInt(port) < 0 || parseInt(port) > 65536) { + layerAlert("请填写正确的端口号!") + return false; + } + + }); + + $("input[name='type']").change(function () { + if(this.value == 2) { + $(".input-field-branch").fadeIn(); + } else { + $(".input-field-branch").fadeOut(); + } + }); + + /** + * 用于代替alert + * @param text + */ + function layerAlert(text) { + $("#alert-modal .text-alert").html(text); + $("#alert-modal").openModal({dismissible: false}); + } + +}); \ No newline at end of file diff --git a/skyeye-deploy/pom.xml b/skyeye-deploy/pom.xml new file mode 100644 index 0000000..8505c69 --- /dev/null +++ b/skyeye-deploy/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-deploy + pom + 1.0-SNAPSHOT + + deploy-web + deploy-common + deploy-centre + deploy-entity + + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + + + \ No newline at end of file diff --git a/skyeye-erp/.gitignore b/skyeye-erp/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-erp/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-erp/erp-common/.gitignore b/skyeye-erp/erp-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-erp/erp-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-erp/erp-common/pom.xml b/skyeye-erp/erp-common/pom.xml new file mode 100644 index 0000000..86c2dc4 --- /dev/null +++ b/skyeye-erp/erp-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-erp + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + erp-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/rest/IProProjectRest.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/rest/IProProjectRest.java new file mode 100644 index 0000000..9a4a24c --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/rest/IProProjectRest.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.project.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: IProProjectRest + * @Description: 项目信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-project}", configuration = ClientConfiguration.class) +public interface IProProjectRest { + + /** + * 根据id批量获取项目信息 + * + * @param ids 主键id,多个用逗号隔开 + */ + @PostMapping("/queryProProjectByIds") + String queryProProjectByIds(@RequestParam("ids") String ids); + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/IProProjectService.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/IProProjectService.java new file mode 100644 index 0000000..50b25b8 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/IProProjectService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.project.service; + +import com.skyeye.base.rest.service.IService; + +/** + * @ClassName: IProProjectService + * @Description: 项目信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IProProjectService extends IService { + + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/impl/IProProjectServiceImpl.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/impl/IProProjectServiceImpl.java new file mode 100644 index 0000000..eb23c23 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/project/service/impl/IProProjectServiceImpl.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.project.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.rest.project.rest.IProProjectRest; +import com.skyeye.rest.project.service.IProProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: IProProjectServiceImpl + * @Description: 项目信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IProProjectServiceImpl extends IServiceImpl implements IProProjectService { + + @Autowired + private IProProjectRest iProProjectRest; + + @Override + public Map queryEntityMationById(String id) { + return queryEntityMationByIds(id).stream().findFirst().orElse(new HashMap<>()); + } + + @Override + public List> queryEntityMationByIds(String ids) { + return ExecuteFeignClient.get(() -> iProProjectRest.queryProProjectByIds(ids)).getRows(); + } + + @Override + public String queryCacheKeyById(String id) { + return String.format(Locale.ROOT, "%s:%s", CacheConstants.PM_PROJECT_CACHE_KEY, id); + } + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/sealservice/rest/IServiceApplyRest.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/sealservice/rest/IServiceApplyRest.java new file mode 100644 index 0000000..7bce7e7 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/sealservice/rest/IServiceApplyRest.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.sealservice.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: IServiceApplyRest + * @Description: 我的申领单接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/19 18:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-seal-service}", configuration = ClientConfiguration.class) +public interface IServiceApplyRest { + + /** + * 修改配件申领单出库状态 + * + * @param params 单据信息,需要包含id(单据id),otherState(出库状态) + */ + @PostMapping("/editSealApplyOtherState") + String editSealApplyOtherState(Map params); + + /** + * 修改配件申领单已出库的数量 + * + * @param params 单据信息 + */ + @PostMapping("/editSealApplyOutNum") + String editSealApplyOutNum(Map params); + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/rest/IShopStoreRest.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/rest/IShopStoreRest.java new file mode 100644 index 0000000..6cbc4b9 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/rest/IShopStoreRest.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shop.rest; + +import com.skyeye.common.client.ClientConfiguration; +import com.skyeye.common.entity.search.CommonPageInfo; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: IShopStoreRest + * @Description: 门店信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-shop}", configuration = ClientConfiguration.class) +public interface IShopStoreRest { + + /** + * 根据id批量获取门店信息 + * + * @param ids 主键id,多个用逗号隔开 + */ + @PostMapping("/queryStoreByIds") + String queryStoreByIds(@RequestParam("ids") String ids); + + /** + * 获取门店列表信息 + * + * @param shopAreaId 门店所属区域id + * @param enabled 是否启用 + */ + @GetMapping("/queryStoreListByParams") + String queryStoreListByParams(@RequestParam("shopAreaId") String shopAreaId, + @RequestParam("enabled") Integer enabled); + + /** + * 分页获取门店列表信息 + */ + @PostMapping("/queryStoreListFoServer") + String queryStoreListFoServer(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/IShopStoreService.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/IShopStoreService.java new file mode 100644 index 0000000..bc90061 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/IShopStoreService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shop.service; + +import com.skyeye.base.rest.service.IService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.ResultEntity; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IShopStoreService + * @Description: 门店信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IShopStoreService extends IService { + + List> queryStoreListByParams(String shopAreaId, Integer enabled); + + ResultEntity queryStoreListFoServer(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/impl/IShopStoreServiceImpl.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/impl/IShopStoreServiceImpl.java new file mode 100644 index 0000000..5e3f72d --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/rest/shop/service/impl/IShopStoreServiceImpl.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shop.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.ResultEntity; +import com.skyeye.rest.shop.rest.IShopStoreRest; +import com.skyeye.rest.shop.service.IShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: IShopStoreServiceImpl + * @Description: 门店信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IShopStoreServiceImpl extends IServiceImpl implements IShopStoreService { + + @Autowired + private IShopStoreRest iShopStoreRest; + + @Override + public Map queryEntityMationById(String id) { + return queryEntityMationByIds(id).stream().findFirst().orElse(new HashMap<>()); + } + + @Override + public List> queryEntityMationByIds(String ids) { + return ExecuteFeignClient.get(() -> iShopStoreRest.queryStoreByIds(ids)).getRows(); + } + + @Override + public String queryCacheKeyById(String id) { + return String.format(Locale.ROOT, "%s:%s", CacheConstants.SHOP_STORE_CACHE_KEY, id); + } + + @Override + public List> queryStoreListByParams(String shopAreaId, Integer enabled) { + return ExecuteFeignClient.get(() -> iShopStoreRest.queryStoreListByParams(shopAreaId, enabled)).getRows(); + } + + @Override + public ResultEntity queryStoreListFoServer(CommonPageInfo commonPageInfo) { + return ExecuteFeignClient.get(() -> iShopStoreRest.queryStoreListFoServer(commonPageInfo)); + } +} diff --git a/skyeye-erp/erp-common/src/main/java/com/skyeye/util/ErpOrderUtil.java b/skyeye-erp/erp-common/src/main/java/com/skyeye/util/ErpOrderUtil.java new file mode 100644 index 0000000..acfd816 --- /dev/null +++ b/skyeye-erp/erp-common/src/main/java/com/skyeye/util/ErpOrderUtil.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.util; + +import com.skyeye.exception.CustomException; + +import java.util.Map; + +/** + * @ClassName: ErpOrderUtil + * @Description: ERP工具类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/23 13:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class ErpOrderUtil { + + public static Integer checkOperNumber(Integer surplusNum, String normsId, Map... nums) { + for (Map num : nums) { + surplusNum -= num.containsKey(normsId) ? num.get(normsId) : 0; + } + if (surplusNum < 0) { + throw new CustomException("超出来源单据的商品数量."); + } + return surplusNum; + } + +} diff --git a/skyeye-erp/erp-pro/.gitignore b/skyeye-erp/erp-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-erp/erp-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-erp/erp-pro/pom.xml b/skyeye-erp/erp-pro/pom.xml new file mode 100644 index 0000000..b7acc0f --- /dev/null +++ b/skyeye-erp/erp-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-erp + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + erp-pro + + + + + com.skyeye + erp-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/controller/BomController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/controller/BomController.java new file mode 100644 index 0000000..cf72cae --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/controller/BomController.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BomController + * @Description: bom清单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "bom清单管理", tags = "bom清单管理", modelName = "bom清单管理") +public class BomController { + + @Autowired + private BomService bomService; + + /** + * 查询bom表列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpbom001", value = "查询bom表列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BomController/queryBomList") + public void queryBomList(InputObject inputObject, OutputObject outputObject) { + bomService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑bom表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBom", value = "新增/编辑bom表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Bom.class) + @RequestMapping("/post/BomController/writeBom") + public void writeBom(InputObject inputObject, OutputObject outputObject) { + bomService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询bom表详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBomById", value = "根据id查询bom表详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "方案id", required = "required")}) + @RequestMapping("/post/BomController/queryBomById") + public void queryBomById(InputObject inputObject, OutputObject outputObject) { + bomService.selectById(inputObject, outputObject); + } + + /** + * 根据ids批量查询bom表详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBomByIds", value = "根据ids批量查询bom表详情", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "方案id集合", required = "required")}) + @RequestMapping("/post/BomController/queryBomByIds") + public void queryBomByIds(InputObject inputObject, OutputObject outputObject) { + bomService.selectByIds(inputObject, outputObject); + } + + /** + * 根据ID删除bom表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBomById", value = "根据ID删除bom表信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/BomController/deleteBomById") + public void deleteBomById(InputObject inputObject, OutputObject outputObject) { + bomService.deleteById(inputObject, outputObject); + } + + /** + * 根据规格id获取方案列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBomListByNormsId", value = "根据规格id获取方案列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "normsId", name = "normsId", value = "规格id")}) + @RequestMapping("/post/BomController/queryBomListByNormsId") + public void queryBomListByNormsId(InputObject inputObject, OutputObject outputObject) { + bomService.queryBomListByNormsId(inputObject, outputObject); + } + + /** + * 根据商品信息以及bom方案信息获取商品树---用于生产模块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "material015", value = "根据商品信息以及bom方案信息获取商品树---用于生产模块", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "proList", name = "proList", value = "商品信息列表json串,需要包含materialId,normsId,bomId", required = "required,json")}) + @RequestMapping("/post/MaterialController/queryMaterialBomChildsToProduceByJson") + public void queryMaterialBomChildsToProduceByJson(InputObject inputObject, OutputObject outputObject) { + bomService.queryMaterialBomChildsToProduceByJson(inputObject, outputObject); + } + + /** + * 根据id发布bom + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "publishBomVersionById", value = "根据id发布bom", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "方案id", required = "required")}) + @RequestMapping("/post/BomController/publishBomVersionById") + public void publishBomVersionById(InputObject inputObject, OutputObject outputObject) { + bomService.publishVersionById(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomChildDao.java new file mode 100644 index 0000000..a16bb6a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomChildDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.dao; + +import com.skyeye.bom.entity.BomChild; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: BomChildDao + * @Description: bom表子件清单数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BomChildDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomDao.java new file mode 100644 index 0000000..93c87ef --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/dao/BomDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.dao; + +import com.skyeye.bom.entity.Bom; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ErpBomDao + * @Description: bom清单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BomDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/Bom.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/Bom.java new file mode 100644 index 0000000..ecad51e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/Bom.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.Version; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Bom + * @Description: bom表实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_BOM_CACHE_KEY) +@TableName(value = "erp_bom") +@ApiModel("bom表实体类") +public class Bom extends Version { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "make_num") + @ApiModelProperty(value = "制造的数量", required = "required,num") + private Integer makeNum; + + @TableField(value = "consumables_price") + @Property(value = "耗材总费用") + private String consumablesPrice; + + @TableField(value = "procedure_price") + @Property(value = "工序总费用") + private String procedurePrice; + + @TableField(value = "all_price") + @Property(value = "总费用") + private String allPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "子件清单", required = "required,json") + private List bomChildList; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/BomChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/BomChild.java new file mode 100644 index 0000000..b49d145 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/entity/BomChild.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.procedure.entity.WayProcedure; +import lombok.Data; + +/** + * @ClassName: BomChild + * @Description: bom表子件清单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_BOM_CACHE_KEY) +@TableName(value = "erp_bom_child", autoResultMap = true) +@ApiModel("bom表子件清单实体类") +public class BomChild extends CommonInfo { + + @TableId("id") + private String id; + + @TableField(exist = false) + @Property(value = "新的id") + private String newId; + + @TableField(exist = false) + @Property(value = "新的父节点id") + private String newParentId; + + @TableField(value = "bom_id") + @Property(value = "bom表id") + private String bomId; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "从属关系的商品id", required = "required", defaultValue = "0") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "need_num") + @ApiModelProperty(value = "需要的数量", required = "required,num") + private Integer needNum; + + @TableField(value = "consumables_price") + @ApiModelProperty(value = "耗材总费用") + private String consumablesPrice; + + @TableField(value = "all_price") + @Property(value = "总费用") + private String allPrice; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(value = "way_procedure_id") + @ApiModelProperty(value = "工艺id") + private String wayProcedureId; + + @TableField(exist = false) + @Property(value = "工艺信息") + private WayProcedure wayProcedureMation; + + @TableField(exist = false) + @Property(value = "树节点是否展开") + private boolean open; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomChildService.java new file mode 100644 index 0000000..deee38d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomChildService.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.bom.entity.BomChild; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: BomChildService + * @Description: bom表子件清单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:46 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BomChildService extends SkyeyeBusinessService { + + /** + * 计算耗材总费用 + * + * @param bomChildList + * @return + */ + String calcConsumablesPrice(List bomChildList); + + /** + * 计算工艺总费用 + * + * @param bomChildList + * @return + */ + String calcProcedurePrice(List bomChildList); + + void deleteBomChildByBomId(String bomId); + + List queryBomChildByBomId(String bomId); + + Map> queryBomChildByBomId(List bomIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomService.java new file mode 100644 index 0000000..d37f0ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/BomService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.bom.entity.Bom; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpBomService + * @Description: bom清单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BomService extends SkyeyeBusinessService { + + void queryBomListByNormsId(InputObject inputObject, OutputObject outputObject); + + Map> getBomListByNormsId(String... normsId); + + void queryMaterialBomChildsToProduceByJson(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomChildServiceImpl.java new file mode 100644 index 0000000..8ebfbd6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomChildServiceImpl.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bom.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.bom.dao.BomChildDao; +import com.skyeye.bom.entity.BomChild; +import com.skyeye.bom.service.BomChildService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.procedure.entity.WayProcedure; +import com.skyeye.procedure.service.WayProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: BomChildServiceImpl + * @Description: bom表子件清单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/27 14:47 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "bom表子件清单", groupName = "bom清单管理", manageShow = false) +public class BomChildServiceImpl extends SkyeyeBusinessServiceImpl implements BomChildService { + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private WayProcedureService wayProcedureService; + + /** + * 计算耗材总费用 + * + * @param bomChildList + * @return + */ + @Override + public String calcConsumablesPrice(List bomChildList) { + String allConsumablesPrice = "0"; + // 获取规格id + List normsIds = bomChildList.stream().map(BomChild::getNormsId).collect(Collectors.toList()); + Map materialNormsMap = materialNormsService.selectMapByIds(normsIds); + for (BomChild bomChild : bomChildList) { + MaterialNorms materialNorms = materialNormsMap.get(bomChild.getNormsId()); + // 单个子件耗材总费用 所需要的数量 * 成本价 + String consumablesPrice = CalculationUtil.multiply(String.valueOf(bomChild.getNeedNum()), materialNorms.getEstimatePurchasePrice()); + bomChild.setConsumablesPrice(consumablesPrice); + allConsumablesPrice = CalculationUtil.add(allConsumablesPrice, consumablesPrice, CommonNumConstants.NUM_TWO); + } + return allConsumablesPrice; + } + + @Override + public String calcProcedurePrice(List bomChildList) { + String allProcedurePrice = "0"; + // 查询工艺信息 + List wayProcedureIdList = bomChildList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getWayProcedureId())) + .map(BomChild::getWayProcedureId).distinct().collect(Collectors.toList()); + Map wayProcedureMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(wayProcedureIdList)) { + wayProcedureMap = wayProcedureService.selectMapByIds(wayProcedureIdList); + } + for (BomChild bomChild : bomChildList) { + String allPrice = bomChild.getConsumablesPrice(); + if (StrUtil.isEmpty(bomChild.getWayProcedureId())) { + bomChild.setAllPrice(allPrice); + continue; + } + WayProcedure wayProcedure = wayProcedureMap.get(bomChild.getWayProcedureId()); + if (ObjectUtil.isEmpty(wayProcedure)) { + bomChild.setAllPrice(allPrice); + continue; + } + allProcedurePrice = CalculationUtil.add(allProcedurePrice, wayProcedure.getAllPrice(), CommonNumConstants.NUM_TWO); + // 子件清单总价 + allPrice = CalculationUtil.add(allPrice, wayProcedure.getAllPrice(), CommonNumConstants.NUM_TWO); + bomChild.setAllPrice(allPrice); + } + return allProcedurePrice; + } + + @Override + protected void createPrepose(List entity) { + BomChild child = entity.stream().findFirst().orElse(new BomChild()); + deleteBomChildByBomId(child.getBomId()); + } + + @Override + public void deleteBomChildByBomId(String bomId) { + if (StrUtil.isEmpty(bomId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BomChild::getBomId), bomId); + remove(queryWrapper); + } + + @Override + public List queryBomChildByBomId(String bomId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BomChild::getBomId), bomId); + List bomChildren = list(queryWrapper); + return bomChildren; + } + + @Override + public Map> queryBomChildByBomId(List bomIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(BomChild::getBomId), bomIds); + List bomChildren = list(queryWrapper); + Map> listMap = bomChildren.stream().collect(Collectors.groupingBy(BomChild::getBomId)); + return listMap; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomServiceImpl.java new file mode 100644 index 0000000..fc7bfc7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/bom/service/impl/BomServiceImpl.java @@ -0,0 +1,261 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.bom.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.bom.dao.BomDao; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.entity.BomChild; +import com.skyeye.bom.service.BomChildService; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.procedure.service.WayProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ErpBomServiceImpl + * @Description: bom清单服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "bom清单管理", groupName = "bom清单管理") +public class BomServiceImpl extends SkyeyeBusinessServiceImpl implements BomService { + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private BomChildService bomChildService; + + @Autowired + private WayProcedureService wayProcedureService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Bom::getWhetherLast), WhetherEnum.ENABLE_USING.getKey()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + return beans; + } + + @Override + public String createEntity(Bom entity, String userId) { + entity.setStartSmallVersion(false); + return super.createEntity(entity, userId); + } + + @Override + public String updateEntity(Bom entity, String userId) { + entity.setStartSmallVersion(false); + return super.updateEntity(entity, userId); + } + + @Override + public void validatorEntity(Bom entity) { + super.validatorEntity(entity); + BomChild checkMaterial = entity.getBomChildList().stream().filter(bomChild -> StrUtil.equals(entity.getMaterialId(), bomChild.getMaterialId())).findFirst().orElse(null); + if (ObjectUtil.isNotEmpty(checkMaterial)) { + throw new CustomException("子件清单中不能包含父件信息"); + } + entity.getBomChildList().forEach(bomChild -> { + if (bomChild.getNeedNum() == 0) { + throw new CustomException("子件数量不能为0"); + } + }); + entity.setConsumablesPrice(bomChildService.calcConsumablesPrice(entity.getBomChildList())); + entity.setProcedurePrice(bomChildService.calcProcedurePrice(entity.getBomChildList())); + entity.setAllPrice(CalculationUtil.add(entity.getConsumablesPrice(), entity.getProcedurePrice(), CommonNumConstants.NUM_TWO)); + } + + @Override + protected void writePostpose(Bom entity, String userId) { + super.writePostpose(entity, userId); + + entity.getBomChildList().forEach(bomChild -> bomChild.setBomId(entity.getId())); + bomChildService.createEntity(entity.getBomChildList(), userId); + } + + @Override + public Bom getDataFromDb(String id) { + Bom bom = super.getDataFromDb(id); + // 设置子件清单信息 + bom.setBomChildList(bomChildService.queryBomChildByBomId(bom.getId())); + return bom; + } + + @Override + protected List getDataFromDb(List idList) { + List bomList = super.getDataFromDb(idList); + List ids = bomList.stream().map(Bom::getId).collect(Collectors.toList()); + // 设置子件清单信息 + Map> bomChildMap = bomChildService.queryBomChildByBomId(ids); + bomList.forEach(bom -> { + String id = bom.getId(); + bom.setBomChildList(bomChildMap.get(id)); + }); + return bomList; + } + + @Override + public Bom selectById(String id) { + Bom bom = super.selectById(id); + + // 查询工艺信息 + wayProcedureService.setDataMation(bom.getBomChildList(), BomChild::getWayProcedureId); + bom.getBomChildList().forEach(bomChild -> { + bomChild.setOpen(true); + }); + // 设置产品/规格信息 + materialService.setDataMation(bom.getBomChildList(), BomChild::getMaterialId); + materialNormsService.setDataMation(bom.getBomChildList(), BomChild::getNormsId); + materialService.setDataMation(bom, Bom::getMaterialId); + materialNormsService.setDataMation(bom, Bom::getNormsId); + return bom; + } + + @Override + public List selectByIds(String... ids) { + List bomList = super.selectByIds(ids); + + // 查询工艺信息 + bomList.forEach(bom -> { + wayProcedureService.setDataMation(bom.getBomChildList(), BomChild::getWayProcedureId); + bom.getBomChildList().forEach(bomChild -> { + bomChild.setOpen(true); + }); + // 设置产品/规格信息 + materialService.setDataMation(bom.getBomChildList(), BomChild::getMaterialId); + materialNormsService.setDataMation(bom.getBomChildList(), BomChild::getNormsId); + }); + materialService.setDataMation(bomList, Bom::getMaterialId); + materialNormsService.setDataMation(bomList, Bom::getNormsId); + + return bomList; + } + + @Override + public void deletePostpose(String id) { + bomChildService.deleteBomChildByBomId(id); + } + + /** + * 根据规格id获取方案列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryBomListByNormsId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String normsId = map.get("normsId").toString(); + if (StrUtil.isEmpty(normsId)) { + return; + } + Map> listMap = getBomListByNormsId(normsId); + List bomList = listMap.get(normsId); + if (CollectionUtil.isEmpty(bomList)) { + return; + } + materialNormsService.setDataMation(bomList, Bom::getNormsId); + + outputObject.setBeans(bomList); + outputObject.settotal(bomList.size()); + } + + @Override + public Map> getBomListByNormsId(String... normsId) { + List normsIdList = Arrays.asList(normsId); + if (CollectionUtil.isEmpty(normsIdList)) { + return cn.hutool.core.map.MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Bom::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(Bom::getNormsId), normsIdList); + queryWrapper.eq(MybatisPlusUtil.toColumns(Bom::getWhetherLast), WhetherEnum.ENABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Bom::getWhetherPublish), WhetherEnum.ENABLE_USING.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Bom::getCreateTime)); + List bomList = list(queryWrapper); + return bomList.stream().collect(Collectors.groupingBy(Bom::getNormsId)); + } + + /** + * 根据商品信息以及bom方案信息获取商品树---用于生产模块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMaterialBomChildsToProduceByJson(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String proList = map.get("proList").toString(); + // 处理数据 + List> beans = JSONUtil.toList(proList, null); + // 设置产品/规格信息 + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + // 获取方案下的子件 + List bomIds = beans.stream() + .filter(bean -> !MapUtil.checkKeyIsNull(bean, "bomId") && StrUtil.isNotEmpty(bean.get("bomId").toString())) + .map(bean -> bean.get("bomId").toString()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(bomIds)) { + Map bomMap = selectMapByIds(bomIds); + List tempList = new ArrayList<>(); + beans.forEach(bean -> { + String bomId = bean.get("bomId").toString(); + if (StrUtil.isNotEmpty(bomId)) { + if (!bomMap.containsKey(bomId)) { + return; + } + tempList.addAll(bomMap.get(bomId).getBomChildList()); + } + }); + if (CollectionUtil.isNotEmpty(tempList)) { + beans.addAll(tempList.stream() + .map(temp -> BeanUtil.beanToMap(temp)).collect(Collectors.toList())); + } + } + outputObject.setBeans(beans); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/controller/BrandController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/controller/BrandController.java new file mode 100644 index 0000000..a8f3ae0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/controller/BrandController.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.brand.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.brand.entity.Brand; +import com.skyeye.brand.service.BrandService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BrandController + * @Description: 品牌管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "品牌管理", tags = "品牌管理", modelName = "品牌管理") +public class BrandController { + + @Autowired + private BrandService brandService; + + /** + * 获取品牌列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBrandList", value = "获取品牌列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BrandController/queryBrandList") + public void queryBrandList(InputObject inputObject, OutputObject outputObject) { + brandService.queryPageList(inputObject, outputObject); + } + + /** + * 根据已启用的品牌列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledBrandList", value = "根据已启用查询品牌列表", method = "POST", allUse = "0") + @RequestMapping("/post/BrandController/queryEnabledBrandList") + public void queryEnabledBrandList(InputObject inputObject, OutputObject outputObject) { + brandService.queryEnabledBrandList(inputObject, outputObject); + } + + /** + * 根据已启用查询品牌列表(可分页) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPageEnabledBrandList", value = "根据已启用查询品牌列表(可分页)", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BrandController/queryPageEnabledBrandList") + public void queryPageEnabledBrandList(InputObject inputObject, OutputObject outputObject) { + brandService.queryPageEnabledBrandList(inputObject, outputObject); + } + + /** + * 新增/编辑品牌信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBrand", value = "新增/编辑品牌信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Brand.class) + @RequestMapping("/post/BrandController/writeBrand") + public void writeBrand(InputObject inputObject, OutputObject outputObject) { + brandService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID删除品牌信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBrandById", value = "根据ID删除品牌信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/BrandController/deleteBrandById") + public void deleteBrandById(InputObject inputObject, OutputObject outputObject) { + brandService.deleteById(inputObject, outputObject); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/dao/BrandDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/dao/BrandDao.java new file mode 100644 index 0000000..9cfb98e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/dao/BrandDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.brand.dao; + +import com.skyeye.brand.entity.Brand; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: BrandDao + * @Description: 品牌管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BrandDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/entity/Brand.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/entity/Brand.java new file mode 100644 index 0000000..36a6166 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/entity/Brand.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.brand.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Brand + * @Description: 品牌管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"name"}) +@RedisCacheField(name = "erp:brand") +@TableName(value = "erp_brand") +@ApiModel("品牌表实体类") +public class Brand extends BaseGeneralInfo { + + @TableField(value = "img") + @ApiModelProperty(value = "背景图") + private String img; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "logo") + @ApiModelProperty(value = "logo图片", required = "required") + private String logo; +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/BrandService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/BrandService.java new file mode 100644 index 0000000..77e63a1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/BrandService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.brand.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.brand.entity.Brand; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: BrandService + * @Description: 品牌管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BrandService extends SkyeyeBusinessService { + void queryEnabledBrandList(InputObject inputObject, OutputObject outputObject); + + void queryPageEnabledBrandList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/impl/BrandServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/impl/BrandServiceImpl.java new file mode 100644 index 0000000..5f4c162 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/brand/service/impl/BrandServiceImpl.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.brand.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.brand.dao.BrandDao; +import com.skyeye.brand.entity.Brand; +import com.skyeye.brand.service.BrandService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: BrandServiceImpl + * @Description: 品牌管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "品牌管理", groupName = "品牌管理") +public class BrandServiceImpl extends SkyeyeBusinessServiceImpl implements BrandService { + + @Override + public void queryEnabledBrandList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(Brand::getEnabled), EnableEnum.ENABLE_USING.getKey()); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(Brand::getCreateTime)); + List brandList = list(wrapper); + outputObject.setBeans(brandList); + outputObject.settotal(brandList.size()); + } + + @Override + public void queryPageEnabledBrandList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = null; + setCommonPageInfoOtherInfo(commonPageInfo); + if (commonPageInfo.getIsPaging() == null || commonPageInfo.getIsPaging()) { + pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + } + QueryWrapper wrapper = getQueryWrapper(commonPageInfo); + wrapper.eq(MybatisPlusUtil.toColumns(Brand::getEnabled), EnableEnum.ENABLE_USING.getKey()); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(Brand::getCreateTime)); + List brandList = list(wrapper); + outputObject.setBeans(brandList); + outputObject.settotal(pages.getTotal()); + } +} \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderItemQualityInspectionType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderItemQualityInspectionType.java new file mode 100644 index 0000000..c6aba38 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderItemQualityInspectionType.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.classenum; + +import cn.hutool.core.map.MapUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: OrderItemQualityInspectionType + * @Description: 采购订单/采购入库单 质检类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 16:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OrderItemQualityInspectionType implements SkyeyeEnumClass { + + NOT_NEED_QUALITYINS_INS(1, "免检", true, true), + SAMPLING_INS(2, "抽检", true, false), + FULL_INSPECTION(3, "全检", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static Map getMation(Integer type) { + for (OrderItemQualityInspectionType bean : OrderItemQualityInspectionType.values()) { + if (type == bean.getKey()) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderQualityInspectionType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderQualityInspectionType.java new file mode 100644 index 0000000..5fba350 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/classenum/OrderQualityInspectionType.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OrderQualityInspectionType + * @Description: 单据质检类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 16:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OrderQualityInspectionType implements SkyeyeEnumClass { + + NOT_NEED_QUALITYINS_INS(1, "免检", "purple", true, true), + NEED_QUALITYINS_INS(2, "需要质检", "blue", true, false), + PARTIAL_QUALITY_INSPECTION(3, "部分质检完成", "orange", true, false), + COMPLATE_QUALITY_INSPECTION(4, "全部质检完成", "green", true, false); + + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/ErpOrderItemCodeService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/ErpOrderItemCodeService.java new file mode 100644 index 0000000..39caf8f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/ErpOrderItemCodeService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.entity.ErpOrderItemCode; + +import java.util.List; + +/** + * @ClassName: ErpOrderItemCodeService + * @Description: 单据子表关联的条形码编号服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 19:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpOrderItemCodeService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String... parentId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderItemService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderItemService.java new file mode 100644 index 0000000..0bfaabd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderItemService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.TransmitObject; + +import java.util.List; + +/** + * @ClassName: SkyeyeErpOrderItemService + * @Description: ERP单据关联的商品的service接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 20:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SkyeyeErpOrderItemService extends SkyeyeLinkDataService { + + /** + * 计算单据信息的总价 + * + * @param object + * @param erpOrderItemList + * @return + */ + List calcOrderAllTotalPrice(TransmitObject object, List erpOrderItemList); + + List queryErpOrderItemByPIds(List pIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderService.java new file mode 100644 index 0000000..7db4717 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/SkyeyeErpOrderService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SkyeyeErpOrderService + * @Description: ERP单据的service接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 20:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SkyeyeErpOrderService extends SkyeyeFlowableService { + + /** + * 获取指定单据id已经(审批通过)的产品的数量 + * + * @param fromId 来源单据id + * @return + */ + Map calcMaterialNormsNumByFromId(String fromId); + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + + void editOtherState(String id, Integer otherState); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/ErpOrderItemCodeServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/ErpOrderItemCodeServiceImpl.java new file mode 100644 index 0000000..0b53d8c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/ErpOrderItemCodeServiceImpl.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.business.service.ErpOrderItemCodeService; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dao.ErpOrderItemCodeDao; +import com.skyeye.entity.ErpOrderItemCode; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: ErpOrderItemCodeServiceImpl + * @Description: 单据子表关联的条形码编号服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 19:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ErpOrderItemCodeServiceImpl extends SkyeyeBusinessServiceImpl implements ErpOrderItemCodeService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ErpOrderItemCode erpOrderItemCode : beans) { + erpOrderItemCode.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderItemCode::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String... parentId) { + List parentIdList = Arrays.asList(parentId); + if (CollectionUtil.isEmpty(parentIdList)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderItemCode::getParentId), parentIdList); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderItemServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderItemServiceImpl.java new file mode 100644 index 0000000..6ec6c00 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderItemServiceImpl.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.business.service.SkyeyeErpOrderItemService; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dao.ErpOrderItemDao; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.TransmitObject; +import com.skyeye.exception.CustomException; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @ClassName: SkyeyeErpOrderItemServiceImpl + * @Description: ERP单据关联的商品的service服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 20:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SkyeyeErpOrderItemServiceImpl extends SkyeyeLinkDataServiceImpl implements SkyeyeErpOrderItemService { + + @Override + protected void checkLinkList(String pId, List beans) { + beans.forEach(erpOrderItem -> { + if (StrUtil.isNotEmpty(erpOrderItem.getDepotId()) + && StrUtil.isNotEmpty(erpOrderItem.getAnotherDepotId())) { + if (StrUtil.equals(erpOrderItem.getDepotId(), erpOrderItem.getAnotherDepotId())) { + throw new CustomException("出入库仓库不能一样。"); + } + } + }); + } + + /** + * 计算单据信息的总价 + * + * @param object + * @param erpOrderItemList + * @return + */ + @Override + public List calcOrderAllTotalPrice(TransmitObject object, List erpOrderItemList) { + erpOrderItemList.forEach(erpOrderItem -> { + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(erpOrderItem.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(erpOrderItem.getOperNumber())); + erpOrderItem.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(erpOrderItem.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(erpOrderItem.getOperNumber())); + erpOrderItem.setTaxLastMoney(taxUnitPrice.toString()); + // 计算主单总价 + object.setTaxLastMoneyPrice(CalculationUtil.add(object.getTaxLastMoneyPrice(), erpOrderItem.getTaxLastMoney())); + }); + return erpOrderItemList; + } + + @Override + public List queryErpOrderItemByPIds(List pIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderItem::getParentId), pIds); + return list(queryWrapper); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderServiceImpl.java new file mode 100644 index 0000000..ead57b2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/business/service/impl/SkyeyeErpOrderServiceImpl.java @@ -0,0 +1,525 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.classenum.OrderQualityInspectionType; +import com.skyeye.business.service.ErpOrderItemCodeService; +import com.skyeye.business.service.SkyeyeErpOrderItemService; +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CorrespondentEnterEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.crm.service.ICustomerService; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.entity.*; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.exception.CustomException; +import com.skyeye.holder.entity.HolderNorms; +import com.skyeye.holder.service.HolderNormsService; +import com.skyeye.ifs.service.IAccountService; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.purchase.service.impl.PurchasePutServiceImpl; +import com.skyeye.retail.service.impl.RetailOutLetServiceImpl; +import com.skyeye.seal.service.impl.SalesOutLetServiceImpl; +import com.skyeye.service.ErpCommonService; +import com.skyeye.shop.service.IMemberService; +import com.skyeye.supplier.entity.Supplier; +import com.skyeye.supplier.service.SupplierService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SkyeyeErpOrderServiceImpl + * @Description: ERP单据的service服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 20:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class SkyeyeErpOrderServiceImpl, T extends ErpOrderCommon> extends SkyeyeFlowableServiceImpl implements SkyeyeErpOrderService { + + @Autowired + protected SkyeyeErpOrderItemService skyeyeErpOrderItemService; + + @Autowired + protected ErpCommonService erpCommonService; + + @Autowired + protected SupplierService supplierService; + + @Autowired + protected IMemberService iMemberService; + + @Autowired + protected MaterialService materialService; + + @Autowired + protected IAccountService iAccountService; + + @Autowired + protected ICustomerService iCustomerService; + + @Autowired + protected ErpDepotService erpDepotService; + + @Autowired + protected HolderNormsService holderNormsService; + + @Autowired + protected MaterialNormsService materialNormsService; + + @Autowired + protected MaterialNormsCodeService materialNormsCodeService; + + @Autowired + protected ErpOrderItemCodeService erpOrderItemCodeService; + + /** + * 会员 + */ + private static final String MEMBER_KEY = "com.skyeye.service.impl.MemberServiceImpl"; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), getServiceClassName()); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderHead::getHolderId), commonPageInfo.getHolderId()); + } + return queryWrapper; + } + + public QueryWrapper getGrandFatherQueryWrapper(CommonPageInfo commonPageInfo) { + return super.getQueryWrapper(commonPageInfo); + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + setHolderMation(beans); + return beans; + } + + private void setHolderMation(List> beans) { + if (!ErpOrderHead.class.isAssignableFrom(clazz)) { + return; + } + // 供应商 + List supplierIds = beans.stream() + .filter(bean -> StrUtil.equals(CorrespondentEnterEnum.SUPPLIER.getKey(), bean.get("holderKey").toString())) + .map(bean -> bean.get("holderId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(supplierIds)) { + Map supplierMap = supplierService.selectMapByIds(supplierIds); + beans.forEach(bean -> { + if (StrUtil.equals(CorrespondentEnterEnum.SUPPLIER.getKey(), bean.get("holderKey").toString())) { + bean.put("holderMation", supplierMap.get(bean.get("holderId").toString())); + } + }); + } + // 客户 + List customerIds = beans.stream() + .filter(bean -> StrUtil.equals(CorrespondentEnterEnum.CUSTOM.getKey(), bean.get("holderKey").toString())) + .map(bean -> bean.get("holderId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(customerIds)) { + Map> customerMap = iCustomerService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(customerIds)); + beans.forEach(bean -> { + if (StrUtil.equals(CorrespondentEnterEnum.CUSTOM.getKey(), bean.get("holderKey").toString())) { + bean.put("holderMation", customerMap.get(bean.get("holderId").toString())); + } + }); + } + + // 会员 + List memberIds = beans.stream() + .filter(bean -> StrUtil.equals(MEMBER_KEY, bean.get("holderKey").toString())) + .map(bean -> bean.get("holderId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(memberIds)) { + Map> supplierMap = iMemberService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(memberIds)); + beans.forEach(bean -> { + if (StrUtil.equals(MEMBER_KEY, bean.get("holderKey").toString())) { + bean.put("holderMation", supplierMap.get(bean.get("holderId").toString())); + } + }); + } + } + + @Override + public void createPrepose(T entity) { + chectErpOrderItem(entity.getErpOrderItemList()); + entity.setIdKey(getServiceClassName()); + getTotalPrice(entity); + // 设置商品为使用中 + entity.getErpOrderItemList().forEach(erpOrderItem -> { + materialService.setUsed(erpOrderItem.getMaterialId()); + }); + super.createPrepose(entity); + } + + private void chectErpOrderItem(List erpOrderItemList) { + if (CollectionUtil.isEmpty(erpOrderItemList)) { + throw new CustomException("请最少选择一条产品信息"); + } + List normsIds = erpOrderItemList.stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + if (erpOrderItemList.size() != normsIds.size()) { + throw new CustomException("单据中不允许存在重复的产品规格信息"); + } + } + + private void setHolderMation(T entity) { + if (!ErpOrderHead.class.isAssignableFrom(clazz)) { + return; + } + String holderId = StrUtil.toString(ReflectUtil.getFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getHolderId))); + if (StrUtil.isNotEmpty(holderId)) { + String holderKey = StrUtil.toString(ReflectUtil.getFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getHolderKey))); + if (StrUtil.equals(CorrespondentEnterEnum.SUPPLIER.getKey(), holderKey)) { + Map supplier = supplierService.selectMapById(holderId); + ReflectUtil.setFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getHolderMation), supplier); + } else if (StrUtil.equals(CorrespondentEnterEnum.CUSTOM.getKey(), holderKey)) { + Map customer = iCustomerService.queryDataMationById(holderId); + ReflectUtil.setFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getHolderMation), customer); + } else if (StrUtil.equals(MEMBER_KEY, holderKey)) { + Map member = iMemberService.queryDataMationById(holderId); + ReflectUtil.setFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getHolderMation), member); + } + } + } + + protected static Integer setQualityInspection(ErpOrderItem erpOrderItem, Integer qualityInspection) { + if (erpOrderItem.getQualityInspection() == OrderItemQualityInspectionType.SAMPLING_INS.getKey() + || erpOrderItem.getQualityInspection() == OrderItemQualityInspectionType.FULL_INSPECTION.getKey()) { + qualityInspection = OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey(); + } + if (erpOrderItem.getQualityInspection() == OrderItemQualityInspectionType.SAMPLING_INS.getKey()) { + // 抽检 + String qualityInspectionRatio = erpOrderItem.getQualityInspectionRatio(); + if (StrUtil.isEmpty(qualityInspectionRatio)) { + throw new CustomException("抽检比例不能为空."); + } + if (CommonNumConstants.NUM_ZERO.equals(Integer.parseInt(qualityInspectionRatio))) { + throw new CustomException("抽检比例不能为0."); + } + if (Integer.parseInt(qualityInspectionRatio) > 100) { + throw new CustomException("抽检比例不能大于100."); + } + } else if (erpOrderItem.getQualityInspection() == OrderItemQualityInspectionType.FULL_INSPECTION.getKey()) { + // 全检 + erpOrderItem.setQualityInspectionRatio(StrUtil.EMPTY); + } + return qualityInspection; + } + + @Override + public void writeChild(T entity, String userId) { + skyeyeErpOrderItemService.saveLinkList(entity.getId(), entity.getErpOrderItemList()); + super.writeChild(entity, userId); + } + + /** + * 保存单据子表关联的条形码编号信息 + * + * @param entity + */ + protected void saveErpOrderItemCode(T entity) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + // 保存单据子表关联的条形码编号信息 + List erpOrderItemCodeList = new ArrayList<>(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + ErpOrderItemCode erpOrderItemCode = new ErpOrderItemCode(); + erpOrderItemCode.setNormsCode(normsCode); + erpOrderItemCode.setMaterialId(erpOrderItem.getMaterialId()); + erpOrderItemCode.setNormsId(erpOrderItem.getNormsId()); + erpOrderItemCodeList.add(erpOrderItemCode); + }); + } + } + erpOrderItemCodeService.saveList(entity.getId(), erpOrderItemCodeList); + } + + /** + * 删除关联的编码信息 + * + * @param id + */ + protected void deleteErpOrderItemCodeById(String id) { + // 删除关联的编码信息 + erpOrderItemCodeService.deleteByParentId(id); + } + + /** + * 查询单据子表关联的条形码编号信息 + * + * @param entity + */ + protected void queryErpOrderItemCodeById(T entity) { + String id = entity.getId(); + // 查询单据子表关联的条形码编号信息 + List erpOrderItemCodeList = erpOrderItemCodeService.selectByParentId(id); + Map> collect = erpOrderItemCodeList.stream().collect(Collectors.groupingBy(ErpOrderItemCode::getNormsId)); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + List erpOrderItemCodes = collect.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isNotEmpty(erpOrderItemCodes)) { + List normsCodeList = erpOrderItemCodes.stream().map(ErpOrderItemCode::getNormsCode).collect(Collectors.toList()); + erpOrderItem.setNormsCodeList(normsCodeList); + erpOrderItem.setNormsCode(Joiner.on("\n").join(normsCodeList)); + } + }); + } + + @Override + public void updatePrepose(T entity) { + chectErpOrderItem(entity.getErpOrderItemList()); + getTotalPrice(entity); + } + + private void getTotalPrice(T entity) { + if (ErpOrderHead.class.isAssignableFrom(clazz)) { + String totalPrice = "0"; + TransmitObject object = new TransmitObject(); + // 计算关联的产品总价 + List erpOrderItemList = skyeyeErpOrderItemService.calcOrderAllTotalPrice(object, entity.getErpOrderItemList()); + entity.setErpOrderItemList(erpOrderItemList); + totalPrice = CalculationUtil.add(totalPrice, object.getTaxLastMoneyPrice()); + // 减去优惠金额 + String discountMoney = String.valueOf(ReflectUtil.getFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getDiscountMoney))); + if (NumberUtil.isNumber(discountMoney)) { + totalPrice = CalculationUtil.subtract(totalPrice, discountMoney); + } + ReflectUtil.setFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getTotalPrice), totalPrice); + } + } + + @Override + public T getDataFromDb(String id) { + T erpOrderHead = super.getDataFromDb(id); + List erpOrderItemList = skyeyeErpOrderItemService.selectByPId(id); + erpOrderHead.setErpOrderItemList(erpOrderItemList); + return erpOrderHead; + } + + @Override + public T selectById(String id) { + T erpOrderHead = super.selectById(id); + // 设置关联的客户/供应商/会员信息 + setHolderMation(erpOrderHead); + // 设置产品信息 + materialService.setDataMation(erpOrderHead.getErpOrderItemList(), ErpOrderItem::getMaterialId); + erpOrderHead.getErpOrderItemList().forEach(erpOrderItem -> { + MaterialNorms norms = erpOrderItem.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(erpOrderItem.getNormsId(), bean.getId())).findFirst().orElse(null); + erpOrderItem.setNormsMation(norms); + }); + // 账户信息 + setAccountMation(erpOrderHead); + // 仓库信息 + erpDepotService.setDataMation(erpOrderHead.getErpOrderItemList(), ErpOrderItem::getDepotId); + erpDepotService.setDataMation(erpOrderHead.getErpOrderItemList(), ErpOrderItem::getAnotherDepotId); + // 业务员信息 + iAuthUserService.setDataMation(erpOrderHead, ErpOrderCommon::getSalesman); + return erpOrderHead; + } + + private void setAccountMation(T entity) { + if (!ErpOrderHead.class.isAssignableFrom(clazz)) { + return; + } + String accountId = StrUtil.toString(ReflectUtil.getFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getAccountId))); + if (StrUtil.isNotEmpty(accountId) && !StrUtil.equals("null", accountId)) { + ReflectUtil.setFieldValue(entity, MybatisPlusUtil.toFieldName(ErpOrderHead::getAccountMation), + iAccountService.queryDataMationById(accountId)); + } + } + + @Override + public void deletePostpose(String id) { + // 删除子单据信息 + skyeyeErpOrderItemService.deleteByPId(id); + } + + protected void depotOutOrPutSuccess(String holderId, String holderKey, List erpOrderItemList, int type, + String orderId, String orderIdKey) { + List holderNormsList = new ArrayList<>(); + // 采购入库单,销售出库单,零售出库单 + List orderTypes = Arrays.asList(PurchasePutServiceImpl.class.getName(), SalesOutLetServiceImpl.class.getName(), RetailOutLetServiceImpl.class.getName()); + String createTime = DateUtil.getTimeAndToString(); + // 修改库存&&保存客户/供应商/会员关联的商品信息 + for (ErpOrderItem bean : erpOrderItemList) { + erpCommonService.editMaterialNormsDepotStock(bean.getDepotId(), bean.getMaterialId(), bean.getNormsId(), bean.getOperNumber(), type); + + if (StrUtil.isNotEmpty(holderId) && StrUtil.isNotEmpty(holderKey) && orderTypes.contains(orderIdKey)) { + // 记录客户/供应商/会员关联的商品 + HolderNorms holderNorms = new HolderNorms(); + holderNorms.setHolderId(holderId); + holderNorms.setHolderKey(holderKey); + holderNorms.setMaterialId(bean.getMaterialId()); + holderNorms.setNormsId(bean.getNormsId()); + holderNorms.setCreateTime(createTime); + holderNorms.setOperNumber(bean.getOperNumber()); + holderNorms.setNormsCodeList(bean.getNormsCodeList()); + holderNorms.setOrderId(orderId); + holderNorms.setOrderKey(orderIdKey); + holderNorms.setDepotId(bean.getDepotId()); + holderNormsList.add(holderNorms); + } + } + holderNormsService.createEntity(holderNormsList, StrUtil.EMPTY); + } + + /** + * 校验单据商品是否存在来源单据中不包含的商品 + * + * @param erpOrderItemList 来源单据的子单据信息 + * @param inSqlNormsId + */ + protected void checkFromOrderMaterialNorms(List erpOrderItemList, List inSqlNormsId) { + List fromNormsIds = erpOrderItemList.stream() + .map(ErpOrderItem::getNormsId).collect(Collectors.toList()); + checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + } + + protected void checkIdFromOrderMaterialNorms(List fromNormsIds, List inSqlNormsId) { + // 求差集(当前单据在来源单据中不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该来源单据下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + } + + /** + * 计算来源单据剩余未操作的数量 + * + * @param erpOrderItemList + * @param setData + * @param nums + */ + protected void setOrCheckOperNumber(List erpOrderItemList, boolean setData, Map... nums) { + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = ErpOrderUtil.checkOperNumber(erpOrderItem.getOperNumber(), erpOrderItem.getNormsId(), nums); + if (setData) { + erpOrderItem.setOperNumber(surplusNum); + } + }); + } + + protected int checkErpOrderItemDetail(T entity, Map materialMap, Map normsMap, List allNormsCodeList) { + int allCodeNum = 0; + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + MaterialNorms norms = normsMap.get(erpOrderItem.getNormsId()); + if (erpOrderItem.getOperNumber() == 0) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的数量不能为0,请确认", material.getName(), norms.getName())); + } + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + // 过滤掉空的,并且去重 + List normsCodeList = Arrays.asList(erpOrderItem.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (erpOrderItem.getOperNumber() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的条形码数量与明细数量不一致,请确认", material.getName(), norms.getName())); + } + allCodeNum += normsCodeList.size(); + erpOrderItem.setNormsCodeList(normsCodeList); + allNormsCodeList.addAll(normsCodeList); + } + } + return allCodeNum; + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), getServiceClassName()); + // 只查询审批通过,部分出入库,已完成的单据 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getState), stateList); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(ErpOrderCommon::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + Map collect = erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.summingInt(ErpOrderItem::getOperNumber))); + return collect; + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List entityList = list(queryWrapper); + Map entityMap = entityList.stream().collect(Collectors.toMap(ErpOrderCommon::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + T entity = entityMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + @Override + public void editOtherState(String id, Integer otherState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), otherState); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/classenum/ErpOrderStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/classenum/ErpOrderStateEnum.java new file mode 100644 index 0000000..6c982ef --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/classenum/ErpOrderStateEnum.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: ErpOrderStateEnum + * @Description: ERP单据状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ErpOrderStateEnum implements SkyeyeEnumClass { + + PARTIALLY_COMPLETED("partiallyCompleted", "部分完成", "orange", true, false), + COMPLETED("completed", "已完成", "green", true, false); + + private String key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractAuthEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractAuthEnum.java new file mode 100644 index 0000000..15f598b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractAuthEnum.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SupplierContractAuthEnum + * @Description: 供应商合同权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SupplierContractAuthEnum implements SkyeyeEnumClass { + + LIST("list", "查看列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false), + PERFORM("perform", "执行", true, false), + CLOSE("close", "关闭", true, false), + LAY_ASIDE("layAside", "搁置", true, false), + RECOVERY("recovery", "恢复", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractChildStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractChildStateEnum.java new file mode 100644 index 0000000..5f4930d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractChildStateEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SupplierContractChildStateEnum + * @Description: 合同产品状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SupplierContractChildStateEnum implements SkyeyeEnumClass { + + PENDING_ORDER("pendingOrder", "待下达订单", true, false), + PARTIAL_RELEASE("partialRelease", "部分下达", true, false), + ALL_ISSUED("allIssued", "全部下达", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractFromType.java new file mode 100644 index 0000000..bb0d86c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SupplierContractFromType + * @Description: 供应商合同来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SupplierContractFromType implements SkyeyeEnumClass { + + PURCHASE_REQUEST(1, "采购申请单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractStateEnum.java new file mode 100644 index 0000000..9624d3b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/classenum/SupplierContractStateEnum.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: SupplierContractStateEnum + * @Description: 供应商合同状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 18:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SupplierContractStateEnum implements SkyeyeEnumClass { + + EXECUTING("executing", "执行中", true, false), + CLOSE("close", "关闭", true, false), + LAY_ASIDE("layAside", "搁置", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/controller/SupplierContractController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/controller/SupplierContractController.java new file mode 100644 index 0000000..f67d331 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/controller/SupplierContractController.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.contract.service.SupplierContractService; +import com.skyeye.purchase.entity.PurchaseOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SupplierContractController + * @Description: 供应商合同管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 16:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "供应商合同管理", tags = "供应商合同管理", modelName = "供应商合同管理") +public class SupplierContractController { + + @Autowired + private SupplierContractService supplierContractService; + + /** + * 获取合同列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySupplierContractList", value = "获取合同列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SupplierContractController/querySupplierContractList") + public void querySupplierContractList(InputObject inputObject, OutputObject outputObject) { + supplierContractService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSupplierContract", value = "新增/编辑合同信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SupplierContract.class) + @RequestMapping("/post/SupplierContractController/writeSupplierContract") + public void writeSupplierContract(InputObject inputObject, OutputObject outputObject) { + supplierContractService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSupplierContractById", value = "删除合同信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/deleteSupplierContractById") + public void deleteSupplierContractById(InputObject inputObject, OutputObject outputObject) { + supplierContractService.deleteById(inputObject, outputObject); + } + + /** + * 根据id批量获取供应商合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySupplierContractByIds", value = "根据id批量获取供应商合同信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/querySupplierContractByIds") + public void querySupplierContractById(InputObject inputObject, OutputObject outputObject) { + supplierContractService.selectByIds(inputObject, outputObject); + } + + /** + * 根据供应商id获取合同管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract008", value = "根据供应商id获取合同管理列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required")}) + @RequestMapping("/post/SupplierContractController/querySupplierContractListByObjectId") + public void querySupplierContractListByObjectId(InputObject inputObject, OutputObject outputObject) { + supplierContractService.querySupplierContractListByObjectId(inputObject, outputObject); + } + + /** + * 合同提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract009", value = "合同提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/SupplierContractController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + supplierContractService.submitToApproval(inputObject, outputObject); + } + + /** + * 合同执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract010", value = "合同执行", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/performSupplierContract") + public void performSupplierContract(InputObject inputObject, OutputObject outputObject) { + supplierContractService.performSupplierContract(inputObject, outputObject); + } + + /** + * 合同关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract011", value = "合同关闭", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/closeSupplierContract") + public void closeSupplierContract(InputObject inputObject, OutputObject outputObject) { + supplierContractService.closeSupplierContract(inputObject, outputObject); + } + + /** + * 合同搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract012", value = "合同搁置", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/shelveSupplierContract") + public void shelveSupplierContract(InputObject inputObject, OutputObject outputObject) { + supplierContractService.shelveSupplierContract(inputObject, outputObject); + } + + /** + * 合同恢复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract013", value = "合同恢复", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/recoverySupplierContract") + public void recoverySupplierContract(InputObject inputObject, OutputObject outputObject) { + supplierContractService.recoverySupplierContract(inputObject, outputObject); + } + + /** + * 作废合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract015", value = "作废合同信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + supplierContractService.invalid(inputObject, outputObject); + } + + /** + * 撤销合同审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mysuppliercontract016", value = "撤销合同审批", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/SupplierContractController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + supplierContractService.revoke(inputObject, outputObject); + } + + /** + * 转采购订单时,根据合同id查询合同信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySupplierContractTransById", value = "转采购订单时,根据合同id查询合同信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/querySupplierContractTransById") + public void querySupplierContractTransById(InputObject inputObject, OutputObject outputObject) { + supplierContractService.querySupplierContractTransById(inputObject, outputObject); + } + + /** + * 转采购订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "supplierContractToOrder", value = "转采购订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseOrder.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierContractController/supplierContractToOrder") + public void supplierContractToOrder(InputObject inputObject, OutputObject outputObject) { + supplierContractService.supplierContractToOrder(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractChildDao.java new file mode 100644 index 0000000..e30cdda --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.dao; + +import com.skyeye.contract.entity.SupplierContractChild; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SupplierContractChildDao + * @Description: 供应商合同-商品明细数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/23 22:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierContractChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractDao.java new file mode 100644 index 0000000..cf5ca46 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/dao/SupplierContractDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.dao; + +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SupplierContractDao + * @Description: 供应商合同管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/14 14:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierContractDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContract.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContract.java new file mode 100644 index 0000000..90999fd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContract.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SupplierContract + * @Description: 供应商合同信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "title"}) +@RedisCacheField(name = CacheConstants.ERP_SUPPLIER_CONTRACT_CACHE_KEY, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_supplier_contract", autoResultMap = true) +@ApiModel("供应商合同信息实体类") +public class SupplierContract extends SkyeyeFlowable { + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField(value = "title") + @ApiModelProperty(value = "合同名称", required = "required", fuzzyLike = true) + private String title; + + @TableField(exist = false) + @Property(value = "合同名称") + private String name; + + @TableField(value = "price") + @ApiModelProperty(value = "合同金额", required = "double", defaultValue = "0") + private String price; + + @TableField(value = "material_total_price") + @ApiModelProperty(value = "产品明细总金额", required = "double", defaultValue = "0") + private String materialTotalPrice; + + @TableField(value = "signing_time") + @ApiModelProperty(value = "签约日期", required = "required") + private String signingTime; + + @TableField(value = "effect_time") + @ApiModelProperty(value = "生效日期") + private String effectTime; + + @TableField(value = "service_end_time") + @ApiModelProperty(value = "服务结束日期") + private String serviceEndTime; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人ID", required = "required") + private String contacts; + + @TableField(exist = false) + @Property(value = "联系人") + private Map contactsMation; + + @TableField(value = "technical_terms") + @ApiModelProperty(value = "主要技术条款") + private String technicalTerms; + + @TableField(value = "business_terms") + @ApiModelProperty(value = "主要商务条款") + private String businessTerms; + + @TableField(value = "department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Map departmentMation; + + @TableField(value = "relation_user_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "关联人员", required = "required,json") + private List relationUserId; + + @TableField(exist = false) + @Property(value = "关联人员") + private List> relationUserMation; + + @TableField(exist = false) + @ApiModelProperty(value = "商品明细信息", required = "json") + private List supplierContractChildList; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#SupplierContractFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("child_state") + @Property(value = "合同产品状态,参考#SupplierContractChildStateEnum") + private String childState; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContractChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContractChild.java new file mode 100644 index 0000000..2217408 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/entity/SupplierContractChild.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +/** + * @ClassName: SupplierContractChild + * @Description: 供应商合同-商品明细实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_supplier_contract_child") +@ApiModel("供应商合同-商品明细实体类") +public class SupplierContractChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractChildService.java new file mode 100644 index 0000000..105fbd3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractChildService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.contract.entity.SupplierContractChild; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SupplierContractChildService + * @Description: 供应商合同-商品明细服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/23 22:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierContractChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + Map> selectByParentId(List parentIds); + + List getSupplierContractChildList(List parentIds); + + String calcOrderAllTotalPrice(List supplierContractChildList); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractService.java new file mode 100644 index 0000000..a14dd86 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/SupplierContractService.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.SupplierContract; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SupplierContractService + * @Description: 供应商合同管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 22:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierContractService extends SkyeyeFlowableService { + + void querySupplierContractListByObjectId(InputObject inputObject, OutputObject outputObject); + + void performSupplierContract(InputObject inputObject, OutputObject outputObject); + + void closeSupplierContract(InputObject inputObject, OutputObject outputObject); + + void shelveSupplierContract(InputObject inputObject, OutputObject outputObject); + + void recoverySupplierContract(InputObject inputObject, OutputObject outputObject); + + /** + * 根据所属第三方业务数据id查询合同信息 + * + * @param objectId 所属第三方业务数据id + * @return + */ + List querySupplierContractListByObjectId(String objectId); + + /** + * 根据单据来源id计算已经签订合同的商品数量 + * + * @param fromId 单据来源id + * @return + */ + Map calcMaterialNormsNumByFromId(String fromId); + + void querySupplierContractTransById(InputObject inputObject, OutputObject outputObject); + + void supplierContractToOrder(InputObject inputObject, OutputObject outputObject); + + void setContractMationByFromId(List> beans, String idKey, String mationKey); + + /** + * 修改合同下达状态 + * + * @param id 合同id + * @param childState 到货状态 + */ + void editChildState(String id, String childState); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractChildServiceImpl.java new file mode 100644 index 0000000..e08cd72 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractChildServiceImpl.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.dao.SupplierContractChildDao; +import com.skyeye.contract.entity.SupplierContractChild; +import com.skyeye.contract.service.SupplierContractChildService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SupplierContractChildServiceImpl + * @Description: 供应商合同-商品明细服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/23 22:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "供应商合同-商品明细", groupName = "供应商合同管理", manageShow = false) +public class SupplierContractChildServiceImpl extends SkyeyeBusinessServiceImpl implements SupplierContractChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (SupplierContractChild supplierContractChild : beans) { + supplierContractChild.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContractChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContractChild::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public Map> selectByParentId(List parentIds) { + List list = getSupplierContractChildList(parentIds); + return list.stream().collect(Collectors.groupingBy(SupplierContractChild::getParentId)); + } + + @Override + public List getSupplierContractChildList(List parentIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(SupplierContractChild::getParentId), parentIds); + List list = list(queryWrapper); + return list; + } + + @Override + public String calcOrderAllTotalPrice(List supplierContractChildList) { + String totalPrice = "0"; + for (SupplierContractChild supplierContractChild : supplierContractChildList) { + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(supplierContractChild.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(supplierContractChild.getOperNumber())); + supplierContractChild.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(supplierContractChild.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(supplierContractChild.getOperNumber())); + supplierContractChild.setTaxLastMoney(taxUnitPrice.toString()); + totalPrice = CalculationUtil.add(totalPrice, supplierContractChild.getTaxLastMoney()); + } + return totalPrice; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractServiceImpl.java new file mode 100644 index 0000000..bbf7e71 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/contract/service/impl/SupplierContractServiceImpl.java @@ -0,0 +1,553 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contract.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.classenum.SupplierContractAuthEnum; +import com.skyeye.contract.classenum.SupplierContractChildStateEnum; +import com.skyeye.contract.classenum.SupplierContractFromType; +import com.skyeye.contract.classenum.SupplierContractStateEnum; +import com.skyeye.contract.dao.SupplierContractDao; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.contract.entity.SupplierContractChild; +import com.skyeye.contract.service.SupplierContractChildService; +import com.skyeye.contract.service.SupplierContractService; +import com.skyeye.eve.contacts.service.IContactsService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.purchase.classenum.PurchaseOrderFromType; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.request.classenum.PurchaseRequestStateEnum; +import com.skyeye.request.entity.PurchaseRequest; +import com.skyeye.request.entity.PurchaseRequestFixedChild; +import com.skyeye.request.service.PurchaseRequestService; +import com.skyeye.supplier.service.SupplierService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SupplierContractServiceImpl + * @Description: 供应商合同管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "供应商合同管理", groupName = "供应商合同管理", flowable = true, teamAuth = true) +public class SupplierContractServiceImpl extends SkyeyeFlowableServiceImpl implements SupplierContractService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IContactsService iContactsService; + + @Autowired + private SupplierContractChildService supplierContractChildService; + + @Autowired + private MaterialService materialService; + + @Autowired + private PurchaseRequestService purchaseRequestService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private SupplierService supplierService; + + @Override + public Class getAuthEnumClass() { + return SupplierContractAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(SupplierContractAuthEnum.ADD.getKey(), SupplierContractAuthEnum.EDIT.getKey(), SupplierContractAuthEnum.DELETE.getKey(), + SupplierContractAuthEnum.REVOKE.getKey(), SupplierContractAuthEnum.INVALID.getKey(), SupplierContractAuthEnum.SUBMIT_TO_APPROVAL.getKey(), SupplierContractAuthEnum.LIST.getKey(), + SupplierContractAuthEnum.PERFORM.getKey(), SupplierContractAuthEnum.CLOSE.getKey(), SupplierContractAuthEnum.LAY_ASIDE.getKey(), SupplierContractAuthEnum.RECOVERY.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getObjectId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getObjectId), commonPageInfo.getObjectId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + purchaseRequestService.setRequestMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(SupplierContract entity) { + super.validatorEntity(entity); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(SupplierContract entity) { + getTotalPrice(entity); + if (CollectionUtil.isNotEmpty(entity.getSupplierContractChildList())) { + entity.setChildState(SupplierContractChildStateEnum.PENDING_ORDER.getKey()); + } + // 设置商品为使用中 + entity.getSupplierContractChildList().forEach(supplierContractChild -> { + materialService.setUsed(supplierContractChild.getMaterialId()); + }); + super.createPrepose(entity); + } + + @Override + public void updatePrepose(SupplierContract entity) { + getTotalPrice(entity); + if (CollectionUtil.isNotEmpty(entity.getSupplierContractChildList())) { + entity.setChildState(SupplierContractChildStateEnum.PENDING_ORDER.getKey()); + } + } + + private void checkMaterialNorms(SupplierContract entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + if (CollectionUtil.isEmpty(entity.getSupplierContractChildList())) { + throw new CustomException("合同下无商品信息,请确认."); + } + // 当前订单的商品数量 + Map orderNormsNum = entity.getSupplierContractChildList().stream() + .collect(Collectors.toMap(SupplierContractChild::getNormsId, SupplierContractChild::getOperNumber)); + // 获取已经签订合同的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == SupplierContractFromType.PURCHASE_REQUEST.getKey()) { + PurchaseRequest purchaseRequest = purchaseRequestService.selectById(entity.getFromId()); + List fromNormsIds = purchaseRequest.getPurchaseRequestFixedChildList().stream() + .map(PurchaseRequestFixedChild::getNormsId).collect(Collectors.toList()); + // 求差集(采购申请单中不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该采购申请单下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + purchaseRequest.getPurchaseRequestFixedChildList().forEach(purchaseRequestFixedChild -> { + Integer surplusNum = purchaseRequestFixedChild.getOperNumber() + - (orderNormsNum.containsKey(purchaseRequestFixedChild.getNormsId()) ? orderNormsNum.get(purchaseRequestFixedChild.getNormsId()) : 0) + - (executeNum.containsKey(purchaseRequestFixedChild.getNormsId()) ? executeNum.get(purchaseRequestFixedChild.getNormsId()) : 0); + if (surplusNum < 0) { + throw new CustomException("超出采购申请单的商品数量."); + } + if (setData) { + purchaseRequestFixedChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List purchaseRequestFixedChildList = purchaseRequest.getPurchaseRequestFixedChildList().stream() + .filter(purchaseRequestFixedChild -> purchaseRequestFixedChild.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该采购申请单的商品已经全部签订合同,那说明已经完成了申请单的内容 + if (CollectionUtil.isEmpty(purchaseRequestFixedChildList)) { + purchaseRequestService.editStateById(purchaseRequest.getId(), PurchaseRequestStateEnum.PROCUREMENT_COMPLETED.getKey()); + } else { + purchaseRequestService.editStateById(purchaseRequest.getId(), PurchaseRequestStateEnum.PARTIAL_PROCUREMENT.getKey()); + } + } + } + } + + private void getTotalPrice(SupplierContract entity) { + // 计算关联的产品总价 + String totalPrice = supplierContractChildService.calcOrderAllTotalPrice(entity.getSupplierContractChildList()); + entity.setMaterialTotalPrice(totalPrice); + } + + @Override + public void writeChild(SupplierContract entity, String userId) { + supplierContractChildService.saveList(entity.getId(), entity.getSupplierContractChildList()); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + supplierContractChildService.deleteByParentId(id); + } + + @Override + public SupplierContract getDataFromDb(String id) { + SupplierContract supplierContract = super.getDataFromDb(id); + // 设置合同商品信息 + List supplierContractChildList = supplierContractChildService.selectByParentId(supplierContract.getId()); + supplierContract.setSupplierContractChildList(supplierContractChildList); + return supplierContract; + } + + @Override + public SupplierContract selectById(String id) { + SupplierContract supplierContract = super.selectById(id); + Map department = iDepmentService.queryDataMationById(supplierContract.getDepartmentId()); + supplierContract.setDepartmentMation(department); + // 联系人信息 + iContactsService.setDataMation(supplierContract, SupplierContract::getContacts); + // 设置关联人员 + supplierContract.setRelationUserMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(supplierContract.getRelationUserId()))); + // 设置合同商品详情信息 + materialService.setDataMation(supplierContract.getSupplierContractChildList(), SupplierContractChild::getMaterialId); + supplierContract.getSupplierContractChildList().forEach(supplierContractChild -> { + MaterialNorms norms = supplierContractChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(supplierContractChild.getNormsId(), bean.getId())).findFirst().orElse(null); + supplierContractChild.setNormsMation(norms); + }); + if (supplierContract.getFromTypeId() == SupplierContractFromType.PURCHASE_REQUEST.getKey()) { + // 采购申请单 + purchaseRequestService.setDataMation(supplierContract, SupplierContract::getFromId); + } + return supplierContract; + } + + @Override + public List getDataFromDb(List idList) { + List supplierContractList = super.getDataFromDb(idList); + // 设置合同商品信息 + Map> childMap = supplierContractChildService.selectByParentId(idList); + supplierContractList.forEach(supplierContract -> { + supplierContract.setSupplierContractChildList(childMap.get(supplierContract.getId())); + }); + return supplierContractList; + } + + @Override + public List selectByIds(String... ids) { + List supplierContractList = super.selectByIds(ids); + iDepmentService.setDataMation(supplierContractList, SupplierContract::getDepartmentId); + // 联系人信息 + iContactsService.setDataMation(supplierContractList, SupplierContract::getContacts); + // 设置关联人员 + List relationUserIds = supplierContractList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getRelationUserId())) + .flatMap(norms -> norms.getRelationUserId().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(relationUserIds)) { + Map> userMap = iAuthUserService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(relationUserIds)); + supplierContractList.forEach(supplierContract -> { + if (CollectionUtil.isEmpty(supplierContract.getRelationUserId())) { + return; + } + List> userMation = new ArrayList<>(); + supplierContract.getRelationUserId().forEach(operatorId -> { + if (!userMap.containsKey(operatorId)) { + return; + } + userMation.add(userMap.get(operatorId)); + }); + supplierContract.setRelationUserMation(userMation); + }); + } + + // 设置合同商品详情信息 + List materialIds = supplierContractList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getSupplierContractChildList())) + .flatMap(farm -> farm.getSupplierContractChildList().stream().map(SupplierContractChild::getMaterialId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(materialIds)) { + List materialList = materialService.selectByIds(materialIds.toArray(new String[]{})); + Map materialMap = materialList.stream().collect(Collectors.toMap(bean -> bean.getId(), item -> item)); + supplierContractList.forEach(supplierContract -> { + if (CollectionUtil.isNotEmpty(supplierContract.getSupplierContractChildList())) { + // 合同商品明细不为空 + supplierContract.getSupplierContractChildList().forEach(supplierContractChild -> { + Material material = materialMap.get(supplierContractChild.getMaterialId()); + supplierContractChild.setMaterialMation(material); + MaterialNorms norms = supplierContractChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(supplierContractChild.getNormsId(), bean.getId())).findFirst().orElse(null); + supplierContractChild.setNormsMation(norms); + }); + } + }); + } + + return supplierContractList; + } + + /** + * 根据供应商id获取合同列表用于下拉框选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySupplierContractListByObjectId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getState), SupplierContractStateEnum.EXECUTING.getKey()); + List supplierContractList = list(queryWrapper); + supplierContractList.forEach(supplierContract -> { + supplierContract.setName(supplierContract.getTitle()); + }); + outputObject.setBeans(supplierContractList); + outputObject.settotal(supplierContractList.size()); + } + + /** + * 合同执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void performSupplierContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SupplierContract supplierContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(supplierContract, userId, CommonNumConstants.NUM_SEVEN); + if (supplierContract.getState().equals(FlowableStateEnum.PASS.getKey())) { + // 审核通过可以执行 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SupplierContract::getState), SupplierContractStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void closeSupplierContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SupplierContract supplierContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(supplierContract, userId, CommonNumConstants.NUM_EIGHT); + if (supplierContract.getState().equals(SupplierContractStateEnum.EXECUTING.getKey())) { + // 执行中可以关闭 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SupplierContract::getState), SupplierContractStateEnum.CLOSE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同搁置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void shelveSupplierContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SupplierContract supplierContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(supplierContract, userId, CommonNumConstants.NUM_NINE); + if (supplierContract.getState().equals(SupplierContractStateEnum.EXECUTING.getKey())) { + // 执行中可以搁置 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SupplierContract::getState), SupplierContractStateEnum.LAY_ASIDE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 合同恢复 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void recoverySupplierContract(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SupplierContract supplierContract = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(supplierContract, userId, CommonNumConstants.NUM_TEN); + if (supplierContract.getState().equals(SupplierContractStateEnum.LAY_ASIDE.getKey())) { + // 搁置中可以恢复 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SupplierContract::getState), SupplierContractStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 根据所属第三方业务数据id查询合同信息 + * + * @param objectId 所属第三方业务数据id + * @return + */ + @Override + public List querySupplierContractListByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getObjectId), objectId); + return list(queryWrapper); + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SupplierContract::getFromId), fromId); + // 只查询审批通过,执行中,关闭,搁置状态的 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), SupplierContractStateEnum.EXECUTING.getKey(), + SupplierContractStateEnum.CLOSE.getKey(), SupplierContractStateEnum.LAY_ASIDE.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(SupplierContract::getState), stateList); + List supplierContractList = list(queryWrapper); + List ids = supplierContractList.stream().map(SupplierContract::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + // 获取所有的商品信息 + List supplierContractChildList = supplierContractChildService.getSupplierContractChildList(ids); + if (CollectionUtil.isNotEmpty(supplierContractChildList)) { + // 分组计算已经签订合同的数量 + return supplierContractChildList.stream() + .collect(Collectors.groupingBy(SupplierContractChild::getNormsId, Collectors.summingInt(SupplierContractChild::getOperNumber))); + } + return cn.hutool.core.map.MapUtil.newHashMap(); + } + + @Override + public void approvalEndIsSuccess(SupplierContract entity) { + entity = selectById(entity.getId()); + checkMaterialNorms(entity, true); + } + + @Override + public void querySupplierContractTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + SupplierContract supplierContract = selectById(id); + if (CollectionUtil.isEmpty(supplierContract.getSupplierContractChildList())) { + throw new CustomException("合同下无商品信息,无需转采购订单."); + } + // 获取已经下达采购订单的商品信息 + Map executeNum = purchaseOrderService.calcMaterialNormsNumByFromId(supplierContract.getId()); + supplierContract.getSupplierContractChildList().forEach(supplierContractChild -> { + Integer surplusNum = supplierContractChild.getOperNumber() + - (executeNum.containsKey(supplierContractChild.getNormsId()) ? executeNum.get(supplierContractChild.getNormsId()) : 0); + // 设置未下达采购订单的商品数量 + supplierContractChild.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成采购订单 + supplierContract.setSupplierContractChildList(supplierContract.getSupplierContractChildList().stream() + .filter(purchaseRequestChild -> purchaseRequestChild.getOperNumber() > 0).collect(Collectors.toList())); + + supplierService.setDataMation(supplierContract, SupplierContract::getObjectId); + + outputObject.setBean(supplierContract); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void supplierContractToOrder(InputObject inputObject, OutputObject outputObject) { + PurchaseOrder purchaseOrder = inputObject.getParams(PurchaseOrder.class); + purchaseOrder.setFromId(purchaseOrder.getId()); + purchaseOrder.setFromTypeId(PurchaseOrderFromType.SUPPLIER_CONTRACT.getKey()); + purchaseOrder.setId(null); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 保存采购订单 + purchaseOrderService.createEntity(purchaseOrder, userId); + } + + @Override + public void setContractMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List supplierContractList = list(queryWrapper); + Map supplierContractMap = supplierContractList.stream() + .collect(Collectors.toMap(SupplierContract::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + SupplierContract entity = supplierContractMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + @Override + public void editChildState(String id, String childState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SupplierContract::getChildState), childState); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpCommonController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpCommonController.java new file mode 100644 index 0000000..9042df0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpCommonController.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.service.ErpCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ErpCommonController + * @Description: ERP进销存公共接口控制类 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "公共接口", tags = "公共接口", modelName = "公共接口") +public class ErpCommonController { + + @Autowired + private ErpCommonService erpCommonService; + + /** + * 获取ERP单据详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryErpOrderById", value = "获取ERP单据详情", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "订单id", required = "required"), + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "单据类型,值为服务类的className", required = "required")}) + @RequestMapping("/post/ErpCommonController/queryDepotHeadDetailsMationById") + public void queryDepotHeadDetailsMationById(InputObject inputObject, OutputObject outputObject) { + erpCommonService.queryDepotHeadDetailsMationById(inputObject, outputObject); + } + + /** + * 删除单据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpcommon005", value = "删除ERP单据信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "订单id", required = "required"), + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "单据类型,值为服务类的className", required = "required")}) + @RequestMapping("/post/ErpCommonController/deleteErpOrderById") + public void deleteErpOrderById(InputObject inputObject, OutputObject outputObject) { + erpCommonService.deleteErpOrderById(inputObject, outputObject); + } + + /** + * erp相关单据撤销审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpcommon003", value = "erp相关单据撤销审批", method = "PUT", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required"), + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "单据类型,值为服务类的className", required = "required")}) + @RequestMapping("/post/ErpCommonController/editDepotHeadToRevoke") + public void editDepotHeadToRevoke(InputObject inputObject, OutputObject outputObject) { + erpCommonService.editDepotHeadToRevoke(inputObject, outputObject); + } + + /** + * 订单信息提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpcommon006", value = "订单信息提交审核", method = "PUT", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "订单id", required = "required"), + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "单据类型,值为服务类的className", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ErpCommonController/orderSubmitToApproval") + public void orderSubmitToApproval(InputObject inputObject, OutputObject outputObject) { + erpCommonService.orderSubmitToApproval(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpPageController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpPageController.java new file mode 100644 index 0000000..de7422f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/ErpPageController.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.service.ErpPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ErpPageController + * @Description: ERP统计模块控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/2 11:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "ERP统计模块", tags = "ERP统计模块", modelName = "ERP统计模块") +public class ErpPageController { + + @Autowired + private ErpPageService erpPageService; + + /** + * 获取本月累计销售,本月累计零售,本月累计采购,本月利润(已审核通过) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppage001", value = "获取本月累计销售,本月累计零售,本月累计采购,本月利润(已审核通过)", method = "POST", allUse = "2") + @RequestMapping("/post/ErpPageController/queryFourTypeMoneyList") + public void queryFourTypeMoneyList(InputObject inputObject, OutputObject outputObject) { + erpPageService.queryFourTypeMoneyList(inputObject, outputObject); + } + + /** + * 获取近半年的采购统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppage002", value = "获取近半年的采购统计", method = "POST", allUse = "2") + @RequestMapping("/post/ErpPageController/querySixMonthPurchaseMoneyList") + public void querySixMonthPurchaseMoneyList(InputObject inputObject, OutputObject outputObject) { + erpPageService.querySixMonthPurchaseMoneyList(inputObject, outputObject); + } + + /** + * 获取近半年的销售统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppage003", value = "获取近半年的销售统计", method = "POST", allUse = "2") + @RequestMapping("/post/ErpPageController/querySixMonthSealsMoneyList") + public void querySixMonthSealsMoneyList(InputObject inputObject, OutputObject outputObject) { + erpPageService.querySixMonthSealsMoneyList(inputObject, outputObject); + } + + /** + * 获取近十二个月的利润统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppage004", value = "获取近十二个月的利润统计", method = "POST", allUse = "2") + @RequestMapping("/post/ErpPageController/queryTwelveMonthProfitMoneyList") + public void queryTwelveMonthProfitMoneyList(InputObject inputObject, OutputObject outputObject) { + erpPageService.queryTwelveMonthProfitMoneyList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/StatisticsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/StatisticsController.java new file mode 100644 index 0000000..653fbbc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/controller/StatisticsController.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.service.StatisticsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: StatisticsController + * @Description: 统计模块 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/20 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "统计模块", tags = "统计模块", modelName = "统计模块") +public class StatisticsController { + + @Autowired + private StatisticsService statisticsService; + + /** + * 入库明细 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics001", value = "入库明细", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/queryWarehousingDetails") + public void queryWarehousingDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.queryWarehousingDetails(inputObject, outputObject); + } + + /** + * 出库明细 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics002", value = "出库明细", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/queryOutgoingDetails") + public void queryOutgoingDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.queryOutgoingDetails(inputObject, outputObject); + } + + /** + * 进货统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics003", value = "进货统计", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/queryInComimgDetails") + public void queryInComimgDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.queryInComimgDetails(inputObject, outputObject); + } + + /** + * 销售统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics004", value = "销售统计", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/querySalesDetails") + public void querySalesDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.querySalesDetails(inputObject, outputObject); + } + + /** + * 客户对账 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics005", value = "客户对账", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/queryCustomerReconciliationDetails") + public void queryCustomerReconciliationDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.queryCustomerReconciliationDetails(inputObject, outputObject); + } + + /** + * 供应商对账 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "statistics006", value = "供应商对账", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StatisticsController/querySupplierReconciliationDetails") + public void querySupplierReconciliationDetails(InputObject inputObject, OutputObject outputObject) { + statisticsService.querySupplierReconciliationDetails(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemCodeDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemCodeDao.java new file mode 100644 index 0000000..0c8a215 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.entity.ErpOrderItemCode; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ErpOrderItemCodeDao + * @Description: 单据子表关联的条形码编号数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 19:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpOrderItemCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemDao.java new file mode 100644 index 0000000..20c8529 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpOrderItemDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ErpOrderItemDao + * @Description: ERP订单关联的产品数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpOrderItemDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpPageDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpPageDao.java new file mode 100644 index 0000000..38e9ab4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/ErpPageDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpPageDao + * @Description: ERP统计模块数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/2 11:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpPageDao { + + String queryThisMonthErpOrder(@Param("idKey") String idKey, @Param("states") List states); + + List> querySixMonthOrderMoneyList(@Param("idKey") String idKey, @Param("states") List states); + + List> queryTwelveMonthProfitMoneyList(@Param("idKeys") List idKeys, @Param("states") List states); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/StatisticsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/StatisticsDao.java new file mode 100644 index 0000000..36e42c9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/dao/StatisticsDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StatisticsDao + * @Description: erp统计管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StatisticsDao { + + List> queryErpOrderItem(CommonPageInfo pageInfo); + + List> queryPointSubTypeOrder(CommonPageInfo commonPageInfo); + + List> queryErpOrderListByIdKey(CommonPageInfo pageInfo); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutFromType.java new file mode 100644 index 0000000..4ed28a9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutFromType.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.other.service.impl.OtherOutLetsServiceImpl; +import com.skyeye.pick.service.impl.PatchOutLetServiceImpl; +import com.skyeye.pick.service.impl.RequisitionOutLetServiceImpl; +import com.skyeye.purchase.service.impl.PurchaseReturnsServiceImpl; +import com.skyeye.retail.service.impl.RetailOutLetServiceImpl; +import com.skyeye.seal.service.impl.SalesOutLetServiceImpl; +import com.skyeye.shop.service.impl.ShopOutLetsServiceImpl; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotOutFromType + * @Description: 仓库出库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotOutFromType implements SkyeyeEnumClass { + + PURCHASE_RETURNS(1, "采购退货单", PurchaseReturnsServiceImpl.class.getName(), true, false), + SEAL_OUTLET(2, "销售出库单", SalesOutLetServiceImpl.class.getName(), true, false), + RETAIL_OUTLET(3, "零售出库单", RetailOutLetServiceImpl.class.getName(), true, false), + OTHER_OUTLET(4, "其他出库单", OtherOutLetsServiceImpl.class.getName(), true, false), + REQUISITION_OUTLET(5, "领料出库单", RequisitionOutLetServiceImpl.class.getName(), true, false), + PATCH_OUTLET(6, "补料出库单", PatchOutLetServiceImpl.class.getName(), true, false), + SEAL_APPLY(7, "配件申领单", "com.skyeye.accessory.service.impl.SealApplyServiceImpl", true, false), + SHOP_OUTLET(8, "门店申领单", ShopOutLetsServiceImpl.class.getName(), true, false); + + private Integer key; + + private String value; + + private String idKey; + + private Boolean show; + + private Boolean isDefault; + + public static Integer getItemKey(String idKey) { + for (DepotOutFromType bean : DepotOutFromType.values()) { + if (StrUtil.equals(idKey, bean.getIdKey())) { + return bean.getKey(); + } + } + return null; + } + + public static String getItemIdKey(Integer key) { + for (DepotOutFromType bean : DepotOutFromType.values()) { + if (key == bean.getKey()) { + return bean.getIdKey(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutOtherState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutOtherState.java new file mode 100644 index 0000000..f03f468 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutOtherState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotOutOtherState + * @Description: 仓库出库单,领料/补料确认状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotOutOtherState implements SkyeyeEnumClass { + + NEED_CONFIRM(1, "待确认", "blue", true, false), + PARTIAL_CONFIRM(2, "部分确认", "orange", true, false), + COMPLATE_CONFIRM(3, "全部确认", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutState.java new file mode 100644 index 0000000..2d0e4b3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotOutState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotOutState + * @Description: 仓库出库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotOutState implements SkyeyeEnumClass { + + NOT_NEED_OUT(1, "无需出库", "purple", true, true), + NEED_OUT(2, "待出库", "blue", true, false), + PARTIAL_OUT(3, "部分出库", "orange", true, false), + COMPLATE_OUT(4, "全部出库", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutFromType.java new file mode 100644 index 0000000..e55d7e1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutFromType.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.machin.service.impl.MachinPutServiceImpl; +import com.skyeye.other.service.impl.OtherWareHousServiceImpl; +import com.skyeye.pick.service.impl.ReturnPutServiceImpl; +import com.skyeye.pickconfirm.service.impl.ConfirmReturnServiceImpl; +import com.skyeye.purchase.service.impl.PurchasePutServiceImpl; +import com.skyeye.retail.service.impl.RetailReturnsServiceImpl; +import com.skyeye.seal.service.impl.SalesReturnsServiceImpl; +import com.skyeye.shop.service.impl.ShopConfirmReturnServiceImpl; +import com.skyeye.shop.service.impl.ShopReturnsServiceImpl; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotPutFromType + * @Description: 仓库入库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotPutFromType implements SkyeyeEnumClass { + + PURCHASE_PUT(1, "采购入库单", PurchasePutServiceImpl.class.getName(), true, false), + SEAL_RETURNS(2, "销售退货单", SalesReturnsServiceImpl.class.getName(), true, false), + RETAIL_RETURNS(3, "零售退货单", RetailReturnsServiceImpl.class.getName(), true, false), + OTHER_WARE_HOUS(4, "其他入库单", OtherWareHousServiceImpl.class.getName(), true, false), + RETURN_PUT(5, "退料入库单", ReturnPutServiceImpl.class.getName(), true, false), + CONFIRM_RETURN(6, "物料退货单", ConfirmReturnServiceImpl.class.getName(), true, false), + MACHIN_PUT(7, "加工入库单", MachinPutServiceImpl.class.getName(), true, false), + SHOP_RETURNS(8, "门店退货单", ShopReturnsServiceImpl.class.getName(), true, false), + SHOP_CONFIRM_RETURNS(9, "门店物料退货单", ShopConfirmReturnServiceImpl.class.getName(), true, false); + + + private Integer key; + + private String value; + + private String idKey; + + private Boolean show; + + private Boolean isDefault; + + public static Integer getItemKey(String idKey) { + for (DepotPutFromType bean : DepotPutFromType.values()) { + if (StrUtil.equals(idKey, bean.getIdKey())) { + return bean.getKey(); + } + } + return null; + } + + public static String getItemIdKey(Integer key) { + for (DepotPutFromType bean : DepotPutFromType.values()) { + if (key == bean.getKey()) { + return bean.getIdKey(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutOutType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutOutType.java new file mode 100644 index 0000000..7e8f084 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutOutType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotPutOutType + * @Description: 出入库类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotPutOutType implements SkyeyeEnumClass { + + PUT(1, "入库", true, true), + OUT(2, "出库", true, false), + OTHER(3, "其他", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutState.java new file mode 100644 index 0000000..7779001 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/DepotPutState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DepotPutState + * @Description: 仓库入库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DepotPutState implements SkyeyeEnumClass { + + NOT_NEED_PUT(1, "无需入库", "purple", true, true), + NEED_PUT(2, "待入库", "blue", true, false), + PARTIAL_PUT(3, "部分入库", "orange", true, false), + COMPLATE_PUT(4, "全部入库", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/GenerateDepotLevelValType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/GenerateDepotLevelValType.java new file mode 100644 index 0000000..088a6bc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/classenum/GenerateDepotLevelValType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: GenerateDepotLevelValType + * @Description: 生成库存等级值编号类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum GenerateDepotLevelValType implements SkyeyeEnumClass { + + NUMBER(1, "数字", true, true), + LETTER(2, "字母", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelController.java new file mode 100644 index 0000000..6421b87 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotLevel; +import com.skyeye.depot.service.DepotLevelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepotLevelController + * @Description: 仓库级别控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 22:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库级别管理", tags = "仓库级别管理", modelName = "仓库级别管理") +public class DepotLevelController { + + @Autowired + private DepotLevelService depotLevelService; + + /** + * 新增/编辑仓库级别信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepotLevel", value = "新增/编辑仓库级别信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DepotLevel.class) + @RequestMapping("/post/DepotLevelController/writeDepotLevel") + public void writeDepotLevel(InputObject inputObject, OutputObject outputObject) { + depotLevelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取仓库级别信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotLevelById", value = "根据id获取仓库级别信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotLevelController/queryDepotLevelById") + public void queryDepotLevelById(InputObject inputObject, OutputObject outputObject) { + depotLevelService.selectById(inputObject, outputObject); + } + + /** + * 删除仓库级别信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDepotLevelById", value = "删除仓库级别信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotLevelController/deleteDepotLevelById") + public void deleteDepotLevelById(InputObject inputObject, OutputObject outputObject) { + depotLevelService.deleteById(inputObject, outputObject); + } + + /** + * 根据仓库id查询仓库级别信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotLevelByDepotId", value = "根据仓库id查询仓库级别信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "depotId", name = "depotId", value = "仓库id", required = "required")}) + @RequestMapping("/post/DepotLevelController/queryDepotLevelByDepotId") + public void queryDepotLevelByDepotId(InputObject inputObject, OutputObject outputObject) { + depotLevelService.queryDepotLevelByDepotId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelValController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelValController.java new file mode 100644 index 0000000..5d4db3f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotLevelValController.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotLevelVal; +import com.skyeye.depot.service.DepotLevelValService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepotLevelValController + * @Description: 仓库级别的值控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 10:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库级别的值管理", tags = "仓库级别的值管理", modelName = "仓库级别管理") +public class DepotLevelValController { + + @Autowired + private DepotLevelValService depotLevelValService; + + /** + * 获取仓库级别的值信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotLevelValList", value = "获取仓库级别的值信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotLevelValController/queryDepotLevelValList") + public void queryDepotLevelValList(InputObject inputObject, OutputObject outputObject) { + depotLevelValService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑仓库级别的值信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepotLevelVal", value = "新增/编辑仓库级别的值信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotLevelVal.class) + @RequestMapping("/post/DepotLevelValController/writeDepotLevelVal") + public void writeDepotLevelVal(InputObject inputObject, OutputObject outputObject) { + depotLevelValService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取仓库级别的值信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotLevelValById", value = "根据id获取仓库级别的值信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotLevelValController/queryDepotLevelValById") + public void queryDepotLevelValById(InputObject inputObject, OutputObject outputObject) { + depotLevelValService.selectById(inputObject, outputObject); + } + + /** + * 删除仓库级别的值信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDepotLevelValById", value = "删除仓库级别的值信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotLevelValController/deleteDepotLevelValById") + public void deleteDepotLevelValById(InputObject inputObject, OutputObject outputObject) { + depotLevelValService.deleteById(inputObject, outputObject); + } + + /** + * 批量生成仓库级别的值信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "batchGenerateDepotLevelVal", value = "批量生成仓库级别的值信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "type", name = "type", value = "生成的编号类型,参考#GenerateDepotLevelValType", required = "required,num"), + @ApiImplicitParam(id = "number", name = "number", value = "生成的数量", required = "required,num"), + @ApiImplicitParam(id = "parentId", name = "parentId", value = "父节点id", required = "required"), + @ApiImplicitParam(id = "depotId", name = "depotId", value = "仓库id", required = "required")}) + @RequestMapping("/post/DepotLevelValController/batchGenerateDepotLevelVal") + public void batchGenerateDepotLevelVal(InputObject inputObject, OutputObject outputObject) { + depotLevelValService.batchGenerateDepotLevelVal(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotOutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotOutController.java new file mode 100644 index 0000000..f765569 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotOutController.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.pickconfirm.entity.ConfirmPut; +import com.skyeye.pickconfirm.entity.ConfirmReturn; +import com.skyeye.shop.entity.ShopConfirmPut; +import com.skyeye.shop.entity.ShopConfirmReturn; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepotOutController + * @Description: 仓库出库单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 9:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库出库单", tags = "仓库出库单", modelName = "仓库出入库") +public class DepotOutController { + + @Autowired + private DepotOutService depotOutService; + + /** + * 获取仓库出库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotOutList", value = "获取仓库出库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotOutController/queryDepotOutList") + public void queryDepotOutList(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryPageList(inputObject, outputObject); + } + + /** + * 获取仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotOutOrderList", value = "获取仓库出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class, value = { + @ApiImplicitParam(id = "type", name = "type", value = "类型", required = "required", defaultValue = "DepotOut")}) + @RequestMapping("/post/DepotOutController/queryDepotOutOrderList") + public void queryDepotOutOrderList(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepotOut", value = "新增/编辑仓库出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DepotOut.class) + @RequestMapping("/post/DepotOutController/writeDepotOut") + public void writeDepotOut(InputObject inputObject, OutputObject outputObject) { + depotOutService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取需要物料确认的仓库出库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNeedConfirmDepotOutList", value = "获取需要物料确认的仓库出库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotOutController/queryNeedConfirmDepotOutList") + public void queryNeedConfirmDepotOutList(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryNeedConfirmDepotOutList(inputObject, outputObject); + } + + /** + * 转物料接收单/物料退货单时,根据id查询仓库出库单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotOutTransById", value = "转物料接收单/物料退货单时,根据id查询仓库出库单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/queryDepotOutTransById") + public void queryDepotOutTransById(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryDepotOutTransById(inputObject, outputObject); + } + + /** + * 仓库出库单转物料接收单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertDepotOutToTurnPut", value = "仓库出库单转物料接收单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConfirmPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/insertDepotOutToTurnPut") + public void insertDepotOutToTurnPut(InputObject inputObject, OutputObject outputObject) { + depotOutService.insertDepotOutToTurnPut(inputObject, outputObject); + } + + /** + * 仓库出库单转物料退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertDepotOutToSealsReturns", value = "仓库出库单转物料退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConfirmReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/insertDepotOutToSealsReturns") + public void insertDepotOutToSealsReturns(InputObject inputObject, OutputObject outputObject) { + depotOutService.insertDepotOutToSealsReturns(inputObject, outputObject); + } + + /** + * 获取需要门店物料确认的仓库出库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNeedStoreConfirmDepotOutList", value = "获取需要门店物料确认的仓库出库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotOutController/queryNeedStoreConfirmDepotOutList") + public void queryNeedStoreConfirmDepotOutList(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryNeedStoreConfirmDepotOutList(inputObject, outputObject); + } + + /** + * 转门店物料接收单/门店物料退货单时,根据id查询仓库出库单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotOutTransStoreById", value = "转门店物料接收单/门店物料退货单时,根据id查询仓库出库单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/queryDepotOutTransStoreById") + public void queryDepotOutTransStoreById(InputObject inputObject, OutputObject outputObject) { + depotOutService.queryDepotOutTransStoreById(inputObject, outputObject); + } + + /** + * 仓库出库单转门店物料接收单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertDepotOutToTurnStorePut", value = "仓库出库单转门店物料接收单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopConfirmPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/insertDepotOutToTurnStorePut") + public void insertDepotOutToTurnStorePut(InputObject inputObject, OutputObject outputObject) { + depotOutService.insertDepotOutToTurnStorePut(inputObject, outputObject); + } + + /** + * 仓库出库单转门店物料退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertDepotOutToStoreSealsReturns", value = "仓库出库单转门店物料退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopConfirmReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DepotOutController/insertDepotOutToStoreSealsReturns") + public void insertDepotOutToStoreSealsReturns(InputObject inputObject, OutputObject outputObject) { + depotOutService.insertDepotOutToStoreSealsReturns(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotPutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotPutController.java new file mode 100644 index 0000000..c747eb9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotPutController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepotPutController + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库入库单", tags = "仓库入库单", modelName = "仓库出入库") +public class DepotPutController { + + @Autowired + private DepotPutService depotPutService; + + /** + * 获取仓库入库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotPutList", value = "获取仓库入库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotPutController/queryDepotPutList") + public void queryDepotPutList(InputObject inputObject, OutputObject outputObject) { + depotPutService.queryPageList(inputObject, outputObject); + } + + /** + * 获取仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotPutOrderList", value = "获取仓库入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class, value = { + @ApiImplicitParam(id = "type", name = "type", value = "类型", required = "required", defaultValue = "DepotPut")}) + @RequestMapping("/post/DepotPutController/queryDepotPutOrderList") + public void queryDepotPutOrderList(InputObject inputObject, OutputObject outputObject) { + depotPutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepotPut", value = "新增/编辑仓库入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DepotPut.class) + @RequestMapping("/post/DepotPutController/writeDepotPut") + public void writeDepotPut(InputObject inputObject, OutputObject outputObject) { + depotPutService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotStaffController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotStaffController.java new file mode 100644 index 0000000..8293fbd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/DepotStaffController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotStaffVO; +import com.skyeye.depot.service.DepotStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepotStaffController + * @Description: 仓库与员工的关系管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库与员工的关系管理", tags = "仓库与员工的关系管理", modelName = "仓库与员工的关系管理") +public class DepotStaffController { + + @Autowired + private DepotStaffService depotStaffService; + + /** + * 获取仓库下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotStaffList", value = "获取仓库下的员工信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepotStaffController/queryDepotStaffList") + public void queryDepotStaffList(InputObject inputObject, OutputObject outputObject) { + depotStaffService.queryPageList(inputObject, outputObject); + } + + /** + * 删除仓库下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDepotStaffById", value = "删除仓库下的员工信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "仓库与员工的关系表主键id", required = "required")}) + @RequestMapping("/post/DepotStaffController/deleteDepotStaffById") + public void deleteDepotStaffById(InputObject inputObject, OutputObject outputObject) { + depotStaffService.deleteById(inputObject, outputObject); + } + + /** + * 新增仓库下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertDepotStaff", value = "新增仓库下的员工信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DepotStaffVO.class) + @RequestMapping("/post/DepotStaffController/insertDepotStaff") + public void insertDepotStaff(InputObject inputObject, OutputObject outputObject) { + depotStaffService.insertDepotStaff(inputObject, outputObject); + } + + /** + * 获取当前登陆用户所属的仓库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStaffBelongDepotList", value = "获取当前登陆用户所属的仓库列表", method = "GET", allUse = "2") + @RequestMapping("/post/DepotStaffController/queryStaffBelongDepotList") + public void queryStaffBelongDepotList(InputObject inputObject, OutputObject outputObject) { + depotStaffService.queryStaffBelongDepotList(inputObject, outputObject); + } + + /** + * 根据员工id删除所有的所属仓库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDepotStaffByStaffId", value = "根据员工id删除所有的所属仓库信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "员工id", required = "required")}) + @RequestMapping("/post/DepotStaffController/deleteDepotStaffByStaffId") + public void deleteDepotStaffByStaffId(InputObject inputObject, OutputObject outputObject) { + depotStaffService.deleteDepotStaffByStaffId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/ErpDepotController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/ErpDepotController.java new file mode 100644 index 0000000..f2427af --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/controller/ErpDepotController.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.Depot; +import com.skyeye.depot.service.ErpDepotService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ErpDepotController + * @Description: 仓库管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2019/9/14 10:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "仓库管理", tags = "仓库管理", modelName = "仓库管理") +public class ErpDepotController { + + @Autowired + private ErpDepotService erpDepotService; + + /** + * 获取仓库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storehouse001", value = "获取仓库信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ErpDepotController/queryStoreHouseList") + public void queryStoreHouseList(InputObject inputObject, OutputObject outputObject) { + erpDepotService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑仓库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepotMation", value = "新增/编辑仓库信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Depot.class) + @RequestMapping("/post/ErpDepotController/writeDepotMation") + public void writeDepotMation(InputObject inputObject, OutputObject outputObject) { + erpDepotService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id批量获取仓库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepotByIds", value = "根据id批量获取仓库信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/ErpDepotController/queryDepotByIds") + public void queryDepotByIds(InputObject inputObject, OutputObject outputObject) { + erpDepotService.selectByIds(inputObject, outputObject); + } + + /** + * 删除仓库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storehouse004", value = "删除仓库信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ErpDepotController/deleteStoreHouseById") + public void deleteStoreHouseById(InputObject inputObject, OutputObject outputObject) { + erpDepotService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有仓库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllStoreHouseList", value = "获取所有仓库", method = "GET", allUse = "2") + @RequestMapping("/post/ErpDepotController/queryAllStoreHouseList") + public void queryAllStoreHouseList(InputObject inputObject, OutputObject outputObject) { + erpDepotService.queryAllStoreHouseList(inputObject, outputObject); + } + + /** + * 获取当前登录用户管理的仓库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storehouse009", value = "获取当前登录用户管理的仓库列表", method = "GET", allUse = "2") + @RequestMapping("/post/ErpDepotController/queryStoreHouseListByCurrentUserId") + public void queryStoreHouseListByCurrentUserId(InputObject inputObject, OutputObject outputObject) { + erpDepotService.queryStoreHouseListByCurrentUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelDao.java new file mode 100644 index 0000000..c817518 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.DepotLevel; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DepotLevelDao + * @Description: 仓库级别数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 22:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotLevelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelValDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelValDao.java new file mode 100644 index 0000000..dd79e21 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotLevelValDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.DepotLevelVal; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName: DepotLevelValDao + * @Description: 仓库级别的值数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 10:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotLevelValDao extends SkyeyeBaseMapper { + + /** + * 根据父id查询所有的子节点信息(包含父id),如果是多个 + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotOutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotOutDao.java new file mode 100644 index 0000000..1e54ef7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotOutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DepotOutDao + * @Description: 仓库出库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotOutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotPutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotPutDao.java new file mode 100644 index 0000000..442a867 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotPutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DepotPutDao + * @Description: 仓库入库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotPutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotStaffDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotStaffDao.java new file mode 100644 index 0000000..0776854 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/DepotStaffDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.DepotStaff; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DepotStaffDao + * @Description: 仓库与员工的关系数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotStaffDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/ErpDepotDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/ErpDepotDao.java new file mode 100644 index 0000000..985079b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/dao/ErpDepotDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.dao; + +import com.skyeye.depot.entity.Depot; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ErpDepotDao + * @Description: 仓库信息数据层 + * @author: skyeye云系列--卫志强 + * @date: 2019/9/14 10:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpDepotDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/Depot.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/Depot.java new file mode 100644 index 0000000..e94caf4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/Depot.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DepotMation + * @Description: 仓库管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/14 9:20 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.ERP_DEPOT_CACHE_KEY) +@TableName(value = "erp_depot", autoResultMap = true) +@ApiModel("仓库管理实体类") +public class Depot extends BaseGeneralInfo { + + @TableField(value = "address") + @ApiModelProperty(value = "仓库地址") + private String address; + + @TableField(value = "warehousing") + @ApiModelProperty(value = "仓储费") + private String warehousing; + + @TableField(value = "truckage") + @ApiModelProperty(value = "搬运费") + private String truckage; + + @TableField(value = "principal", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "负责人id") + private List principal; + + @TableField(exist = false) + @Property(value = "负责人对象") + private List> principalMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(value = "is_default") + @ApiModelProperty(value = "是否默认,参考#IsDefaultEnum", required = "required,num") + private Integer isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevel.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevel.java new file mode 100644 index 0000000..e76bb33 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevel.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: DepotLevel + * @Description: 仓库级别表 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 21:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"depotId", "name"}) +@RedisCacheField(name = "erp:depotLevel") +@TableName(value = "erp_depot_level", autoResultMap = true) +@ApiModel("仓库级别表") +public class DepotLevel extends BaseGeneralInfo { + + @TableField(value = "parent_id") + @ApiModelProperty(value = "父节点id", required = "required", defaultValue = "0") + private String parentId; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevelVal.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevelVal.java new file mode 100644 index 0000000..792dfe0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotLevelVal.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: DepotLevelVal + * @Description: 仓库级别的值表 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 21:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"depotId", "parentId", "number"}) +@TableName(value = "erp_depot_level_val", autoResultMap = true) +@ApiModel("仓库级别的值表") +public class DepotLevelVal extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "number") + @ApiModelProperty(value = "编号", required = "required", fuzzyLike = true) + private String number; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "父节点id", required = "required") + private String parentId; + + @TableField(exist = false) + @Property(value = "父节点信息") + private DepotLevelVal parentMation; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "depot_level_id") + @ApiModelProperty(value = "级别id") + private String depotLevelId; + + @TableField(exist = false) + @Property(value = "级别信息") + private DepotLevel depotLevelMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotOut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotOut.java new file mode 100644 index 0000000..fdd385f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotOut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: DepotOut + * @Description: 仓库出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:depot:out", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("仓库出库单实体类") +public class DepotOut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotPut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotPut.java new file mode 100644 index 0000000..cb30243 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotPut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: DepotPut + * @Description: 仓库入库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:49 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:depot:put", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("仓库入库单实体类") +public class DepotPut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaff.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaff.java new file mode 100644 index 0000000..b2fe7f7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaff.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: DepotStaff + * @Description: 仓库与员工的关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_depot_staff", autoResultMap = true) +@ApiModel("仓库与员工的关系实体类") +public class DepotStaff extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库ID", required = "required") + private String depotId; + + @TableField(value = "staff_id") + @ApiModelProperty(value = "员工ID", required = "required") + private String staffId; + + @TableField(exist = false) + @Property(value = "员工信息") + private Map staffMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaffVO.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaffVO.java new file mode 100644 index 0000000..fde8872 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/entity/DepotStaffVO.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: DepotStaffVO + * @Description: 仓库与员工的关系入参实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("仓库与员工的关系入参实体类") +public class DepotStaffVO implements Serializable { + + @ApiModelProperty(value = "仓库ID", required = "required") + private String depotId; + + @ApiModelProperty(value = "员工ID", required = "required,json") + private List staffId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelService.java new file mode 100644 index 0000000..018b269 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotLevel; + +/** + * @ClassName: DepotLevelService + * @Description: 仓库级别服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotLevelService extends SkyeyeBusinessService { + + void queryDepotLevelByDepotId(InputObject inputObject, OutputObject outputObject); + + DepotLevel queryChildDepotLevelById(String depotId, String id); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelValService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelValService.java new file mode 100644 index 0000000..1afa046 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotLevelValService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotLevelVal; + +import java.util.List; + +/** + * @ClassName: DepotLevelValService + * @Description: 仓库级别的值服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 10:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotLevelValService extends SkyeyeBusinessService { + + List queryDepotLevelValListByParentId(String parentId); + + void deleteDepotLevelValListByDepotLevelId(String... depotLevelId); + + void batchGenerateDepotLevelVal(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotOutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotOutService.java new file mode 100644 index 0000000..40a0019 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotOutService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; + +/** + * @ClassName: DepotOutService + * @Description: 仓库出库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 9:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotOutService extends SkyeyeErpOrderService { + + void queryDepotOutTransById(InputObject inputObject, OutputObject outputObject); + + void insertDepotOutToTurnPut(InputObject inputObject, OutputObject outputObject); + + void insertDepotOutToSealsReturns(InputObject inputObject, OutputObject outputObject); + + void queryNeedConfirmDepotOutList(InputObject inputObject, OutputObject outputObject); + + void queryNeedStoreConfirmDepotOutList(InputObject inputObject, OutputObject outputObject); + + void queryDepotOutTransStoreById(InputObject inputObject, OutputObject outputObject); + + void insertDepotOutToTurnStorePut(InputObject inputObject, OutputObject outputObject); + + void insertDepotOutToStoreSealsReturns(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotPutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotPutService.java new file mode 100644 index 0000000..28ae092 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotPutService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.depot.entity.DepotPut; + +/** + * @ClassName: DepotPutService + * @Description: 仓库入库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotPutService extends SkyeyeErpOrderService { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotStaffService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotStaffService.java new file mode 100644 index 0000000..ffedb20 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/DepotStaffService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotStaff; + +/** + * @ClassName: DepotStaffService + * @Description: 仓库与员工的关系服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepotStaffService extends SkyeyeBusinessService { + + void insertDepotStaff(InputObject inputObject, OutputObject outputObject); + + void queryStaffBelongDepotList(InputObject inputObject, OutputObject outputObject); + + void deleteDepotStaffByStaffId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/ErpDepotService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/ErpDepotService.java new file mode 100644 index 0000000..087b8a3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/ErpDepotService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.Depot; + +import java.util.List; + +/** + * @ClassName: ErpDepotService + * @Description: 仓库管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2019/9/14 10:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpDepotService extends SkyeyeBusinessService { + + void queryAllStoreHouseList(InputObject inputObject, OutputObject outputObject); + + void queryStoreHouseListByCurrentUserId(InputObject inputObject, OutputObject outputObject); + + List queryDepotListByChargePerson(String userId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelServiceImpl.java new file mode 100644 index 0000000..9ce0bde --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelServiceImpl.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.dao.DepotLevelDao; +import com.skyeye.depot.entity.DepotLevel; +import com.skyeye.depot.service.DepotLevelService; +import com.skyeye.depot.service.DepotLevelValService; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DepotLevelServiceImpl + * @Description: 仓库级别服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/5 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库级别管理", groupName = "仓库级别管理") +public class DepotLevelServiceImpl extends SkyeyeBusinessServiceImpl implements DepotLevelService { + + @Autowired + private DepotLevelValService depotLevelValService; + + @Override + public void validatorEntity(DepotLevel entity) { + super.validatorEntity(entity); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevel::getDepotId), entity.getDepotId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevel::getParentId), entity.getParentId()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + long count = count(queryWrapper); + if (count != 0) { + throw new CustomException("该父节点下已存在子节点,一个节点下面只允许有一个子节点"); + } + } + + @Override + public void deletePostpose(DepotLevel entity) { + List depotLevelList = queryDepotLevelListByDepotId(entity.getDepotId()); + if (CollectionUtil.isEmpty(depotLevelList)) { + return; + } + // 将数据转化为树的形式,方便进行父id重新赋值 + List> depotLevelMapList = JSONUtil.toList(JSONUtil.toJsonStr(depotLevelList), null); + depotLevelMapList = ToolUtil.listToTree(depotLevelMapList, "id", "parentId", "children"); + // 删除父节点id不是0的所有节点 + depotLevelMapList = depotLevelMapList.stream().filter(depotLevel -> !StrUtil.equals(CommonNumConstants.NUM_ZERO.toString(), depotLevel.get("parentId").toString())) + .collect(Collectors.toList()); + List ids = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(depotLevelMapList)) { + // 递归找到所有待删除的子节点id + findChildId(depotLevelMapList, ids); + deleteById(ids); + } + ids.add(entity.getId()); + depotLevelValService.deleteDepotLevelValListByDepotLevelId(ids.toArray(new String[]{})); + } + + private void findChildId(List> depotLevelMapList, List ids) { + depotLevelMapList.forEach(depotLevel -> { + ids.add(depotLevel.get("id").toString()); + List> children = (List>) depotLevel.get("children"); + if (CollectionUtil.isNotEmpty(children)) { + findChildId(children, ids); + } + }); + } + + private List queryDepotLevelListByDepotId(String depotId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevel::getDepotId), depotId); + return list(queryWrapper); + } + + @Override + public void queryDepotLevelByDepotId(InputObject inputObject, OutputObject outputObject) { + String depotId = inputObject.getParams().get("depotId").toString(); + List depotLevelList = queryDepotLevelListByDepotId(depotId); + if (CollectionUtil.isEmpty(depotLevelList)) { + return; + } + // 将数据转化为树的形式,方便进行父id重新赋值 + List> depotLevelMapList = JSONUtil.toList(JSONUtil.toJsonStr(depotLevelList), null); + depotLevelMapList = ToolUtil.listToTree(depotLevelMapList, "id", "parentId", "children"); + outputObject.setBeans(depotLevelMapList); + outputObject.settotal(depotLevelMapList.size()); + } + + @Override + public DepotLevel queryChildDepotLevelById(String depotId, String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevel::getDepotId), depotId); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevel::getParentId), id); + return getOne(queryWrapper, false); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelValServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelValServiceImpl.java new file mode 100644 index 0000000..aa77cfc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotLevelValServiceImpl.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.GenerateDepotLevelValType; +import com.skyeye.depot.dao.DepotLevelValDao; +import com.skyeye.depot.entity.DepotLevel; +import com.skyeye.depot.entity.DepotLevelVal; +import com.skyeye.depot.service.DepotLevelService; +import com.skyeye.depot.service.DepotLevelValService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DepotLevelValServiceImpl + * @Description: 仓库级别的值服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 10:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库级别的值管理", groupName = "仓库级别管理") +public class DepotLevelValServiceImpl extends SkyeyeBusinessServiceImpl implements DepotLevelValService { + + @Autowired + private DepotLevelService depotLevelService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + // 仓库 + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevelVal::getDepotId), commonPageInfo.getObjectId()); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + // 级别 + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevelVal::getDepotLevelId), commonPageInfo.getHolderId()); + } else { + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevelVal::getParentId), CommonNumConstants.NUM_ZERO); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + List ids = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return beans; + } + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(ids); + beans = selectMapByIds(childIds).values().stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + beans.forEach(bean -> { + bean.put("lay_is_open", true); + }); + + depotLevelService.setMationForMap(beans, "depotLevelId", "depotLevelMation"); + setMationForMap(beans, "parentId", "parentMation"); + return beans; + } + + @Override + public void validatorEntity(DepotLevelVal entity) { + super.validatorEntity(entity); + DepotLevel depotLevel; + if (!StrUtil.equals(entity.getParentId(), "0")) { + // 查询父级别的值 + DepotLevelVal parentLevelVal = selectById(entity.getParentId()); + // 查询该值对应的级别的子级别 + depotLevel = depotLevelService.queryChildDepotLevelById(entity.getDepotId(), parentLevelVal.getDepotLevelId()); + } else { + depotLevel = depotLevelService.queryChildDepotLevelById(entity.getDepotId(), "0"); + } + if (ObjectUtil.isNull(depotLevel)) { + throw new CustomException("该值对应的级别下没有子级别!"); + } + entity.setDepotLevelId(depotLevel.getId()); + } + + @Override + public void deletePostpose(DepotLevelVal entity) { + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(Arrays.asList(entity.getId())); + deleteById(childIds); + } + + @Override + public List queryDepotLevelValListByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotLevelVal::getParentId), parentId); + return list(queryWrapper); + } + + @Override + public void deleteDepotLevelValListByDepotLevelId(String... depotLevelId) { + List depotLevelIdList = Arrays.asList(depotLevelId); + if (CollectionUtil.isEmpty(depotLevelIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(DepotLevelVal::getDepotLevelId), depotLevelIdList); + remove(queryWrapper); + } + + @Override + public void batchGenerateDepotLevelVal(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + Integer type = Integer.parseInt(params.get("type").toString()); + Integer number = Integer.parseInt(params.get("number").toString()); + String parentId = params.get("parentId").toString(); + String depotId = params.get("depotId").toString(); + if (number <= 0) { + throw new CustomException("生成数量必须大于0!"); + } + + DepotLevel depotLevel; + if (!StrUtil.equals(parentId, "0")) { + // 查询父级别的值 + DepotLevelVal parentLevelVal = selectById(parentId); + // 查询该值对应的级别的子级别 + depotLevel = depotLevelService.queryChildDepotLevelById(depotId, parentLevelVal.getDepotLevelId()); + } else { + depotLevel = depotLevelService.queryChildDepotLevelById(depotId, "0"); + } + if (ObjectUtil.isNull(depotLevel)) { + throw new CustomException("该值对应的级别下没有子级别!"); + } + // 查询当前级别的值下的所有子级别的值 + List depotLevelValList = queryDepotLevelValListByParentId(parentId); + List numberList = depotLevelValList.stream().map(DepotLevelVal::getNumber).collect(Collectors.toList()); + + List saveDataList = new ArrayList<>(); + if (type == GenerateDepotLevelValType.NUMBER.getKey()) { + // 生成数字 + int start = 1; + while (saveDataList.size() < number) { + if (!numberList.contains(String.valueOf(start))) { + DepotLevelVal depotLevelVal = new DepotLevelVal(); + depotLevelVal.setParentId(parentId); + depotLevelVal.setDepotLevelId(depotLevel.getId()); + depotLevelVal.setDepotId(depotId); + depotLevelVal.setNumber(String.valueOf(start)); + saveDataList.add(depotLevelVal); + } + start++; + } + } else if (type == GenerateDepotLevelValType.LETTER.getKey()) { + // 生成字母 + int start = 1; + while (saveDataList.size() < number) { + String code = convertToTitle(start); + if (!numberList.contains(code)) { + DepotLevelVal depotLevelVal = new DepotLevelVal(); + depotLevelVal.setParentId(parentId); + depotLevelVal.setDepotLevelId(depotLevel.getId()); + depotLevelVal.setDepotId(depotId); + depotLevelVal.setNumber(code); + saveDataList.add(depotLevelVal); + } + start++; + } + } + if (CollectionUtil.isNotEmpty(saveDataList)) { + String userId = inputObject.getLogParams().get("id").toString(); + createEntity(saveDataList, userId); + } + } + + /** + * 给一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称。 + * 例如,columnNumber 为 1 ,返回 "A" ,columnNumber 为 27 ,返回 "AA" 。 + * 这个方法主要用于生成 Excel 表头。 + * + * @param columnNumber + * @return + */ + public String convertToTitle(int columnNumber) { + StringBuffer sb = new StringBuffer(); + while (columnNumber != 0) { + columnNumber--; + sb.append((char) (columnNumber % 26 + 'A')); + columnNumber /= 26; + } + return sb.reverse().toString(); + } + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotOutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotOutServiceImpl.java new file mode 100644 index 0000000..3f549fd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotOutServiceImpl.java @@ -0,0 +1,725 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutOtherState; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.dao.DepotOutDao; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderCommon; +import com.skyeye.entity.ErpOrderHead; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.holder.classenum.HolderNormsChildState; +import com.skyeye.holder.service.HolderNormsChildService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.other.service.OtherOutLetsService; +import com.skyeye.other.service.impl.OtherOutLetsServiceImpl; +import com.skyeye.otherwise.service.OtherWiseOrderService; +import com.skyeye.pick.service.PatchOutLetService; +import com.skyeye.pick.service.RequisitionOutLetService; +import com.skyeye.pick.service.impl.PatchOutLetServiceImpl; +import com.skyeye.pick.service.impl.RequisitionOutLetServiceImpl; +import com.skyeye.pickconfirm.classenum.ConfirmFromType; +import com.skyeye.pickconfirm.entity.ConfirmPut; +import com.skyeye.pickconfirm.entity.ConfirmReturn; +import com.skyeye.pickconfirm.service.ConfirmPutService; +import com.skyeye.pickconfirm.service.ConfirmReturnService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.purchase.service.impl.PurchaseReturnsServiceImpl; +import com.skyeye.rest.sealservice.rest.IServiceApplyRest; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.retail.service.RetailOutLetService; +import com.skyeye.retail.service.impl.RetailOutLetServiceImpl; +import com.skyeye.seal.service.SalesOutLetService; +import com.skyeye.seal.service.impl.SalesOutLetServiceImpl; +import com.skyeye.shop.classenum.ShopConfirmFromType; +import com.skyeye.shop.entity.ShopConfirmPut; +import com.skyeye.shop.entity.ShopConfirmReturn; +import com.skyeye.shop.service.ShopConfirmPutService; +import com.skyeye.shop.service.ShopConfirmReturnService; +import com.skyeye.shop.service.ShopOutLetsService; +import com.skyeye.shop.service.impl.ShopOutLetsServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: DepotOutServiceImpl + * @Description: 仓库出库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 9:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库出库单", groupName = "仓库出入库", flowable = true) +public class DepotOutServiceImpl extends SkyeyeErpOrderServiceImpl implements DepotOutService { + + // 采购退货单,销售出库单,零售出库单,其他出库单,领料出库单,补料出库单,配件申领单,门店申领单 + private static final List OUT_ORDER_TYPE = Arrays.asList(PurchaseReturnsServiceImpl.class.getName(), SalesOutLetServiceImpl.class.getName(), + RetailOutLetServiceImpl.class.getName(), OtherOutLetsServiceImpl.class.getName(), RequisitionOutLetServiceImpl.class.getName(), + PatchOutLetServiceImpl.class.getName(), DepotOutFromType.SEAL_APPLY.getIdKey(), ShopOutLetsServiceImpl.class.getName()); + + @Autowired + private HolderNormsChildService holderNormsChildService; + + @Autowired + private ConfirmPutService confirmPutService; + + @Autowired + private ConfirmReturnService confirmReturnService; + + @Autowired + private ShopConfirmPutService shopConfirmPutService; + + @Autowired + private ShopConfirmReturnService shopConfirmReturnService; + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + @Autowired + private SalesOutLetService salesOutLetService; + + @Autowired + private RetailOutLetService retailOutLetService; + + @Autowired + private OtherOutLetsService otherOutLetsService; + + @Autowired + private RequisitionOutLetService requisitionOutLetService; + + @Autowired + private PatchOutLetService patchOutLetService; + + @Autowired + private FarmService farmService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IServiceApplyRest iServiceApplyRest; + + @Autowired + private OtherWiseOrderService otherWiseOrderService; + + @Autowired + private ShopOutLetsService shopOutLetsService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + if (StrUtil.isEmpty(commonPageInfo.getType())) { + throw new CustomException("type不能为空"); + } + QueryWrapper queryWrapper; + if (StrUtil.equals(commonPageInfo.getType(), "AllWait")) { + // 所有待出库的单据信息 + queryWrapper = super.getGrandFatherQueryWrapper(commonPageInfo); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), OUT_ORDER_TYPE); + List otherStateList = Arrays.asList(DepotOutState.NEED_OUT.getKey(), DepotOutState.PARTIAL_OUT.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), otherStateList); + // 只查询审批通过,部分完成,已完成的 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getState), stateList); + } else if (StrUtil.equals(commonPageInfo.getType(), "AllComplate")) { + // 所有已出库的单据信息 + queryWrapper = super.getGrandFatherQueryWrapper(commonPageInfo); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), OUT_ORDER_TYPE); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), DepotOutState.COMPLATE_OUT.getKey()); + } else { + // 查询仓库出库单 + queryWrapper = super.getQueryWrapper(commonPageInfo); + } + return queryWrapper; + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (!StrUtil.equals(commonPageInfo.getType(), "AllWait") && !StrUtil.equals(commonPageInfo.getType(), "AllComplate")) { + // 查询仓库出库单 + // 采购退货单 + purchaseReturnsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 销售出库单 + salesOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 零售出库单 + retailOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 其他出库单 + otherOutLetsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 领料出库单 + requisitionOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 补料出库单 + patchOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 配件申领单 + otherWiseOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 门店申领单 + shopOutLetsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + } + return beans; + } + + @Override + public void validatorEntity(DepotOut entity) { + String fromTypeIdKey; + if (StrUtil.isNotEmpty(entity.getId())) { + DepotOut depotOut = selectById(entity.getId()); + fromTypeIdKey = DepotOutFromType.getItemIdKey(depotOut.getFromTypeId()); + } else { + fromTypeIdKey = DepotOutFromType.getItemIdKey(entity.getFromTypeId()); + } + checkMaterialNorms(entity, fromTypeIdKey, false); + checkNormsCodeAndOutbound(entity, true); + if (StrUtil.equals(fromTypeIdKey, DepotOutFromType.REQUISITION_OUTLET.getIdKey()) + || StrUtil.equals(fromTypeIdKey, DepotOutFromType.PATCH_OUTLET.getIdKey()) + || StrUtil.equals(fromTypeIdKey, DepotOutFromType.SHOP_OUTLET.getIdKey())) { + // 领料出库单/补料出库单/门店申领单 + entity.setOtherState(DepotOutOtherState.NEED_CONFIRM.getKey()); + } + } + + @Override + public void createPrepose(DepotOut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void updatePrepose(DepotOut entity) { + super.updatePrepose(entity); + // 查询数据库里的值 + DepotOut oldDepotOut = selectById(entity.getId()); + if (oldDepotOut.getFromTypeId() == DepotOutFromType.REQUISITION_OUTLET.getKey() + || oldDepotOut.getFromTypeId() == DepotOutFromType.PATCH_OUTLET.getKey()) { + // 领料出库单/补料出库单 + entity.setFarmId(oldDepotOut.getFarmId()); + entity.setDepartmentId(oldDepotOut.getDepartmentId()); + entity.setSalesman(oldDepotOut.getSalesman()); + } else if (oldDepotOut.getFromTypeId() == DepotOutFromType.SHOP_OUTLET.getKey()) { + // 门店申领单 + entity.setStoreId(oldDepotOut.getStoreId()); + entity.setSalesman(oldDepotOut.getSalesman()); + } + } + + @Override + public void writeChild(DepotOut entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public DepotOut getDataFromDb(String id) { + DepotOut depotOut = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(depotOut); + return depotOut; + } + + @Override + public DepotOut selectById(String id) { + DepotOut depotOut = super.selectById(id); + if (depotOut.getFromTypeId() == DepotOutFromType.PURCHASE_RETURNS.getKey()) { + // 采购退货单 + purchaseReturnsService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.SEAL_OUTLET.getKey()) { + // 销售出库单 + salesOutLetService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.RETAIL_OUTLET.getKey()) { + // 零售出库单 + retailOutLetService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.OTHER_OUTLET.getKey()) { + // 其他出库单 + otherOutLetsService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.REQUISITION_OUTLET.getKey()) { + // 领料出库单 + requisitionOutLetService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.PATCH_OUTLET.getKey()) { + // 补料出库单 + patchOutLetService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.SEAL_APPLY.getKey()) { + // 配件申领单 + otherWiseOrderService.setDataMation(depotOut, DepotOut::getFromId); + } else if (depotOut.getFromTypeId() == DepotOutFromType.SHOP_OUTLET.getKey()) { + // 门店申领单 + shopOutLetsService.setDataMation(depotOut, DepotOut::getFromId); + } + return depotOut; + } + + @Override + public void approvalEndIsSuccess(DepotOut entity) { + entity = selectById(entity.getId()); + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + String fromTypeIdKey = DepotOutFromType.getItemIdKey(entity.getFromTypeId()); + // 修改来源单据信息 + boolean result = checkMaterialNorms(entity, fromTypeIdKey, true); + // 需要出库 + // 校验并修改条形码信息 + List normsCodeList = checkNormsCodeAndOutbound(entity, false); + if (entity.getFromTypeId() == DepotOutFromType.PURCHASE_RETURNS.getKey()) { + // 修改采购退货的商品状态为退货状态 + holderNormsChildService.editHolderNormsChildState(entity.getHolderId(), normsCodeList, HolderNormsChildState.RETURN_OF_GOODS.getKey()); + } else if (entity.getFromTypeId() == DepotOutFromType.SEAL_APPLY.getKey()) { + // 配件申领单 + updateSealApply(entity, normsCodeList, result); + } + // 修改库存信息以及记录客户/供应商/会员关联的商品 + super.depotOutOrPutSuccess(entity.getHolderId(), entity.getHolderKey(), entity.getErpOrderItemList(), DepotPutOutType.OUT.getKey(), + entity.getFromId(), fromTypeIdKey); + } + + private void updateSealApply(DepotOut entity, List normsCodeList, boolean result) { + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, normsCodeList); + Map> listMap = materialNormsCodeList.stream() + .collect(Collectors.groupingBy(MaterialNormsCode::getNormsId)); + Map outNumMap = new HashMap<>(); + List> applyLinkList = new ArrayList<>(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + String normsId = erpOrderItem.getNormsId(); + Map applyLink = BeanUtil.beanToMap(erpOrderItem); + List list = listMap.get(normsId).stream() + .map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + applyLink.put("normsCodeList", list); + applyLinkList.add(applyLink); + } + outNumMap.put("id", entity.getFromId()); + outNumMap.put("createId", entity.getCreateId()); + outNumMap.put("applyLinkList", applyLinkList); + ExecuteFeignClient.get(() -> iServiceApplyRest.editSealApplyOutNum(outNumMap)); + + // 修改配件申领单出库状态 + Map outStateMap = new HashMap<>(); + outStateMap.put("id", entity.getFromId()); + if (result) { + outStateMap.put("otherState", DepotOutState.COMPLATE_OUT.getKey()); + } else { + outStateMap.put("otherState", DepotOutState.PARTIAL_OUT.getKey()); + } + ExecuteFeignClient.get(() -> iServiceApplyRest.editSealApplyOtherState(outStateMap)); + } + + private boolean checkMaterialNorms(DepotOut entity, String fromTypeIdKey, boolean setData) { + // 获取来源单据信息 + SkyeyeErpOrderService skyeyeErpOrderService = null; + ErpOrderHead fromMation; + if (entity.getFromTypeId() == DepotOutFromType.SEAL_APPLY.getKey()) { + // 配件申领单 + fromMation = otherWiseOrderService.selectById(entity.getFromId()); + } else { + try { + Class clazz = Class.forName(fromTypeIdKey); + skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + fromMation = (ErpOrderHead) skyeyeErpOrderService.selectById(entity.getFromId()); + } + // 当前出库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达出库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + super.checkFromOrderMaterialNorms(fromMation.getErpOrderItemList(), inSqlNormsId); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经出库的商品数量 + super.setOrCheckOperNumber(fromMation.getErpOrderItemList(), setData, orderNormsNum, executeNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = fromMation.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 该来源单据的商品数量已经全部出库 + if (entity.getFromTypeId() == DepotOutFromType.SEAL_APPLY.getKey()) { + // 配件申领单 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + otherWiseOrderService.editOtherState(entity.getFromId(), DepotOutState.COMPLATE_OUT.getKey()); + return true; + } else { + otherWiseOrderService.editOtherState(entity.getFromId(), DepotOutState.PARTIAL_OUT.getKey()); + } + } else { + if (CollectionUtil.isEmpty(erpOrderItemList)) { + skyeyeErpOrderService.editOtherState(entity.getFromId(), DepotOutState.COMPLATE_OUT.getKey()); + return true; + } else { + skyeyeErpOrderService.editOtherState(entity.getFromId(), DepotOutState.PARTIAL_OUT.getKey()); + } + } + } + return false; + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 出库 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndOutbound(DepotOut entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行出库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/未入库/已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 判断条形码是否就在出库仓库里面 + Map materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + MaterialNormsCode materialNormsCode = materialNormsCodeMap.get(normsCode); + if (!StrUtil.equals(materialNormsCode.getDepotId(), erpOrderItem.getDepotId())) { + throw new CustomException( + String.format(Locale.ROOT, "条形码【%s】不在指定出库仓库,请确认", normsCode)); + } + if (!StrUtil.equals(materialNormsCode.getNormsId(), erpOrderItem.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + String outboundTime = DateUtil.getTimeAndToString(); + String serviceClassName = getServiceClassName(); + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setInDepot(MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCode.setOutboundTime(outboundTime); + materialNormsCode.setToObjectId(entity.getId()); + materialNormsCode.setToObjectKey(serviceClassName); + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + return allNormsCodeList; + } + + @Override + public void queryNeedConfirmDepotOutList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + // 只查询来源类型是领料出库单/补料出库单 + List fromTypeIdList = Arrays.asList(new Integer[]{DepotOutFromType.REQUISITION_OUTLET.getKey(), DepotOutFromType.PATCH_OUTLET.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getFromTypeId), fromTypeIdList); + // 只查询审批通过的单据 + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getState), FlowableStateEnum.PASS.getKey()); + if (StrUtil.equals(commonPageInfo.getType(), "waitConfirm")) { + // 所有待确认的单据信息 + List otherStateList = Arrays.asList(new Integer[]{DepotOutOtherState.NEED_CONFIRM.getKey(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), otherStateList); + } else if (StrUtil.equals(commonPageInfo.getType(), "confirm")) { + // 所有已确认的单据信息 + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } + List list = list(queryWrapper); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list), null); + // 领料出库单 + requisitionOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 补料出库单 + patchOutLetService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 车间 + farmService.setMationForMap(beans, "farmId", "farmMation"); + // 部门 + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void queryDepotOutTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + DepotOut depotOut = selectById(id); + // 车间 + farmService.setDataMation(depotOut, DepotOut::getFarmId); + // 部门 + iDepmentService.setDataMation(depotOut, DepotOut::getDepartmentId); + // 获取物料接收单的数量 + Map normsNum = confirmPutService.calcMaterialNormsNumByFromId(id); + // 获取物料退货单的数量 + Map normsReturnsNum = confirmReturnService.calcMaterialNormsNumByFromId(id); + // 设置未下达物料接收单/物料退货单的商品数量-----订单数量 - 物料接收单的数量 - 物料退货单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), true, normsNum, normsReturnsNum); + + // 获取物料接收单的商品编码 + Map> putCode = confirmPutService.calcMaterialNormsCodeByFromId(id); + // 获取物料退货单的商品编码 + Map> returnCode = confirmReturnService.calcMaterialNormsCodeByFromId(id); + // 减去物料接收单/物料退货单的商品编码 + for (ErpOrderItem erpOrderItem : depotOut.getErpOrderItemList()) { + List putCodeList = putCode.get(erpOrderItem.getNormsId()); + List returnCodeList = returnCode.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isEmpty(putCodeList) && CollectionUtil.isEmpty(returnCodeList)) { + continue; + } + // 求差集 + List codeList = erpOrderItem.getNormsCodeList(); + if (CollectionUtil.isNotEmpty(putCodeList)) { + codeList = codeList.stream() + .filter(num -> !putCodeList.contains(num)).collect(Collectors.toList()); + } + if (CollectionUtil.isNotEmpty(returnCodeList)) { + codeList = codeList.stream() + .filter(num -> !returnCodeList.contains(num)).collect(Collectors.toList()); + } + erpOrderItem.setNormsCode(Joiner.on("\n").join(codeList)); + erpOrderItem.setNormsCodeList(codeList); + } + + // 过滤掉数量为0的商品 + depotOut.setErpOrderItemList(depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(depotOut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertDepotOutToTurnPut(InputObject inputObject, OutputObject outputObject) { + ConfirmPut confirmPut = inputObject.getParams(ConfirmPut.class); + DepotOut depotOut = selectById(confirmPut.getId()); + if (ObjectUtil.isEmpty(depotOut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转 + if (FlowableStateEnum.PASS.getKey().equals(depotOut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + confirmPut.setFromId(confirmPut.getId()); + confirmPut.setFromTypeId(ConfirmFromType.DEPOT_OUT.getKey()); + confirmPut.setDepartmentId(depotOut.getDepartmentId()); + confirmPut.setFarmId(depotOut.getFarmId()); + confirmPut.setSalesman(depotOut.getSalesman()); + confirmPut.setId(StrUtil.EMPTY); + confirmPutService.createEntity(confirmPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转物料接收单."); + } + } + + @Override + public void insertDepotOutToSealsReturns(InputObject inputObject, OutputObject outputObject) { + ConfirmReturn confirmReturn = inputObject.getParams(ConfirmReturn.class); + DepotOut depotOut = selectById(confirmReturn.getId()); + if (ObjectUtil.isEmpty(depotOut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转 + if (FlowableStateEnum.PASS.getKey().equals(depotOut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + confirmReturn.setFromId(confirmReturn.getId()); + confirmReturn.setFromTypeId(ConfirmFromType.DEPOT_OUT.getKey()); + confirmReturn.setDepartmentId(depotOut.getDepartmentId()); + confirmReturn.setFarmId(depotOut.getFarmId()); + confirmReturn.setSalesman(depotOut.getSalesman()); + confirmReturn.setId(StrUtil.EMPTY); + confirmReturnService.createEntity(confirmReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转物料退货单."); + } + } + + @Override + public void queryNeedStoreConfirmDepotOutList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + // 只查询来源类型是门店申领单 + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getFromTypeId), DepotOutFromType.SHOP_OUTLET.getKey()); + // 只查询审批通过的单据 + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getState), FlowableStateEnum.PASS.getKey()); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + commonPageInfo.setObjectId("-"); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getStoreId), commonPageInfo.getObjectId()); + if (StrUtil.equals(commonPageInfo.getType(), "waitConfirm")) { + // 所有待确认的单据信息 + List otherStateList = Arrays.asList(new Integer[]{DepotOutOtherState.NEED_CONFIRM.getKey(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), otherStateList); + } else if (StrUtil.equals(commonPageInfo.getType(), "confirm")) { + // 所有已确认的单据信息 + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } + List list = list(queryWrapper); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list), null); + // 门店申领单 + shopOutLetsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 门店 + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void queryDepotOutTransStoreById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + DepotOut depotOut = selectById(id); + // 门店 + iShopStoreService.setDataMation(depotOut, DepotOut::getStoreId); + // 获取物料接收单的数量 + Map normsNum = shopConfirmPutService.calcMaterialNormsNumByFromId(id); + // 获取物料退货单的数量 + Map normsReturnsNum = shopConfirmReturnService.calcMaterialNormsNumByFromId(id); + // 设置未下达物料接收单/物料退货单的商品数量-----订单数量 - 物料接收单的数量 - 物料退货单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), true, normsNum, normsReturnsNum); + + // 获取物料接收单的商品编码 + Map> putCode = shopConfirmPutService.calcMaterialNormsCodeByFromId(id); + // 获取物料退货单的商品编码 + Map> returnCode = shopConfirmReturnService.calcMaterialNormsCodeByFromId(id); + // 减去物料接收单/物料退货单的商品编码 + for (ErpOrderItem erpOrderItem : depotOut.getErpOrderItemList()) { + List putCodeList = putCode.get(erpOrderItem.getNormsId()); + List returnCodeList = returnCode.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isEmpty(putCodeList) && CollectionUtil.isEmpty(returnCodeList)) { + continue; + } + // 求差集 + List codeList = erpOrderItem.getNormsCodeList(); + if (CollectionUtil.isNotEmpty(putCodeList)) { + codeList = codeList.stream() + .filter(num -> !putCodeList.contains(num)).collect(Collectors.toList()); + } + if (CollectionUtil.isNotEmpty(returnCodeList)) { + codeList = codeList.stream() + .filter(num -> !returnCodeList.contains(num)).collect(Collectors.toList()); + } + erpOrderItem.setNormsCode(Joiner.on("\n").join(codeList)); + erpOrderItem.setNormsCodeList(codeList); + } + + // 过滤掉数量为0的商品 + depotOut.setErpOrderItemList(depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(depotOut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertDepotOutToTurnStorePut(InputObject inputObject, OutputObject outputObject) { + ShopConfirmPut shopConfirmPut = inputObject.getParams(ShopConfirmPut.class); + DepotOut depotOut = selectById(shopConfirmPut.getId()); + if (ObjectUtil.isEmpty(depotOut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转 + if (FlowableStateEnum.PASS.getKey().equals(depotOut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + shopConfirmPut.setFromId(shopConfirmPut.getId()); + shopConfirmPut.setFromTypeId(ShopConfirmFromType.DEPOT_OUT.getKey()); + shopConfirmPut.setDepartmentId(depotOut.getDepartmentId()); + shopConfirmPut.setFarmId(depotOut.getFarmId()); + shopConfirmPut.setSalesman(depotOut.getSalesman()); + shopConfirmPut.setId(StrUtil.EMPTY); + shopConfirmPutService.createEntity(shopConfirmPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转物料接收单."); + } + } + + @Override + public void insertDepotOutToStoreSealsReturns(InputObject inputObject, OutputObject outputObject) { + ShopConfirmReturn shopConfirmReturn = inputObject.getParams(ShopConfirmReturn.class); + DepotOut depotOut = selectById(shopConfirmReturn.getId()); + if (ObjectUtil.isEmpty(depotOut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转 + if (FlowableStateEnum.PASS.getKey().equals(depotOut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + shopConfirmReturn.setFromId(shopConfirmReturn.getId()); + shopConfirmReturn.setFromTypeId(ConfirmFromType.DEPOT_OUT.getKey()); + shopConfirmReturn.setDepartmentId(depotOut.getDepartmentId()); + shopConfirmReturn.setFarmId(depotOut.getFarmId()); + shopConfirmReturn.setSalesman(depotOut.getSalesman()); + shopConfirmReturn.setId(StrUtil.EMPTY); + shopConfirmReturnService.createEntity(shopConfirmReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转物料退货单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotPutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotPutServiceImpl.java new file mode 100644 index 0000000..941a8ae --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotPutServiceImpl.java @@ -0,0 +1,390 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.dao.DepotPutDao; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderCommon; +import com.skyeye.entity.ErpOrderHead; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.holder.classenum.HolderNormsChildState; +import com.skyeye.holder.service.HolderNormsChildService; +import com.skyeye.machin.service.MachinPutService; +import com.skyeye.machin.service.impl.MachinPutServiceImpl; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.classenum.MaterialNormsCodeType; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.other.service.OtherWareHousService; +import com.skyeye.other.service.impl.OtherWareHousServiceImpl; +import com.skyeye.pick.service.ReturnPutService; +import com.skyeye.pick.service.impl.ReturnPutServiceImpl; +import com.skyeye.pickconfirm.service.ConfirmReturnService; +import com.skyeye.pickconfirm.service.impl.ConfirmReturnServiceImpl; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.impl.PurchasePutServiceImpl; +import com.skyeye.retail.service.RetailReturnsService; +import com.skyeye.retail.service.impl.RetailReturnsServiceImpl; +import com.skyeye.seal.service.SalesReturnsService; +import com.skyeye.seal.service.impl.SalesReturnsServiceImpl; +import com.skyeye.shop.service.ShopConfirmReturnService; +import com.skyeye.shop.service.ShopReturnsService; +import com.skyeye.shop.service.impl.ShopConfirmReturnServiceImpl; +import com.skyeye.shop.service.impl.ShopReturnsServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: DepotPutServiceImpl + * @Description: 仓库入库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 8:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库入库单", groupName = "仓库出入库", flowable = true) +public class DepotPutServiceImpl extends SkyeyeErpOrderServiceImpl implements DepotPutService { + + // 采购入库单,销售退货单,零售退货单,其他入库单,退料入库单,物料退货单,加工入库单,门店退货单,门店物料退货单 + private static final List PUT_ORDER_TYPE = Arrays.asList(PurchasePutServiceImpl.class.getName(), SalesReturnsServiceImpl.class.getName(), + RetailReturnsServiceImpl.class.getName(), OtherWareHousServiceImpl.class.getName(), ReturnPutServiceImpl.class.getName(), + ConfirmReturnServiceImpl.class.getName(), MachinPutServiceImpl.class.getName(), ShopReturnsServiceImpl.class.getName(), + ShopConfirmReturnServiceImpl.class.getName()); + + @Autowired + private HolderNormsChildService holderNormsChildService; + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private SalesReturnsService salesReturnsService; + + @Autowired + private RetailReturnsService retailReturnsService; + + @Autowired + private OtherWareHousService otherWareHousService; + + @Autowired + private ReturnPutService returnPutService; + + @Autowired + private ConfirmReturnService confirmReturnService; + + @Autowired + private MachinPutService machinPutService; + + @Autowired + private ShopReturnsService shopReturnsService; + + @Autowired + private ShopConfirmReturnService shopConfirmReturnService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + if (StrUtil.isEmpty(commonPageInfo.getType())) { + throw new CustomException("type不能为空"); + } + QueryWrapper queryWrapper; + if (StrUtil.equals(commonPageInfo.getType(), "AllWait")) { + // 所有待入库的单据信息 + queryWrapper = super.getGrandFatherQueryWrapper(commonPageInfo); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), PUT_ORDER_TYPE); + List otherStateList = Arrays.asList(DepotPutState.NEED_PUT.getKey(), DepotPutState.PARTIAL_PUT.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), otherStateList); + // 只查询审批通过,部分完成,已完成的 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getState), stateList); + } else if (StrUtil.equals(commonPageInfo.getType(), "AllComplate")) { + // 所有已入库的单据信息 + queryWrapper = super.getGrandFatherQueryWrapper(commonPageInfo); + queryWrapper.in(MybatisPlusUtil.toColumns(ErpOrderCommon::getIdKey), PUT_ORDER_TYPE); + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderCommon::getOtherState), DepotPutState.COMPLATE_PUT.getKey()); + } else { + // 查询仓库入库单 + queryWrapper = super.getQueryWrapper(commonPageInfo); + } + return queryWrapper; + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (!StrUtil.equals(commonPageInfo.getType(), "AllWait") && !StrUtil.equals(commonPageInfo.getType(), "AllComplate")) { + // 查询仓库入库单 + // 采购入库单 + purchasePutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 销售退货单 + salesReturnsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 零售退货单 + retailReturnsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 其他入库单 + otherWareHousService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 退料入库单 + returnPutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 物料退货单 + confirmReturnService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 加工入库单 + machinPutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 门店退货单 + shopReturnsService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 门店物料退货单 + shopConfirmReturnService.setOrderMationByFromId(beans, "fromId", "fromMation"); + } + return beans; + } + + @Override + public void validatorEntity(DepotPut entity) { + String fromTypeIdKey; + if (StrUtil.isNotEmpty(entity.getId())) { + DepotPut depotPut = selectById(entity.getId()); + fromTypeIdKey = DepotPutFromType.getItemIdKey(depotPut.getFromTypeId()); + } else { + fromTypeIdKey = DepotPutFromType.getItemIdKey(entity.getFromTypeId()); + } + checkMaterialNorms(entity, fromTypeIdKey, false); + checkNormsCodeAndWarehousing(entity, true); + } + + @Override + public void createPrepose(DepotPut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void updatePrepose(DepotPut entity) { + super.updatePrepose(entity); + // 查询数据库里的值 + DepotPut oldDepotPut = selectById(entity.getId()); + if (oldDepotPut.getFromTypeId() == DepotPutFromType.CONFIRM_RETURN.getKey()) { + // 物料退货单 + entity.setFarmId(oldDepotPut.getFarmId()); + entity.setDepartmentId(oldDepotPut.getDepartmentId()); + entity.setSalesman(oldDepotPut.getSalesman()); + } else if (oldDepotPut.getFromTypeId() == DepotPutFromType.SHOP_RETURNS.getKey() + || oldDepotPut.getFromTypeId() == DepotPutFromType.SHOP_CONFIRM_RETURNS.getKey()) { + // 门店退货单/门店物料退货单 + entity.setStoreId(oldDepotPut.getStoreId()); + } + } + + @Override + public void writeChild(DepotPut entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public DepotPut getDataFromDb(String id) { + DepotPut depotPut = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(depotPut); + return depotPut; + } + + @Override + public DepotPut selectById(String id) { + DepotPut depotPut = super.selectById(id); + if (depotPut.getFromTypeId() == DepotPutFromType.PURCHASE_PUT.getKey()) { + // 采购入库单 + purchasePutService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.SEAL_RETURNS.getKey()) { + // 销售退货单 + salesReturnsService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.RETAIL_RETURNS.getKey()) { + // 零售退货单 + retailReturnsService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.OTHER_WARE_HOUS.getKey()) { + // 其他入库单 + otherWareHousService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.RETURN_PUT.getKey()) { + // 退料入库单 + returnPutService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.CONFIRM_RETURN.getKey()) { + // 物料退货单 + confirmReturnService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.MACHIN_PUT.getKey()) { + // 加工入库单 + machinPutService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.SHOP_RETURNS.getKey()) { + // 门店退货单 + shopReturnsService.setDataMation(depotPut, DepotPut::getFromId); + } else if (depotPut.getFromTypeId() == DepotPutFromType.SHOP_CONFIRM_RETURNS.getKey()) { + // 门店物料退货单 + shopConfirmReturnService.setDataMation(depotPut, DepotPut::getFromId); + } + return depotPut; + } + + @Override + public void approvalEndIsSuccess(DepotPut entity) { + entity = selectById(entity.getId()); + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + String fromTypeIdKey = DepotPutFromType.getItemIdKey(entity.getFromTypeId()); + // 修改来源单据信息 + checkMaterialNorms(entity, fromTypeIdKey, true); + // 需要入库 + // 校验并修改条形码信息 + List normsCodeList = checkNormsCodeAndWarehousing(entity, false); + if (entity.getFromTypeId() == DepotPutFromType.SEAL_RETURNS.getKey() + || entity.getFromTypeId() == DepotPutFromType.RETAIL_RETURNS.getKey()) { + // 修改销售退货/零售退货单据的商品状态为退货状态 + holderNormsChildService.editHolderNormsChildState(entity.getHolderId(), normsCodeList, HolderNormsChildState.RETURN_OF_GOODS.getKey()); + } + // 修改库存信息以及记录客户/供应商/会员关联的商品 + super.depotOutOrPutSuccess(entity.getHolderId(), entity.getHolderKey(), entity.getErpOrderItemList(), DepotPutOutType.PUT.getKey(), + entity.getFromId(), fromTypeIdKey); + } + + private void checkMaterialNorms(DepotPut entity, String fromTypeIdKey, boolean setData) { + // 获取来源单据信息 + SkyeyeErpOrderService skyeyeErpOrderService; + try { + Class clazz = Class.forName(fromTypeIdKey); + skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + ErpOrderHead fromMation = (ErpOrderHead) skyeyeErpOrderService.selectById(entity.getFromId()); + // 当前入库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达入库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + super.checkFromOrderMaterialNorms(fromMation.getErpOrderItemList(), inSqlNormsId); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 + super.setOrCheckOperNumber(fromMation.getErpOrderItemList(), setData, orderNormsNum, executeNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = fromMation.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 该来源单据的商品数量已经全部入库 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + skyeyeErpOrderService.editOtherState(entity.getFromId(), DepotPutState.COMPLATE_PUT.getKey()); + } else { + skyeyeErpOrderService.editOtherState(entity.getFromId(), DepotPutState.PARTIAL_PUT.getKey()); + } + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 入库 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndWarehousing(DepotPut entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询未入库/已经出库的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey(), MaterialNormsCodeInDepot.OUTBOUND.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或已被使用,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 判断条形码是否符合规范 + Map materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + MaterialNormsCode materialNormsCode = materialNormsCodeMap.get(normsCode); + if (!StrUtil.equals(materialNormsCode.getNormsId(), erpOrderItem.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + Map erpOrderItemMap = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(bean -> String.format("%s-%s", bean.getMaterialId(), bean.getNormsId()), bean -> bean)); + String warehousingTime = DateUtil.getTimeAndToString(); + String serviceClassName = getServiceClassName(); + materialNormsCodeList.forEach(materialNormsCode -> { + String key = String.format("%s-%s", materialNormsCode.getMaterialId(), materialNormsCode.getNormsId()); + ErpOrderItem erpOrderItem = erpOrderItemMap.get(key); + materialNormsCode.setInDepot(MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + materialNormsCode.setDepotId(erpOrderItem.getDepotId()); + materialNormsCode.setWarehousingTime(warehousingTime); + materialNormsCode.setFromObjectId(entity.getId()); + materialNormsCode.setFromObjectKey(serviceClassName); + materialNormsCode.setType(MaterialNormsCodeType.AUTHENTIC.getKey()); + if (DepotPutFromType.SEAL_RETURNS.getKey() == entity.getFromTypeId() + || DepotPutFromType.RETAIL_RETURNS.getKey() == entity.getFromTypeId()) { + // 来源单据类型是零售退货/销售退货,则将商品规格类型修改为二手商品 + materialNormsCode.setType(MaterialNormsCodeType.SECOND_HAND_GOODS.getKey()); + } + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + return allNormsCodeList; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotStaffServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotStaffServiceImpl.java new file mode 100644 index 0000000..60e94ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/DepotStaffServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.dao.DepotStaffDao; +import com.skyeye.depot.entity.Depot; +import com.skyeye.depot.entity.DepotStaff; +import com.skyeye.depot.entity.DepotStaffVO; +import com.skyeye.depot.service.DepotStaffService; +import com.skyeye.depot.service.ErpDepotService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: DepotStaffServiceImpl + * @Description: 仓库与员工的关系服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库与员工的关系管理", groupName = "仓库与员工的关系管理", manageShow = false) +public class DepotStaffServiceImpl extends SkyeyeBusinessServiceImpl implements DepotStaffService { + + @Autowired + private ErpDepotService erpDepotService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotStaff::getDepotId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + return CollectionUtil.newArrayList(); + } + List> beans = super.queryPageDataList(inputObject); + // 设置员工信息 + List staffIds = beans.stream().map(bean -> bean.get("staffId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String staffId = bean.get("staffId").toString(); + bean.put("staffMation", staffMap.get(staffId)); + }); + return beans; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertDepotStaff(InputObject inputObject, OutputObject outputObject) { + DepotStaffVO DepotStaffVO = inputObject.getParams(DepotStaffVO.class); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotStaff::getDepotId), DepotStaffVO.getDepotId()); + List list = list(queryWrapper); + List DepotStaffIdList = list.stream().map(DepotStaff::getStaffId).collect(Collectors.toList()); + + List beans = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + for (String str : DepotStaffVO.getStaffId()) { + if (DepotStaffIdList.contains(str)) { + // 如果该仓库已经存在这个员工,则跳过 + continue; + } + if (StrUtil.isNotEmpty(str)) { + DepotStaff item = new DepotStaff(); + item.setDepotId(DepotStaffVO.getDepotId()); + item.setStaffId(str); + beans.add(item); + } + } + if (CollectionUtil.isNotEmpty(beans)) { + createEntity(beans, userId); + } + } + + @Override + public void queryStaffBelongDepotList(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + List DepotList = getDepotListByStaffId(staffId, userId); + outputObject.setBeans(DepotList); + outputObject.settotal(DepotList.size()); + } + + private List getDepotListByStaffId(String staffId, String userId) { + // 1. 查询员工所属的仓库 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotStaff::getStaffId), staffId); + List list = list(queryWrapper); + // 获取仓库id + List depotIdList = list.stream().map(DepotStaff::getDepotId).collect(Collectors.toList()); + // 查询仓库信息 + List depotList = erpDepotService.selectByIds(depotIdList.toArray(new String[]{})); + // 2. 查询当前用户所负责的仓库 + List chargeDepotList = erpDepotService.queryDepotListByChargePerson(userId); + // 3. 合并仓库信息 + depotList.addAll(chargeDepotList); + // 4. 去重 + depotList = depotList.stream() + .collect(Collectors.collectingAndThen( + Collectors.toMap( + Depot::getId, // 使用id作为key + Function.identity(), // 使用原始对象作为value + (existing, replacement) -> existing), // 当键冲突时,保留现有的条目 + map -> new ArrayList<>(map.values()))); // 将Map的值转换回List + return depotList; + } + + @Override + public void deleteDepotStaffByStaffId(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepotStaff::getStaffId), staffId); + remove(queryWrapper); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/ErpDepotServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/ErpDepotServiceImpl.java new file mode 100644 index 0000000..6a8ece1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/depot/service/impl/ErpDepotServiceImpl.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.depot.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.dao.ErpDepotDao; +import com.skyeye.depot.entity.Depot; +import com.skyeye.depot.service.ErpDepotService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ErpDepotServiceImpl + * @Description: 仓库信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "仓库管理", groupName = "仓库管理") +public class ErpDepotServiceImpl extends SkyeyeBusinessServiceImpl implements ErpDepotService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + protected void writePostpose(Depot entity, String userId) { + if (entity.getIsDefault().equals(IsDefaultEnum.IS_DEFAULT.getKey())) { + // 如果将当前数据修改为默认数据,则需要修改之前的数据为非默认 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.ne(CommonConstants.ID, entity.getId()); + updateWrapper.eq(MybatisPlusUtil.toColumns(Depot::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Depot::getIsDefault), IsDefaultEnum.NOT_DEFAULT.getKey()); + update(updateWrapper); + } + } + + @Override + public Depot selectById(String id) { + Depot depot = super.selectById(id); + depot.setPrincipalMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(depot.getPrincipal()))); + return depot; + } + + @Override + public List selectByIds(String... ids) { + List depots = super.selectByIds(ids); + List principalIds = depots.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getPrincipal())) + .flatMap(norms -> norms.getPrincipal().stream()).distinct().collect(Collectors.toList()); + Map> userMap = iAuthUserService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(principalIds)); + depots.forEach(depot -> { + if (CollectionUtil.isEmpty(depot.getPrincipal())) { + return; + } + List> userMation = new ArrayList<>(); + depot.getPrincipal().forEach(principalId -> { + if (!userMap.containsKey(principalId)) { + return; + } + userMation.add(userMap.get(principalId)); + }); + depot.setPrincipalMation(userMation); + }); + return depots; + } + + /** + * 获取所有仓库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllStoreHouseList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Depot::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Depot::getIsDefault)); + List depotList = list(queryWrapper); + outputObject.setBeans(depotList); + outputObject.settotal(depotList.size()); + } + + /** + * 获取当前登录用户管理的仓库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStoreHouseListByCurrentUserId(InputObject inputObject, OutputObject outputObject) { + String currentUserId = inputObject.getLogParams().get("id").toString(); + List depotList = queryDepotListByChargePerson(currentUserId); + outputObject.setBeans(depotList); + outputObject.settotal(depotList.size()); + } + + @Override + public List queryDepotListByChargePerson(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("INSTR(CONCAT(',', REPLACE(REPLACE(" + MybatisPlusUtil.toColumns(Depot::getPrincipal) + ", '[', ''), ']', ''), ','), CONCAT(',\"', {0}, '\",'))", userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Depot::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Depot::getIsDefault)); + List depotList = list(queryWrapper); + return depotList; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderCommon.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderCommon.java new file mode 100644 index 0000000..2e23292 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderCommon.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.farm.entity.Farm; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpOrderHead + * @Description: ERP相关订单实体类,包括:采购入库单 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("ERP相关订单实体类") +public class ErpOrderCommon extends SkyeyeFlowable { + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @Property(value = "出入库类型,参考#DepotPutOutType") + private Integer type; + + /** + * 订单类型,每个服务类的serviceClassName + */ + @TableField(value = "id_key", updateStrategy = FieldStrategy.NEVER) + private String idKey; + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("salesman") + @ApiModelProperty(value = "业务员id") + private String salesman; + + @TableField(exist = false) + @Property(value = "业务员信息") + private Map salesmanMation; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("real_complate_time") + @Property(value = "实际完成时间") + private String realComplateTime; + + @TableField(exist = false) + @ApiModelProperty(value = "商品列表,json串", required = "required,json") + private List erpOrderItemList; + + @TableField("quality_inspection") + @Property(value = "质检类型,参考#OrderQualityInspectionType") + private Integer qualityInspection; + + @TableField("need_depot") + @ApiModelProperty(value = "是否需要出入库,参考#WhetherEnum") + private Integer needDepot; + + @TableField("other_state") + @Property("其他状态信息,根据单据类型不同,状态信息表达含义不同。") + private Integer otherState; + + @TableField(value = "department_id") + @ApiModelProperty(value = "部门id") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间id") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField(value = "store_id") + @ApiModelProperty(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderHead.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderHead.java new file mode 100644 index 0000000..659b785 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderHead.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ErpOrderHead + * @Description: ERP相关订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("ERP相关订单实体类") +public class ErpOrderHead extends ErpOrderCommon { + + @TableField("project_id") + @ApiModelProperty(value = "关联项目id") + private String projectId; + + @TableField(exist = false) + @Property(value = "关联项目信息") + private Map projectMation; + + @TableField("discount") + @ApiModelProperty(value = "优惠率,默认为0.00", required = "double") + private String discount; + + @TableField("discount_money") + @ApiModelProperty(value = "优惠金额/折损扣费,默认为0.00", required = "double") + private String discountMoney; + + @TableField("need_over_plan") + @ApiModelProperty(value = "是否需要统筹,参考#WhetherEnum") + private Integer needOverPlan; + + @TableField("plan_complate_time") + @ApiModelProperty(value = "计划完成时间") + private String planComplateTime; + + @TableField("pay_type") + @ApiModelProperty(value = "付款类型,参考#PayTypeEnum", required = "num", defaultValue = "0") + private String payType; + + @TableField("holder_id") + @ApiModelProperty(value = "关联的客户/供应商/会员id") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/供应商/会员信息") + private Map holderMation; + + @TableField("holder_key") + @ApiModelProperty(value = "关联的客户/供应商/会员的className") + private String holderKey; + + @TableField("total_price") + @ApiModelProperty(value = "合计总金额(减去优惠后的金额,加上其他金额)") + private String totalPrice; + + @TableField("account_id") + @ApiModelProperty(value = "账户id") + private String accountId; + + @TableField(exist = false) + @Property(value = "账户信息") + private Map accountMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItem.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItem.java new file mode 100644 index 0000000..2aaedb8 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItem.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpOrderItem + * @Description: ERP相关订单关联的产品信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_depotitem") +@ApiModel("ERP相关订单关联的产品信息实体类") +public class ErpOrderItem extends SkyeyeLinkData { + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField("oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField(exist = false) + @ApiModelProperty(value = "未出入库数量") + private Integer notUseNumber; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "another_depot_id") + @ApiModelProperty(value = "调拨时,对方仓库Id") + private String anotherDepotId; + + @TableField(exist = false) + @Property(value = "调拨时,对方仓库信息") + private Depot anotherDepotMation; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("m_type") + @ApiModelProperty(value = "商品在单据中的类型,参考#MaterialInOrderType", required = "num") + private Integer mType; + + @TableField(exist = false) + @Property(value = "商品在单据中的类型信息") + private Map mTypeMation; + + @TableField("quality_inspection") + @ApiModelProperty(value = "质检类型,参考#OrderItemQualityInspectionType", required = "num") + private Integer qualityInspection; + + @TableField(exist = false) + @Property(value = "质检类型信息") + private Map qualityInspectionMation; + + @TableField("quality_inspection_ratio") + @ApiModelProperty(value = "质检比例(%),质检类型为抽检时才生效") + private String qualityInspectionRatio; + + @TableField(exist = false) + @ApiModelProperty(value = "商品规格条形码编号") + private String normsCode; + + @TableField(exist = false) + @Property(value = "商品规格条形码编号集合") + private List normsCodeList; + + @TableField("delivery_time") + @ApiModelProperty(value = "交货日期") + private String deliveryTime; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItemCode.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItemCode.java new file mode 100644 index 0000000..7d0fb95 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/ErpOrderItemCode.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ErpOrderItemCode + * @Description: 单据子表关联的条形码编号 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_depotitem_code") +@ApiModel("单据子表关联的条形码编号实体类") +public class ErpOrderItemCode extends CommonInfo { + + @TableId("id") + private String id; + + @TableField("parent_id") + @Property(value = "订单id") + private String parentId; + + @TableField("material_id") + @Property(value = "产品id") + private String materialId; + + @TableField("norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField("norms_code") + @Property(value = "条形码编号") + private String normsCode; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/TransmitObject.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/TransmitObject.java new file mode 100644 index 0000000..37962c3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/entity/TransmitObject.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: TransmitObject + * @Description: 价格信息 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class TransmitObject implements Serializable { + + private static final long serialVersionUID = 8791538327978796421L; + + /** + * 主单据价税合计 + */ + private String taxLastMoneyPrice = "0"; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/controller/EquipmentController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/controller/EquipmentController.java new file mode 100644 index 0000000..a542061 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/controller/EquipmentController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.equipment.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.equipment.entity.Equipment; +import com.skyeye.equipment.service.EquipmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EquipmentController + * @Description: 设备管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "设备管理", tags = "设备管理", modelName = "设备管理") +public class EquipmentController { + + @Autowired + private EquipmentService equipmentService; + + /** + * 获取设备列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEquipmentList", value = "获取设备列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/EquipmentController/queryEquipmentList") + public void queryEquipmentList(InputObject inputObject, OutputObject outputObject) { + equipmentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑设备信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeEquipment", value = "新增/编辑设备信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Equipment.class) + @RequestMapping("/post/EquipmentController/writeEquipment") + public void writeEquipment(InputObject inputObject, OutputObject outputObject) { + equipmentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID删除设备信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteEquipmentById", value = "根据ID删除设备信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/EquipmentController/deleteEquipmentById") + public void deleteEquipmentById(InputObject inputObject, OutputObject outputObject) { + equipmentService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有设备列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEquipmentList", value = "获取所有设备列表", method = "GET", allUse = "2") + @RequestMapping("/post/EquipmentController/queryAllEquipmentList") + public void queryAllEquipmentList(InputObject inputObject, OutputObject outputObject) { + equipmentService.queryAllEquipmentList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/dao/EquipmentDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/dao/EquipmentDao.java new file mode 100644 index 0000000..b171079 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/dao/EquipmentDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.equipment.dao; + +import com.skyeye.equipment.entity.Equipment; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: EquipmentDao + * @Description: 设备管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EquipmentDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/entity/Equipment.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/entity/Equipment.java new file mode 100644 index 0000000..ef6ffc3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/entity/Equipment.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.equipment.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.farm.entity.Farm; +import lombok.Data; + +/** + * @ClassName: Equipment + * @Description: 设备管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"name", "model", "serialNumber"}) +@RedisCacheField(name = "mes:equipment") +@TableName(value = "erp_equipment") +@ApiModel("设备管理实体类") +public class Equipment extends BaseGeneralInfo { + + @TableField(value = "model") + @ApiModelProperty(value = "规格", required = "required", fuzzyLike = true) + private String model; + + @TableField(value = "serial_number") + @ApiModelProperty(value = "序列号", required = "required", fuzzyLike = true) + private String serialNumber; + + @TableField(value = "manufacturer") + @ApiModelProperty(value = "生产厂家", required = "required") + private String manufacturer; + + @TableField(value = "buy_time") + @ApiModelProperty(value = "购买日期", required = "required") + private String buyTime; + + @TableField(value = "operating_hours") + @ApiModelProperty(value = "每日运转时长") + private String operatingHours; + + @TableField(value = "quota_capacity") + @ApiModelProperty(value = "定额能力(h)") + private String quotaCapacity; + + @TableField(value = "max_capacity") + @ApiModelProperty(value = "最大能力(h)") + private String maxCapacity; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间id", required = "required") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/EquipmentService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/EquipmentService.java new file mode 100644 index 0000000..d13024b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/EquipmentService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.equipment.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.equipment.entity.Equipment; + +/** + * @ClassName: EquipmentService + * @Description: 设备管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EquipmentService extends SkyeyeBusinessService { + + void queryAllEquipmentList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/impl/EquipmentServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/impl/EquipmentServiceImpl.java new file mode 100644 index 0000000..e9448c4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/equipment/service/impl/EquipmentServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.equipment.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.equipment.dao.EquipmentDao; +import com.skyeye.equipment.entity.Equipment; +import com.skyeye.equipment.service.EquipmentService; +import com.skyeye.farm.service.FarmService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EquipmentServiceImpl + * @Description: 设备管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 21:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "设备管理", groupName = "设备管理") +public class EquipmentServiceImpl extends SkyeyeBusinessServiceImpl implements EquipmentService { + + @Autowired + private FarmService farmService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + farmService.setMationForMap(beans, "farmId", "farmMation"); + return beans; + } + + @Override + public Equipment selectById(String id) { + Equipment equipment = super.selectById(id); + farmService.setDataMation(equipment, Equipment::getFarmId); + return equipment; + } + + @Override + public void queryAllEquipmentList(InputObject inputObject, OutputObject outputObject) { + List equipmentList = list(); + outputObject.setBeans(equipmentList); + outputObject.settotal(equipmentList.size()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmController.java new file mode 100644 index 0000000..bf5619f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmController.java @@ -0,0 +1,113 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.farm.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.farm.entity.Farm; +import com.skyeye.farm.service.FarmService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FarmController + * @Description: 加工车间管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2020/8/30 14:09 + * @Copyright: 2020 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车间管理", tags = "车间管理", modelName = "车间管理") +public class FarmController { + + @Autowired + private FarmService farmService; + + /** + * 获取车间列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpfarm001", value = "获取车间列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FarmController/queryFarmList") + public void queryFarmList(InputObject inputObject, OutputObject outputObject) { + farmService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeFarm", value = "新增/编辑车间信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Farm.class) + @RequestMapping("/post/FarmController/writeFarm") + public void writeFarm(InputObject inputObject, OutputObject outputObject) { + farmService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFarmById", value = "根据id获取车间信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FarmController/queryFarmById") + public void queryFarmById(InputObject inputObject, OutputObject outputObject) { + farmService.selectById(inputObject, outputObject); + } + + /** + * 根据ID删除车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFarmById", value = "根据ID删除车间信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FarmController/deleteFarmById") + public void deleteFarmById(InputObject inputObject, OutputObject outputObject) { + farmService.deleteById(inputObject, outputObject); + } + + /** + * 获取我负责的车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyChargeFarmList", value = "获取我负责的车间信息", method = "GET", allUse = "2") + @RequestMapping("/post/FarmController/queryMyChargeFarmList") + public void queryMyChargeFarmList(InputObject inputObject, OutputObject outputObject) { + farmService.queryMyChargeFarmList(inputObject, outputObject); + } + + /** + * 获取所有启用的车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledFarmList", value = "获取所有启用的车间信息", method = "GET", allUse = "2") + @RequestMapping("/post/FarmController/queryEnabledFarmList") + public void queryEnabledFarmList(InputObject inputObject, OutputObject outputObject) { + farmService.queryEnabledFarmList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmStaffController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmStaffController.java new file mode 100644 index 0000000..41a7d29 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/controller/FarmStaffController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.farm.entity.FarmStaffVO; +import com.skyeye.farm.service.FarmStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FarmStaffController + * @Description: 车间与员工的关系管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车间与员工的关系管理", tags = "车间与员工的关系管理", modelName = "车间与员工的关系管理") +public class FarmStaffController { + + @Autowired + private FarmStaffService farmStaffService; + + /** + * 获取车间下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFarmStaffList", value = "获取车间下的员工信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FarmStaffController/queryFarmStaffList") + public void queryFarmStaffList(InputObject inputObject, OutputObject outputObject) { + farmStaffService.queryPageList(inputObject, outputObject); + } + + /** + * 删除车间下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFarmStaffById", value = "删除车间下的员工信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "车间与员工的关系表主键id", required = "required")}) + @RequestMapping("/post/FarmStaffController/deleteFarmStaffById") + public void deleteFarmStaffById(InputObject inputObject, OutputObject outputObject) { + farmStaffService.deleteById(inputObject, outputObject); + } + + /** + * 新增车间下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertFarmStaff", value = "新增车间下的员工信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = FarmStaffVO.class) + @RequestMapping("/post/FarmStaffController/insertFarmStaff") + public void insertFarmStaff(InputObject inputObject, OutputObject outputObject) { + farmStaffService.insertFarmStaff(inputObject, outputObject); + } + + /** + * 获取当前登陆用户所属的车间列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStaffBelongFarmList", value = "获取当前登陆用户所属的车间列表", method = "GET", allUse = "2") + @RequestMapping("/post/FarmStaffController/queryStaffBelongFarmList") + public void queryStaffBelongFarmList(InputObject inputObject, OutputObject outputObject) { + farmStaffService.queryStaffBelongFarmList(inputObject, outputObject); + } + + /** + * 根据员工id删除所有的所属车间信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFarmStaffByStaffId", value = "根据员工id删除所有的所属车间信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "员工id", required = "required")}) + @RequestMapping("/post/FarmStaffController/deleteFarmStaffByStaffId") + public void deleteFarmStaffByStaffId(InputObject inputObject, OutputObject outputObject) { + farmStaffService.deleteFarmStaffByStaffId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmDao.java new file mode 100644 index 0000000..9397e8e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmDao.java @@ -0,0 +1,20 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.farm.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.farm.entity.Farm; + +/** + * @ClassName: FarmDao + * @Description: 车间管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FarmDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmStaffDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmStaffDao.java new file mode 100644 index 0000000..fa1e6f6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/dao/FarmStaffDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.farm.entity.FarmStaff; + +/** + * @ClassName: FarmStaffDao + * @Description: 车间与员工的关系数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FarmStaffDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/Farm.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/Farm.java new file mode 100644 index 0000000..b4ebc28 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/Farm.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Farm + * @Description: 车间管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/24 22:43 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_FARM_CACHE_KEY) +@TableName(value = "erp_farm") +@ApiModel("车间管理实体类") +public class Farm extends BaseGeneralInfo { + + @TableField(value = "number") + @ApiModelProperty(value = "车间编号", required = "required", fuzzyLike = true) + private String number; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "department_id") + @ApiModelProperty(value = "部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "charge_person") + @ApiModelProperty(value = "车间负责人", required = "required") + private String chargePerson; + + @TableField(exist = false) + @Property(value = "车间负责人") + private Map chargePersonMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaff.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaff.java new file mode 100644 index 0000000..674eebe --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaff.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: FarmStaff + * @Description: 车间与员工的关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_farm_staff", autoResultMap = true) +@ApiModel("车间与员工的关系实体类") +public class FarmStaff extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间ID", required = "required") + private String farmId; + + @TableField(value = "staff_id") + @ApiModelProperty(value = "员工ID", required = "required") + private String staffId; + + @TableField(exist = false) + @Property(value = "员工信息") + private Map staffMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaffVO.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaffVO.java new file mode 100644 index 0000000..7646d37 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/entity/FarmStaffVO.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: FarmStaffVO + * @Description: 车间与员工的关系入参实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("车间与员工的关系入参实体类") +public class FarmStaffVO implements Serializable { + + @ApiModelProperty(value = "车间ID", required = "required") + private String farmId; + + @ApiModelProperty(value = "员工ID", required = "required,json") + private List staffId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmService.java new file mode 100644 index 0000000..3ab6a71 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmService.java @@ -0,0 +1,33 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.farm.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.farm.entity.Farm; + +import java.util.List; + +/** + * @ClassName: FarmService + * @Description: 车间管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FarmService extends SkyeyeBusinessService { + + List queryFarmIdListByDepartmentId(String departmentId); + + List queryFarmListByChargePerson(String userId); + + void queryMyChargeFarmList(InputObject inputObject, OutputObject outputObject); + + void queryEnabledFarmList(InputObject inputObject, OutputObject outputObject); + + List queryEnabledFarmList(); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmStaffService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmStaffService.java new file mode 100644 index 0000000..a55b6ac --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/FarmStaffService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.farm.entity.FarmStaff; + +import java.util.List; + +/** + * @ClassName: FarmStaffService + * @Description: 车间与员工的关系服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FarmStaffService extends SkyeyeBusinessService { + + void insertFarmStaff(InputObject inputObject, OutputObject outputObject); + + void queryStaffBelongFarmList(InputObject inputObject, OutputObject outputObject); + + void deleteFarmStaffByStaffId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmServiceImpl.java new file mode 100644 index 0000000..157627e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmServiceImpl.java @@ -0,0 +1,138 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.farm.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.dao.FarmDao; +import com.skyeye.farm.entity.Farm; +import com.skyeye.farm.service.FarmService; +import com.skyeye.organization.service.IDepmentService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: FarmServiceImpl + * @Description: 车间管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车间管理", groupName = "车间管理") +public class FarmServiceImpl extends SkyeyeBusinessServiceImpl implements FarmService { + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + if (CollectionUtil.isEmpty(beans)) { + return beans; + } + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + iAuthUserService.setMationForMap(beans, "chargePerson", "chargePersonMation"); + return beans; + } + + @Override + public void validatorEntity(Farm entity) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(Farm::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(Farm::getNumber), entity.getNumber())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Farm checkFarm = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkFarm)) { + throw new CustomException("this 【name/number】 is exist."); + } + } + + @Override + public void writePostpose(Farm entity, String userId) { + super.writePostpose(entity, userId); + } + + @Override + public Farm selectById(String id) { + Farm farm = super.selectById(id); + // 设置负责人 + iAuthUserService.setDataMation(farm, Farm::getChargePerson); + iDepmentService.setDataMation(farm, Farm::getDepartmentId); + return farm; + } + + @Override + public List selectByIds(String... ids) { + List farms = super.selectByIds(ids); + // 设置负责人 + iAuthUserService.setDataMation(farms, Farm::getChargePerson); + iDepmentService.setDataMation(farms, Farm::getDepartmentId); + return farms; + } + + @Override + public List queryFarmIdListByDepartmentId(String departmentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getDepartmentId), departmentId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List farmList = list(queryWrapper); + List idList = farmList.stream().map(Farm::getId).collect(Collectors.toList()); + return idList; + } + + @Override + public void queryMyChargeFarmList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + List farmList = queryFarmListByChargePerson(userId); + outputObject.setBeans(farmList); + outputObject.settotal(farmList.size()); + } + + @Override + public List queryFarmListByChargePerson(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getChargePerson), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List farmList = list(queryWrapper); + return farmList; + } + + @Override + public void queryEnabledFarmList(InputObject inputObject, OutputObject outputObject) { + List farmList = queryEnabledFarmList(); + outputObject.setBeans(farmList); + outputObject.settotal(farmList.size()); + } + + @Override + public List queryEnabledFarmList() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Farm::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List farmList = list(queryWrapper); + return farmList; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmStaffServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmStaffServiceImpl.java new file mode 100644 index 0000000..35efb8e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/farm/service/impl/FarmStaffServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.farm.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.farm.dao.FarmStaffDao; +import com.skyeye.farm.entity.Farm; +import com.skyeye.farm.entity.FarmStaff; +import com.skyeye.farm.entity.FarmStaffVO; +import com.skyeye.farm.service.FarmService; +import com.skyeye.farm.service.FarmStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: FarmStaffServiceImpl + * @Description: 车间与员工的关系服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车间与员工的关系管理", groupName = "车间与员工的关系管理", manageShow = false) +public class FarmStaffServiceImpl extends SkyeyeBusinessServiceImpl implements FarmStaffService { + + @Autowired + private FarmService farmService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(FarmStaff::getFarmId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + return CollectionUtil.newArrayList(); + } + List> beans = super.queryPageDataList(inputObject); + // 设置员工信息 + List staffIds = beans.stream().map(bean -> bean.get("staffId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String staffId = bean.get("staffId").toString(); + bean.put("staffMation", staffMap.get(staffId)); + }); + return beans; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertFarmStaff(InputObject inputObject, OutputObject outputObject) { + FarmStaffVO farmStaffVO = inputObject.getParams(FarmStaffVO.class); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FarmStaff::getFarmId), farmStaffVO.getFarmId()); + List list = list(queryWrapper); + List farmStaffIdList = list.stream().map(FarmStaff::getStaffId).collect(Collectors.toList()); + + List beans = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + for (String str : farmStaffVO.getStaffId()) { + if (farmStaffIdList.contains(str)) { + // 如果该车间已经存在这个员工,则跳过 + continue; + } + if (StrUtil.isNotEmpty(str)) { + FarmStaff item = new FarmStaff(); + item.setFarmId(farmStaffVO.getFarmId()); + item.setStaffId(str); + beans.add(item); + } + } + if (CollectionUtil.isNotEmpty(beans)) { + createEntity(beans, userId); + } + } + + @Override + public void queryStaffBelongFarmList(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + List farmList = getFarmListByStaffId(staffId, userId); + outputObject.setBeans(farmList); + outputObject.settotal(farmList.size()); + } + + private List getFarmListByStaffId(String staffId, String userId) { + // 1. 查询员工所属的车间 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FarmStaff::getStaffId), staffId); + List list = list(queryWrapper); + // 获取车间id + List farmIdList = list.stream().map(FarmStaff::getFarmId).collect(Collectors.toList()); + // 查询车间信息 + List farmList = farmService.selectByIds(farmIdList.toArray(new String[]{})); + // 2. 查询当前用户所负责的车间 + List chargeFarmList = farmService.queryFarmListByChargePerson(userId); + // 3. 合并车间信息 + farmList.addAll(chargeFarmList); + // 4. 去重 + farmList = farmList.stream() + .collect(Collectors.collectingAndThen( + Collectors.toMap( + Farm::getId, // 使用id作为key + Function.identity(), // 使用原始对象作为value + (existing, replacement) -> existing), // 当键冲突时,保留现有的条目 + map -> new ArrayList<>(map.values()))); // 将Map的值转换回List + return farmList; + } + + @Override + public void deleteFarmStaffByStaffId(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FarmStaff::getStaffId), staffId); + remove(queryWrapper); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/classenum/HolderNormsChildState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/classenum/HolderNormsChildState.java new file mode 100644 index 0000000..b5e986e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/classenum/HolderNormsChildState.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: HolderNormsChildState + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 11:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum HolderNormsChildState implements SkyeyeEnumClass { + + NORMAL_TRANSACTIONS(1, "正常交易", "green", true, true), + RETURN_OF_GOODS(2, "退还货物", "red", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsChildController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsChildController.java new file mode 100644 index 0000000..87d2747 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsChildController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.holder.service.HolderNormsChildService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: HolderNormsChildController + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/16 10:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "关联的客户/供应商/会员购买或者出售的商品子信息", tags = "关联的客户/供应商/会员购买或者出售的商品子信息", modelName = "关联的客户/供应商/会员购买或者出售的商品子信息") +public class HolderNormsChildController { + + @Autowired + private HolderNormsChildService holderNormsChildService; + + /** + * 获取关联的客户/供应商/会员购买或者出售的商品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHolderNormsChildList", value = "获取关联的客户/供应商/会员购买或者出售的商品子信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/HolderNormsChildController/queryHolderNormsChildList") + public void queryHolderNormsList(InputObject inputObject, OutputObject outputObject) { + holderNormsChildService.queryPageList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsController.java new file mode 100644 index 0000000..1bb577f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/controller/HolderNormsController.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.holder.service.HolderNormsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: HolderNormsController + * @Description: 关联的客户/供应商/会员购买或者出售的商品信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:34 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "关联的客户/供应商/会员购买或者出售的商品信息管理", tags = "关联的客户/供应商/会员购买或者出售的商品信息管理", modelName = "关联的客户/供应商/会员购买或者出售的商品信息管理") +public class HolderNormsController { + + @Autowired + private HolderNormsService holderNormsService; + + /** + * 获取关联的客户/供应商/会员购买或者出售的商品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHolderNormsList", value = "获取关联的客户/供应商/会员购买或者出售的商品信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/HolderNormsController/queryHolderNormsList") + public void queryHolderNormsList(InputObject inputObject, OutputObject outputObject) { + holderNormsService.queryPageList(inputObject, outputObject); + } + + /** + * 根据holder获取商品信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHolderMaterialListByHolder", value = "根据holder获取商品信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "holderId", name = "holderId", value = "关联的客户/供应商/会员id"), + @ApiImplicitParam(id = "holderKey", name = "holderKey", value = "关联的客户/供应商/会员的className")}) + @RequestMapping("/post/HolderNormsController/queryHolderMaterialListByHolder") + public void queryHolderMaterialListByHolder(InputObject inputObject, OutputObject outputObject) { + holderNormsService.queryHolderMaterialListByHolder(inputObject, outputObject); + } + + /** + * 根据holder获取商品规格信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHolderMaterialNormsListByHolder", value = "根据holder获取商品规格信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "materialId", name = "materialId", value = "商品id"), + @ApiImplicitParam(id = "holderId", name = "holderId", value = "关联的客户/供应商/会员id"), + @ApiImplicitParam(id = "holderKey", name = "holderKey", value = "关联的客户/供应商/会员的className")}) + @RequestMapping("/post/HolderNormsController/queryHolderMaterialNormsListByHolder") + public void queryHolderMaterialNormsListByHolder(InputObject inputObject, OutputObject outputObject) { + holderNormsService.queryHolderMaterialNormsListByHolder(inputObject, outputObject); + } + + /** + * 根据holder获取商品规格对应的条形码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHolderMaterialNormsCodeListByHolder", value = "根据holder获取商品规格对应的条形码信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "normsId", name = "normsId", value = "规格id"), + @ApiImplicitParam(id = "holderId", name = "holderId", value = "关联的客户/供应商/会员id"), + @ApiImplicitParam(id = "holderKey", name = "holderKey", value = "关联的客户/供应商/会员的className")}) + @RequestMapping("/post/HolderNormsController/queryHolderMaterialNormsCodeListByHolder") + public void queryHolderMaterialNormsCodeListByHolder(InputObject inputObject, OutputObject outputObject) { + holderNormsService.queryHolderMaterialNormsCodeListByHolder(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsChildDao.java new file mode 100644 index 0000000..3ebd6c7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.holder.entity.HolderNormsChild; + +/** + * @ClassName: HolderNormsChildDao + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 11:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface HolderNormsChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsDao.java new file mode 100644 index 0000000..b69cb5e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/dao/HolderNormsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.holder.entity.HolderNorms; + +/** + * @ClassName: HolderNormsDao + * @Description: 关联的客户/供应商/会员购买或者出售的商品信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface HolderNormsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNorms.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNorms.java new file mode 100644 index 0000000..300b59c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNorms.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: HolderNorms + * @Description: 关联的客户/供应商/会员购买或者出售的商品信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "erp_holder_norms", autoResultMap = true) +@ApiModel("关联的客户/供应商/会员购买或者出售的商品信息实体类") +public class HolderNorms extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @Property(value = "名称") + private String name; + + @TableField(value = "holder_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "关联的客户/供应商/会员id", required = "required") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/供应商/会员的信息") + private Map holderMation; + + @TableField(value = "holder_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "关联的客户/供应商/会员的className", required = "required") + private String holderKey; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField("oper_number") + @ApiModelProperty(value = "交易数量", required = "required") + private Integer operNumber; + + @TableField(value = "sum(oper_number)", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER) + @Property(value = "交易数量合计") + private Integer allOperNumber; + + @TableField("create_time") + @Property(value = "创建时间") + private String createTime; + + @TableField(exist = false) + @Property(value = "商品规格条形码编号集合") + private List normsCodeList; + + @TableField(value = "order_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "单据id") + private String orderId; + + @TableField(value = "order_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "单据的className") + private String orderKey; + + @TableField(exist = false) + @Property(value = "关联的单据信息") + private Map orderMation; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNormsChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNormsChild.java new file mode 100644 index 0000000..cae738d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/entity/HolderNormsChild.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: HolderNormsChild + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "erp_holder_norms_child", autoResultMap = true) +@ApiModel("关联的客户/供应商/会员购买或者出售的商品子信息实体类") +public class HolderNormsChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "holder_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "关联的客户/供应商/会员id", required = "required") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/供应商/会员的信息") + private Map holderMation; + + @TableField(value = "holder_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "关联的客户/供应商/会员的className", required = "required") + private String holderKey; + + @TableField("parent_id") + @ApiModelProperty(value = "父节点id", required = "required") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField("norms_code_num") + @ApiModelProperty(value = "条形码编号", required = "required", fuzzyLike = true) + private String normsCodeNum; + + @TableField("state") + @ApiModelProperty(value = "状态,参考#HolderNormsChildState", required = "required") + private Integer state; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsChildService.java new file mode 100644 index 0000000..178a2b1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsChildService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.holder.entity.HolderNormsChild; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: HolderNormsChildService + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 11:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface HolderNormsChildService extends SkyeyeBusinessService { + + void editHolderNormsChildState(String holderId, List normsCode, Integer state); + + List> queryHolderMaterialNormsCodeListByHolder(String holderId, String holderKey, String normsId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsService.java new file mode 100644 index 0000000..d243b72 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/HolderNormsService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.holder.entity.HolderNorms; + +import java.util.List; + +/** + * @ClassName: HolderNormsService + * @Description: 关联的客户/供应商/会员购买或者出售的商品信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface HolderNormsService extends SkyeyeBusinessService { + + void queryHolderMaterialListByHolder(InputObject inputObject, OutputObject outputObject); + + List queryHolderMaterialIdListByHolderId(String holderId); + + void queryHolderMaterialNormsListByHolder(InputObject inputObject, OutputObject outputObject); + + void queryHolderMaterialNormsCodeListByHolder(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsChildServiceImpl.java new file mode 100644 index 0000000..ff1b9ce --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsChildServiceImpl.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.service.IBarCodeService; +import com.skyeye.holder.dao.HolderNormsChildDao; +import com.skyeye.holder.entity.HolderNormsChild; +import com.skyeye.holder.service.HolderNormsChildService; +import com.skyeye.holder.service.HolderNormsService; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.impl.MaterialNormsCodeServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: HolderNormsChildServiceImpl + * @Description: 关联的客户/供应商/会员购买或者出售的商品子信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/5 11:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "关联的客户/供应商/会员购买或者出售的商品子信息", groupName = "关联的客户/供应商/会员购买或者出售的商品子信息", manageShow = false) +public class HolderNormsChildServiceImpl extends SkyeyeBusinessServiceImpl implements HolderNormsChildService { + + @Autowired + private MaterialNormsCodeService materialNormsCodeService; + + @Autowired + private IBarCodeService iBarCodeService; + + @Autowired + private HolderNormsService holderNormsService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getHolderId), commonPageInfo.getHolderId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getHolderKey), commonPageInfo.getHolderKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getNormsId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + if (CollectionUtil.isEmpty(beans)) { + return beans; + } + // 商品编码信息 + List normsCodeNumList = beans.stream().map(bean -> bean.get("normsCodeNum").toString()) + .collect(Collectors.toList()); + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, normsCodeNumList); + iBarCodeService.setBarCodeMation(materialNormsCodeList, "id", MaterialNormsCodeServiceImpl.class.getName()); + Map materialNormsCodeMap = materialNormsCodeList.stream().collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + beans.forEach(bean -> { + String normsCodeNum = bean.get("normsCodeNum").toString(); + bean.put("normsCodeMation", materialNormsCodeMap.get(normsCodeNum)); + }); + return beans; + } + + @Override + public void editHolderNormsChildState(String holderId, List normsCode, Integer state) { + // 获取关联的客户/供应商/会员购买或者出售的商品信息id + List ids = holderNormsService.queryHolderMaterialIdListByHolderId(holderId); + if (CollectionUtil.isEmpty(ids)) { + return; + } + // 查询购买或者出售的商品编码信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(HolderNormsChild::getParentId), ids); + List holderNormsChildList = list(queryWrapper); + if (CollectionUtil.isEmpty(holderNormsChildList)) { + return; + } + List childIds = holderNormsChildList.stream() + .filter(bean -> normsCode.contains(bean.getNormsCodeNum())) + .map(HolderNormsChild::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(childIds)) { + return; + } + // 修改状态 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in(CommonConstants.ID, childIds); + updateWrapper.set(MybatisPlusUtil.toColumns(HolderNormsChild::getState), state); + update(updateWrapper); + } + + @Override + public List> queryHolderMaterialNormsCodeListByHolder(String holderId, String holderKey, String normsId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getHolderId), holderId); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getHolderKey), holderKey); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNormsChild::getNormsId), normsId); + List holderNormsChildList = list(queryWrapper); + List> resultList = holderNormsChildList.stream().map(bean -> { + Map map = BeanUtil.beanToMap(bean); + map.put("id", bean.getNormsCodeNum()); + map.put("name", bean.getNormsCodeNum()); + return map; + }).collect(Collectors.toList()); + return resultList; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsServiceImpl.java new file mode 100644 index 0000000..5a83570 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/holder/service/impl/HolderNormsServiceImpl.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.holder.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.holder.classenum.HolderNormsChildState; +import com.skyeye.holder.dao.HolderNormsDao; +import com.skyeye.holder.entity.HolderNorms; +import com.skyeye.holder.entity.HolderNormsChild; +import com.skyeye.holder.service.HolderNormsChildService; +import com.skyeye.holder.service.HolderNormsService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: HolderNormsServiceImpl + * @Description: 关联的客户/供应商/会员购买或者出售的商品信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/2 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "关联的客户/供应商/会员购买或者出售的商品信息管理", groupName = "关联的客户/供应商/会员购买或者出售的商品信息管理", manageShow = false) +public class HolderNormsServiceImpl extends SkyeyeBusinessServiceImpl implements HolderNormsService { + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private HolderNormsChildService holderNormsChildService; + + @Autowired + protected ErpDepotService erpDepotService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getHolderKey())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderKey), commonPageInfo.getHolderKey()); + } + queryWrapper.select(MybatisPlusUtil.toColumns(HolderNorms::getMaterialId), + MybatisPlusUtil.toColumns(HolderNorms::getHolderId), MybatisPlusUtil.toColumns(HolderNorms::getHolderKey), + MybatisPlusUtil.toColumns(HolderNorms::getNormsId), MybatisPlusUtil.toColumns(HolderNorms::getAllOperNumber)); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(HolderNorms::getNormsId)); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + return beans; + } + + @Override + public void queryHolderMaterialListByHolder(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String holderId = map.get("holderId").toString(); + String holderKey = map.get("holderKey").toString(); + if (StrUtil.isEmpty(holderId) || StrUtil.isEmpty(holderKey)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderId), holderId); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderKey), holderKey); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(HolderNorms::getMaterialId)); + List holderNormsList = list(queryWrapper); + // 设置产品信息 + materialService.setDataMation(holderNormsList, HolderNorms::getMaterialId); + holderNormsList.forEach(holderNorms -> { + holderNorms.setId(holderNorms.getMaterialId()); + if (ObjectUtil.isNotEmpty(holderNorms.getMaterialMation())) { + holderNorms.setName(holderNorms.getMaterialMation().getName()); + } + }); + outputObject.setBeans(holderNormsList); + outputObject.settotal(holderNormsList.size()); + } + + @Override + public void writePostpose(List entity, String userId) { + // 构造并保存购买或者出售的商品的编码信息 + List holderNormsChildList = new ArrayList<>(); + entity.forEach(holderNorms -> { + if (CollectionUtil.isNotEmpty(holderNorms.getNormsCodeList())) { + holderNorms.getNormsCodeList().forEach(normsCode -> { + HolderNormsChild holderNormsChild = new HolderNormsChild(); + holderNormsChild.setNormsCodeNum(normsCode); + holderNormsChild.setState(HolderNormsChildState.NORMAL_TRANSACTIONS.getKey()); + holderNormsChild.setHolderId(holderNorms.getHolderId()); + holderNormsChild.setHolderKey(holderNorms.getHolderKey()); + holderNormsChild.setMaterialId(holderNorms.getId()); + holderNormsChild.setNormsId(holderNorms.getNormsId()); + holderNormsChild.setParentId(holderNorms.getId()); + holderNormsChildList.add(holderNormsChild); + }); + } + }); + if (CollectionUtil.isNotEmpty(holderNormsChildList)) { + holderNormsChildService.createEntity(holderNormsChildList, StrUtil.EMPTY); + } + } + + @Override + public List queryHolderMaterialIdListByHolderId(String holderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderId), holderId); + List holderNormsList = list(queryWrapper); + if (CollectionUtil.isEmpty(holderNormsList)) { + return CollectionUtil.newArrayList(); + } + return holderNormsList.stream().map(HolderNorms::getId).collect(Collectors.toList()); + } + + @Override + public void queryHolderMaterialNormsListByHolder(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String holderId = map.get("holderId").toString(); + String holderKey = map.get("holderKey").toString(); + String materialId = map.get("materialId").toString(); + if (StrUtil.isEmpty(holderId) || StrUtil.isEmpty(holderKey) || StrUtil.isEmpty(materialId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderId), holderId); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getHolderKey), holderKey); + queryWrapper.eq(MybatisPlusUtil.toColumns(HolderNorms::getMaterialId), materialId); + + queryWrapper.groupBy(MybatisPlusUtil.toColumns(HolderNorms::getNormsId)); + List holderNormsList = list(queryWrapper); + // 设置规格信息 + materialNormsService.setDataMation(holderNormsList, HolderNorms::getNormsId); + holderNormsList.forEach(holderNorms -> { + holderNorms.setId(holderNorms.getNormsId()); + if (ObjectUtil.isNotEmpty(holderNorms.getNormsMation())) { + holderNorms.setName(holderNorms.getNormsMation().getName()); + } + }); + outputObject.setBeans(holderNormsList); + outputObject.settotal(holderNormsList.size()); + } + + @Override + public void queryHolderMaterialNormsCodeListByHolder(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String holderId = map.get("holderId").toString(); + String holderKey = map.get("holderKey").toString(); + String normsId = map.get("normsId").toString(); + if (StrUtil.isEmpty(holderId) || StrUtil.isEmpty(holderKey) || StrUtil.isEmpty(normsId)) { + return; + } + List> beans = holderNormsChildService.queryHolderMaterialNormsCodeListByHolder(holderId, holderKey, normsId); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionFromType.java new file mode 100644 index 0000000..dbb5b57 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionFromType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: QualityInspectionFromType + * @Description: 质检单单据来源枚举类,都是加载需要质检的单据信息 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum QualityInspectionFromType implements SkyeyeEnumClass { + + PURCHASE_DELIVERY(1, "到货单", true, true), + MACHIN_ORDER(2, "生产加工单", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionPutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionPutState.java new file mode 100644 index 0000000..6fa659e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionPutState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: QualityInspectionPutState + * @Description: 质检单入库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum QualityInspectionPutState implements SkyeyeEnumClass { + + NOT_NEED_PUT(1, "无需入库", true, true), + NEED_PUT(2, "待入库", true, false), + PARTIAL_PUT(3, "部分入库", true, false), + COMPLATE_PUT(4, "全部入库", true, false); + + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionReturnState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionReturnState.java new file mode 100644 index 0000000..a31d0df --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/classenum/QualityInspectionReturnState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: QualityInspectionReturnState + * @Description: 质检单退货状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum QualityInspectionReturnState implements SkyeyeEnumClass { + + NOT_NEED_RETURN(1, "无需退货", true, true), + NEED_RETURN(2, "待退货", true, false), + PARTIAL_RETURN(3, "部分退货", true, false), + COMPLATE_RETURN(4, "全部退货", true, false); + + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/controller/QualityInspectionController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/controller/QualityInspectionController.java new file mode 100644 index 0000000..cb15a84 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/controller/QualityInspectionController.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.inspection.service.QualityInspectionService; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: QualityInspectionController + * @Description: 质检单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "质检单", tags = "质检单", modelName = "质检单") +public class QualityInspectionController { + + @Autowired + private QualityInspectionService qualityInspectionService; + + /** + * 获取质检单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryQualityInspectionList", value = "获取质检单信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/QualityInspectionController/queryQualityInspectionList") + public void queryQualityInspectionList(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑质检单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeQualityInspection", value = "新增/编辑质检单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = QualityInspection.class) + @RequestMapping("/post/QualityInspectionController/writeQualityInspection") + public void writeQualityInspection(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 质检申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitQualityInspectionToApproval", value = "质检申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/QualityInspectionController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除质检申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteQualityInspection", value = "删除质检申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/deleteQualityInspection") + public void invalid(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.deleteById(inputObject, outputObject); + } + + /** + * 撤销质检申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeQualityInspection", value = "撤销质检申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.revoke(inputObject, outputObject); + } + + /** + * 转采购入库单时,根据id查询质检单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryQualityInspectionTransById", value = "转采购入库单时,根据id查询质检单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/queryQualityInspectionTransById") + public void queryQualityInspectionTransById(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.queryQualityInspectionTransById(inputObject, outputObject); + } + + /** + * 质检单转采购入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "qualityInspectionToPurchasePut", value = "质检单转采购入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchasePut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/qualityInspectionToPurchasePut") + public void qualityInspectionToPurchasePut(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.qualityInspectionToPurchasePut(inputObject, outputObject); + } + + /** + * 转采购退货单时,根据id查询质检单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryQualityInspectionTransReturnById", value = "转采购退货单时,根据id查询质检单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/queryQualityInspectionTransReturnById") + public void queryQualityInspectionTransReturnById(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.queryQualityInspectionTransReturnById(inputObject, outputObject); + } + + /** + * 质检单转采购退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "qualityInspectionToPurchaseReturn", value = "质检单转采购退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/QualityInspectionController/qualityInspectionToPurchaseReturn") + public void qualityInspectionToPurchaseReturn(InputObject inputObject, OutputObject outputObject) { + qualityInspectionService.qualityInspectionToPurchaseReturn(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionDao.java new file mode 100644 index 0000000..fa2b293 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.inspection.entity.QualityInspection; + +/** + * @ClassName: QualityInspectionDao + * @Description: 质检单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QualityInspectionDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionItemDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionItemDao.java new file mode 100644 index 0000000..07616bb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/dao/QualityInspectionItemDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.inspection.entity.QualityInspectionItem; + +/** + * @ClassName: QualityInspectionItemDao + * @Description: 质检单子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 9:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QualityInspectionItemDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspection.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspection.java new file mode 100644 index 0000000..34d3537 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspection.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: QualityInspection + * @Description: 质检单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:qualityInspection", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "erp_quality_inspection") +@ApiModel("质检单实体类") +public class QualityInspection extends SkyeyeFlowable { + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#QualityInspectionFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("department_id") + @ApiModelProperty(value = "检验部门") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("put_state") + @Property(value = "入库状态,参考#QualityInspectionPutState") + private Integer putState; + + @TableField("return_state") + @Property(value = "退货状态,参考#QualityInspectionReturnState") + private Integer returnState; + + @TableField(exist = false) + @ApiModelProperty(value = "质检单明细信息", required = "required,json") + private List qualityInspectionItemList; + + @TableField("holder_id") + @ApiModelProperty(value = "关联的客户/供应商/会员id", required = "required") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/供应商/会员信息") + private Map holderMation; + + @TableField("holder_key") + @ApiModelProperty(value = "关联的客户/供应商/会员的className") + private String holderKey; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspectionItem.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspectionItem.java new file mode 100644 index 0000000..dc35f7f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/entity/QualityInspectionItem.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: QualityInspectionItem + * @Description: 质检单子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_quality_inspection_child", autoResultMap = true) +@ApiModel("质检单子单据实体类") +public class QualityInspectionItem extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("quality_inspection") + @ApiModelProperty(value = "质检类型,参考#OrderItemQualityInspectionType", required = "num") + private Integer qualityInspection; + + @TableField(exist = false) + @Property(value = "质检类型信息") + private Map qualityInspectionMation; + + @TableField("quality_inspection_ratio") + @ApiModelProperty(value = "质检比例(%),质检类型为抽检时才生效") + private String qualityInspectionRatio; + + @TableField("oper_number") + @ApiModelProperty(value = "质检数量", required = "required,num") + private Integer operNumber; + + @TableField("qualified_number") + @ApiModelProperty(value = "合格数量", required = "required,num") + private Integer qualifiedNumber; + + @TableField("return_number") + @ApiModelProperty(value = "验收退回数量", required = "required,num") + private Integer returnNumber; + + @TableField("return_reason") + @ApiModelProperty(value = "验收退回原因") + private String returnReason; + + @TableField("concession_number") + @ApiModelProperty(value = "让步接收数量", required = "required,num") + private Integer concessionNumber; + + @TableField(value = "inspector_id") + @ApiModelProperty(value = "质检员id") + private String inspectorId; + + @TableField(exist = false) + @Property(value = "质检员信息") + private Map inspectorMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionItemService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionItemService.java new file mode 100644 index 0000000..171a761 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionItemService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.inspection.entity.QualityInspectionItem; + +import java.util.List; + +/** + * @ClassName: QualityInspectionItemService + * @Description: 质检单子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 9:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QualityInspectionItemService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + List selectByParentId(List parentId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionService.java new file mode 100644 index 0000000..fe358fd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/QualityInspectionService.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inspection.entity.QualityInspection; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: QualityInspectionService + * @Description: 质检单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface QualityInspectionService extends SkyeyeFlowableService { + + Map calcMaterialNormsNumByFromId(String... fromId); + + /** + * 修改入库状态 + * + * @param id 质检单id + * @param putState 入库状态 {@link com.skyeye.inspection.classenum.QualityInspectionPutState} + */ + void editPutState(String id, Integer putState); + + /** + * 修改退货状态 + * + * @param id 质检单id + * @param returnState 退货状态 {@link com.skyeye.inspection.classenum.QualityInspectionReturnState} + */ + void editReturnState(String id, Integer returnState); + + void setQualityInspectionMationByFromId(List> beans, String idKey, String mationKey); + + void queryQualityInspectionTransById(InputObject inputObject, OutputObject outputObject); + + void qualityInspectionToPurchasePut(InputObject inputObject, OutputObject outputObject); + + void queryQualityInspectionTransReturnById(InputObject inputObject, OutputObject outputObject); + + void qualityInspectionToPurchaseReturn(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionItemServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionItemServiceImpl.java new file mode 100644 index 0000000..d975efb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionItemServiceImpl.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.inspection.dao.QualityInspectionItemDao; +import com.skyeye.inspection.entity.QualityInspectionItem; +import com.skyeye.inspection.service.QualityInspectionItemService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: QualityInspectionItemServiceImpl + * @Description: 质检单子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 9:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "质检单子单据", groupName = "质检单", manageShow = false) +public class QualityInspectionItemServiceImpl extends SkyeyeBusinessServiceImpl implements QualityInspectionItemService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (QualityInspectionItem qualityInspectionItem : beans) { + qualityInspectionItem.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(QualityInspectionItem::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(QualityInspectionItem::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public List selectByParentId(List parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(QualityInspectionItem::getParentId), parentId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionServiceImpl.java new file mode 100644 index 0000000..35f4327 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inspection/service/impl/QualityInspectionServiceImpl.java @@ -0,0 +1,429 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inspection.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.classenum.OrderQualityInspectionType; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.inspection.classenum.QualityInspectionFromType; +import com.skyeye.inspection.classenum.QualityInspectionPutState; +import com.skyeye.inspection.classenum.QualityInspectionReturnState; +import com.skyeye.inspection.dao.QualityInspectionDao; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.inspection.entity.QualityInspectionItem; +import com.skyeye.inspection.service.QualityInspectionItemService; +import com.skyeye.inspection.service.QualityInspectionService; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.purchase.classenum.PurchasePutFromType; +import com.skyeye.purchase.classenum.PurchaseReturnsFromType; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.supplier.service.SupplierService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: QualityInspectionServiceImpl + * @Description: 质检单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 8:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "质检单", groupName = "质检单", flowable = true) +public class QualityInspectionServiceImpl extends SkyeyeFlowableServiceImpl implements QualityInspectionService { + + @Autowired + private QualityInspectionItemService qualityInspectionItemService; + + @Autowired + private MaterialService materialService; + + @Autowired + private ErpDepotService erpDepotService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private PurchaseDeliveryService purchaseDeliveryService; + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private SupplierService supplierService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(QualityInspection::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(QualityInspection::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + purchaseDeliveryService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(QualityInspection entity) { + checkOrderItem(entity); + checkMaterialNorms(entity, false); + } + + @Override + public void writeChild(QualityInspection entity, String userId) { + qualityInspectionItemService.saveList(entity.getId(), entity.getQualityInspectionItemList()); + super.writeChild(entity, userId); + } + + private void checkOrderItem(QualityInspection entity) { + Integer putState = QualityInspectionPutState.NOT_NEED_PUT.getKey(); + Integer returnState = QualityInspectionReturnState.NOT_NEED_RETURN.getKey(); + + if (CollectionUtil.isEmpty(entity.getQualityInspectionItemList())) { + throw new CustomException("请最少选择一条产品信息"); + } + List normsIds = entity.getQualityInspectionItemList().stream().map(QualityInspectionItem::getNormsId).distinct().collect(Collectors.toList()); + if (entity.getQualityInspectionItemList().size() != normsIds.size()) { + throw new CustomException("单据中不允许存在重复的产品规格信息"); + } + + for (QualityInspectionItem qualityInspectionItem : entity.getQualityInspectionItemList()) { + // 实际验收总数量 = 合格数量 + 验收退回数量 + 让步接收数量 + int tempNum = qualityInspectionItem.getQualifiedNumber() + qualityInspectionItem.getReturnNumber() + qualityInspectionItem.getConcessionNumber(); + if (qualityInspectionItem.getQualityInspection() == OrderItemQualityInspectionType.FULL_INSPECTION.getKey()) { + // 全检 + // 质检数量 != 实际验收总数量 + if (qualityInspectionItem.getOperNumber() != tempNum) { + throw new CustomException("验收数量不等于【合格数量】 + 【验收退回数量】 + 【让步接收数量】,请确认."); + } + } else if (qualityInspectionItem.getQualityInspection() == OrderItemQualityInspectionType.SAMPLING_INS.getKey()) { + // 抽检 + // 计算抽检比例 + String samplingRatio = CalculationUtil.divide(qualityInspectionItem.getQualityInspectionRatio(), "100", CommonNumConstants.NUM_TWO); + // 计算需要抽检的数量 + int samplingNum = Integer.parseInt( + CalculationUtil.multiply(CommonNumConstants.NUM_ZERO, samplingRatio, String.valueOf(qualityInspectionItem.getOperNumber()))); + // 实际验收总数量 < 需要抽检的数量 + if (tempNum < samplingNum) { + throw new CustomException("抽检数量不足,请确认."); + } + } + + // 设置入库状态 + if (qualityInspectionItem.getQualifiedNumber() > 0 || qualityInspectionItem.getConcessionNumber() > 0) { + putState = QualityInspectionPutState.NEED_PUT.getKey(); + } + // 设置退货状态 + if (qualityInspectionItem.getReturnNumber() > 0) { + returnState = QualityInspectionReturnState.NEED_RETURN.getKey(); + } + } + entity.setPutState(putState); + entity.setReturnState(returnState); + } + + private void checkMaterialNorms(QualityInspection entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前质检单的商品数量 + Map orderNormsNum = entity.getQualityInspectionItemList().stream() + .collect(Collectors.toMap(QualityInspectionItem::getNormsId, QualityInspectionItem::getOperNumber)); + // 获取同一个来源单据下已经质检(审批通过)的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == QualityInspectionFromType.PURCHASE_DELIVERY.getKey()) { + // 到货单 + PurchaseDelivery purchaseDelivery = purchaseDeliveryService.selectById(entity.getFromId()); + // 过滤掉到货单中免检的商品 + List erpOrderItemList = purchaseDelivery.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() != OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + throw new CustomException("该到货单下未包含需要质检的商品."); + } + List fromNormsIds = erpOrderItemList.stream() + .map(ErpOrderItem::getNormsId).collect(Collectors.toList()); + // 求差集(到货单不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该到货单下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = erpOrderItem.getOperNumber() + - (orderNormsNum.containsKey(erpOrderItem.getNormsId()) ? orderNormsNum.get(erpOrderItem.getNormsId()) : 0) + - (executeNum.containsKey(erpOrderItem.getNormsId()) ? executeNum.get(erpOrderItem.getNormsId()) : 0); + if (surplusNum < 0) { + throw new CustomException("超出到货单的商品数量."); + } + if (setData) { + erpOrderItem.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + erpOrderItemList = erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 该到货单的商品已经全部进行了质检 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseDeliveryService.editQualityInspection(purchaseDelivery.getId(), OrderQualityInspectionType.COMPLATE_QUALITY_INSPECTION.getKey()); + } else { + purchaseDeliveryService.editQualityInspection(purchaseDelivery.getId(), OrderQualityInspectionType.PARTIAL_QUALITY_INSPECTION.getKey()); + } + } + } + } + + @Override + public QualityInspection getDataFromDb(String id) { + QualityInspection qualityInspection = super.getDataFromDb(id); + List qualityInspectionItemList = qualityInspectionItemService.selectByParentId(qualityInspection.getId()); + qualityInspection.setQualityInspectionItemList(qualityInspectionItemList); + return qualityInspection; + } + + @Override + public QualityInspection selectById(String id) { + QualityInspection qualityInspection = super.selectById(id); + // 设置产品信息 + materialService.setDataMation(qualityInspection.getQualityInspectionItemList(), QualityInspectionItem::getMaterialId); + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + MaterialNorms norms = qualityInspectionItem.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(qualityInspectionItem.getNormsId(), bean.getId())).findFirst().orElse(null); + qualityInspectionItem.setNormsMation(norms); + }); + // 仓库信息 + erpDepotService.setDataMation(qualityInspection.getQualityInspectionItemList(), QualityInspectionItem::getDepotId); + // 质检部门 + iDepmentService.setDataMation(qualityInspection, QualityInspection::getDepartmentId); + // 质检员信息 + iAuthUserService.setDataMation(qualityInspection.getQualityInspectionItemList(), QualityInspectionItem::getInspectorId); + if (qualityInspection.getFromTypeId() == QualityInspectionFromType.PURCHASE_DELIVERY.getKey()) { + // 到货单 + purchaseDeliveryService.setDataMation(qualityInspection, QualityInspection::getFromId); + } else if (qualityInspection.getFromTypeId() == QualityInspectionFromType.MACHIN_ORDER.getKey()) { + // 生产加工单 + } + + // 供应商 + supplierService.setDataMation(qualityInspection, QualityInspection::getHolderId); + + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + qualityInspectionItem.setQualityInspectionMation(OrderItemQualityInspectionType.getMation(qualityInspectionItem.getQualityInspection())); + }); + return qualityInspection; + } + + @Override + public void approvalEndIsSuccess(QualityInspection entity) { + entity = selectById(entity.getId()); + // 修改来源单据的质检信息 + checkMaterialNorms(entity, true); + } + + @Override + public Map calcMaterialNormsNumByFromId(String... fromId) { + List fromIdList = Arrays.asList(fromId); + if (CollectionUtil.isEmpty(fromIdList)) { + return cn.hutool.core.map.MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(QualityInspection::getFromId), fromIdList); + // 只查询审批通过的质检单 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(QualityInspection::getState), stateList); + List qualityInspectionList = list(queryWrapper); + List ids = qualityInspectionList.stream().map(QualityInspection::getId).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + // 获取所有的商品信息 + List qualityInspectionItemList = qualityInspectionItemService.selectByParentId(ids); + if (CollectionUtil.isNotEmpty(qualityInspectionItemList)) { + // 分组计算已经质检的数量 + return qualityInspectionItemList.stream() + .collect(Collectors.groupingBy(QualityInspectionItem::getNormsId, Collectors.summingInt(QualityInspectionItem::getOperNumber))); + } + return cn.hutool.core.map.MapUtil.newHashMap(); + } + + @Override + public void editPutState(String id, Integer putState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(QualityInspection::getPutState), putState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void editReturnState(String id, Integer returnState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(QualityInspection::getReturnState), returnState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void setQualityInspectionMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List qualityInspectionList = list(queryWrapper); + Map qualityInspectionMap = qualityInspectionList.stream() + .collect(Collectors.toMap(QualityInspection::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + QualityInspection entity = qualityInspectionMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + @Override + public void queryQualityInspectionTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + QualityInspection qualityInspection = selectById(id); + Map normsNum = purchasePutService.calcMaterialNormsNumByFromId(id); + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + Integer surplusNum = qualityInspectionItem.getQualifiedNumber() + qualityInspectionItem.getConcessionNumber() + - (normsNum.containsKey(qualityInspectionItem.getNormsId()) ? normsNum.get(qualityInspectionItem.getNormsId()) : 0); + // 设置未下达采购入库单的商品数量 + qualityInspectionItem.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成采购入库单 + qualityInspection.setQualityInspectionItemList(qualityInspection.getQualityInspectionItemList().stream() + .filter(qualityInspectionItem -> qualityInspectionItem.getOperNumber() > 0).collect(Collectors.toList())); + // 供应商 + supplierService.setDataMation(qualityInspection, QualityInspection::getHolderId); + outputObject.setBean(qualityInspection); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void qualityInspectionToPurchasePut(InputObject inputObject, OutputObject outputObject) { + PurchasePut purchasePut = inputObject.getParams(PurchasePut.class); + // 获取质检单状态 + QualityInspection qualityInspection = selectById(purchasePut.getId()); + if (ObjectUtil.isEmpty(qualityInspection)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以进行采购入库单 + if (FlowableStateEnum.PASS.getKey().equals(qualityInspection.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + purchasePut.setFromId(purchasePut.getId()); + purchasePut.setFromTypeId(PurchasePutFromType.QUALITY_INSPECTION.getKey()); + purchasePut.setId(StrUtil.EMPTY); + purchasePutService.createEntity(purchasePut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达质检单."); + } + } + + @Override + public void queryQualityInspectionTransReturnById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + QualityInspection qualityInspection = selectById(id); + Map normsNum = purchaseReturnsService.calcMaterialNormsNumByFromId(id); + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + // 退还数量 - 已退货数量 + Integer surplusNum = qualityInspectionItem.getReturnNumber() + - (normsNum.containsKey(qualityInspectionItem.getNormsId()) ? normsNum.get(qualityInspectionItem.getNormsId()) : 0); + // 设置未下达采购退货单的商品数量 + qualityInspectionItem.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成采购退货单 + qualityInspection.setQualityInspectionItemList(qualityInspection.getQualityInspectionItemList().stream() + .filter(qualityInspectionItem -> qualityInspectionItem.getOperNumber() > 0).collect(Collectors.toList())); + // 供应商 + supplierService.setDataMation(qualityInspection, QualityInspection::getHolderId); + outputObject.setBean(qualityInspection); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void qualityInspectionToPurchaseReturn(InputObject inputObject, OutputObject outputObject) { + PurchaseReturn purchaseReturn = inputObject.getParams(PurchaseReturn.class); + // 获取质检单状态 + QualityInspection qualityInspection = selectById(purchaseReturn.getId()); + if (ObjectUtil.isEmpty(qualityInspection)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以进行采购退货单 + if (FlowableStateEnum.PASS.getKey().equals(qualityInspection.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + purchaseReturn.setFromId(purchaseReturn.getId()); + purchaseReturn.setFromTypeId(PurchaseReturnsFromType.QUALITY_INSPECTION.getKey()); + purchaseReturn.setId(StrUtil.EMPTY); + purchaseReturnsService.createEntity(purchaseReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达质检单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/classenum/InventoryChildState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/classenum/InventoryChildState.java new file mode 100644 index 0000000..9700e0f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/classenum/InventoryChildState.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: InventoryChildState + * @Description: 盘点任务表-子单据表状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 22:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum InventoryChildState implements SkyeyeEnumClass { + + COMPLATE("complate", "盘点完成", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableChildStateEnum.class); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildCodeController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildCodeController.java new file mode 100644 index 0000000..da374ac --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildCodeController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inventory.service.InventoryChildCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InventoryChildCodeController + * @Description: 盘点任务表-子单据关联的编码控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 17:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "盘点任务表-子单据关联的编码", tags = "盘点任务表-子单据关联的编码", modelName = "盘点任务单") +public class InventoryChildCodeController { + + @Autowired + private InventoryChildCodeService inventoryChildCodeService; + + /** + * 获取盘点任务子单据下的编码信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInventoryChildCodeList", value = "获取盘点任务子单据下的编码信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InventoryChildCodeController/queryInventoryChildCodeList") + public void queryInventoryChildCodeList(InputObject inputObject, OutputObject outputObject) { + inventoryChildCodeService.queryPageList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildController.java new file mode 100644 index 0000000..eeeaf93 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryChildController.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inventory.service.InventoryChildService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InventoryChildController + * @Description: 盘点任务表-子单据控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 16:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "盘点任务表-子单据", tags = "盘点任务表-子单据", modelName = "盘点任务单") +public class InventoryChildController { + + @Autowired + private InventoryChildService inventoryChildService; + + /** + * 获取我的盘点任务信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInventoryChildList", value = "获取我的盘点任务信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InventoryChildController/queryInventoryChildList") + public void queryInventoryChildList(InputObject inputObject, OutputObject outputObject) { + inventoryChildService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id查询盘点任务子单据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInventoryChildById", value = "根据id查询盘点任务子单据信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InventoryChildController/queryInventoryChildById") + public void queryInventoryChildById(InputObject inputObject, OutputObject outputObject) { + inventoryChildService.selectById(inputObject, outputObject); + } + + /** + * 盘点完成 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "complateInventoryChild", value = "盘点完成", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "realNumber", name = "realNumber", value = "实际盘点数量(实盘后的数量)", required = "required,num"), + @ApiImplicitParam(id = "profitNum", name = "profitNum", value = "盘盈数量", required = "required,num"), + @ApiImplicitParam(id = "lossNum", name = "lossNum", value = "盘亏数量", required = "required,num"), + @ApiImplicitParam(id = "profitNormsCode", name = "profitNormsCode", value = "盘盈明细的商品规格条形码编号"), + @ApiImplicitParam(id = "lossNormsCode", name = "lossNormsCode", value = "盘亏明细的商品规格条形码编号")}) + @RequestMapping("/post/InventoryChildController/complateInventoryChild") + public void complateInventoryChild(InputObject inputObject, OutputObject outputObject) { + inventoryChildService.complateInventoryChild(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryController.java new file mode 100644 index 0000000..017822c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/controller/InventoryController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inventory.entity.Inventory; +import com.skyeye.inventory.service.InventoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: InventoryController + * @Description: 盘点任务单据控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 15:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "盘点任务单", tags = "盘点任务单", modelName = "盘点任务单") +public class InventoryController { + + @Autowired + private InventoryService inventoryService; + + /** + * 获取盘点任务单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryInventoryList", value = "获取盘点任务单信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InventoryController/queryInventoryList") + public void queryInventoryList(InputObject inputObject, OutputObject outputObject) { + inventoryService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑盘点任务单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeInventory", value = "新增/编辑盘点任务单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Inventory.class) + @RequestMapping("/post/InventoryController/writeInventory") + public void writeInventory(InputObject inputObject, OutputObject outputObject) { + inventoryService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 质检申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitInventoryToApproval", value = "质检申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/InventoryController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + inventoryService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除质检申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteInventory", value = "删除质检申请", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InventoryController/deleteInventory") + public void invalid(InputObject inputObject, OutputObject outputObject) { + inventoryService.deleteById(inputObject, outputObject); + } + + /** + * 撤销质检申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeInventory", value = "撤销质检申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/InventoryController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + inventoryService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildCodeDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildCodeDao.java new file mode 100644 index 0000000..885e62c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.inventory.entity.InventoryChildCode; + +/** + * @ClassName: InventoryChildCodeDao + * @Description: 盘点任务表-子单据关联的编码数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 17:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryChildCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildDao.java new file mode 100644 index 0000000..be0db0f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.inventory.entity.InventoryChild; + +/** + * @ClassName: InventoryChildDao + * @Description: 盘点任务表-子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 16:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryDao.java new file mode 100644 index 0000000..882f670 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/dao/InventoryDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.inventory.entity.Inventory; + +/** + * @ClassName: InventoryDao + * @Description: 盘点任务单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 15:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/Inventory.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/Inventory.java new file mode 100644 index 0000000..0ce83e4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/Inventory.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Inventory + * @Description: 盘点任务单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 15:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:inventory", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "erp_inventory") +@ApiModel("盘点任务单据实体类") +public class Inventory extends SkyeyeFlowable { + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_num") + @ApiModelProperty(value = "盘点总数量") + private Integer allNum; + + @TableField(value = "inventory_num") + @ApiModelProperty(value = "已盘点数量") + private Integer inventoryNum; + + @TableField(exist = false) + @ApiModelProperty(value = "盘点任务明细信息", required = "required,json") + private List inventoryChildList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChild.java new file mode 100644 index 0000000..cdc3ca7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChild.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: InventoryChild + * @Description: 盘点任务表-子单据表信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_inventory_child") +@ApiModel("盘点任务表-子单据表信息") +public class InventoryChild extends SkyeyeLinkData { + + @TableField("odd_number") + @Property(value = "单据编号", fuzzyLike = true) + private String oddNumber; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "operator_id") + @ApiModelProperty(value = "盘点人id", required = "required") + private String operatorId; + + @TableField(exist = false) + @Property(value = "盘点人信息") + private Map operatorMation; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "plan_start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String planStartTime; + + @TableField(value = "plan_end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String planEndTime; + + @TableField(value = "plan_number") + @Property(value = "计划盘点数量(账面数量)") + private Integer planNumber; + + @TableField(value = "real_number") + @Property(value = "实际盘点数量(实盘后的数量)") + private Integer realNumber; + + @TableField(value = "profit_num") + @Property(value = "盘盈数量") + private Integer profitNum; + + @TableField(value = "loss_num") + @Property(value = "盘亏数量") + private Integer lossNum; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "profit_price") + @Property(value = "盘盈总金额") + private String profitPrice; + + @TableField(value = "loss_price") + @Property(value = "盘亏总金额") + private String lossPrice; + + @TableField(value = "type") + @ApiModelProperty(value = "盘点的商品的类型,参考#MaterialNormsCodeType") + private Integer type; + + @TableField(exist = false) + @Property(value = "盘点的商品的类型信息") + private Map typeMation; + + @TableField(exist = false) + @Property(value = "子单据关联的编码") + private List inventoryChildCodeList; + + @TableField(value = "profit_norms_code") + @ApiModelProperty(value = "盘盈明细的商品规格条形码编号") + private String profitNormsCode; + + @TableField(value = "loss_norms_code") + @ApiModelProperty(value = "盘亏明细的商品规格条形码编号") + private String lossNormsCode; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChildCode.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChildCode.java new file mode 100644 index 0000000..e2c9693 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/entity/InventoryChildCode.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +/** + * @ClassName: InventoryChildCode + * @Description: 盘点任务表-子单据关联的编码实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 17:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_inventory_child_code") +@ApiModel("盘点任务表-子单据关联的编码实体类") +public class InventoryChildCode extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("order_id") + @Property("订单id") + private String orderId; + + @TableField("parent_id") + @Property("父节点id") + private String parentId; + + @TableField("material_id") + @Property(value = "产品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @Property(value = "规格物品编码", fuzzyLike = true) + private String codeNum; + + @TableField(value = "in_depot") + @Property(value = "库存状态,参考#MaterialNormsCodeInDepot") + private Integer inDepot; + + @TableField(value = "type") + @Property(value = "类型,参考#MaterialNormsCodeType") + private Integer type; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildCodeService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildCodeService.java new file mode 100644 index 0000000..c4f3789 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildCodeService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.inventory.entity.InventoryChildCode; + +import java.util.List; + +/** + * @ClassName: InventoryChildCodeService + * @Description: 盘点任务表-子单据关联的编码服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 17:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryChildCodeService extends SkyeyeBusinessService { + + void saveList(String orderId, List beans); + + void deleteByOrderId(String orderId); + + List selectByOrderId(String... orderId); + + List selectByParentId(String... parentId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildService.java new file mode 100644 index 0000000..dd3a1aa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryChildService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inventory.entity.InventoryChild; + +import java.util.List; + +/** + * @ClassName: InventoryChildService + * @Description: 盘点任务表-子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 16:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryChildService extends SkyeyeLinkDataService { + + Integer calcAllPlanInventoryNum(List inventoryChildList); + + void complateInventoryChild(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryService.java new file mode 100644 index 0000000..11653f4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/InventoryService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.inventory.entity.Inventory; + +/** + * @ClassName: InventoryService + * @Description: 盘点任务单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 15:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface InventoryService extends SkyeyeFlowableService { + + /** + * 设置已盘点数量 + * + * @param id 盘点单据id + * @param addNum 新增的盘点数量 + */ + void setInventoriedNum(String id, Integer addNum); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildCodeServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildCodeServiceImpl.java new file mode 100644 index 0000000..d70d961 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildCodeServiceImpl.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.inventory.dao.InventoryChildCodeDao; +import com.skyeye.inventory.entity.InventoryChildCode; +import com.skyeye.inventory.service.InventoryChildCodeService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: InventoryChildCodeServiceImpl + * @Description: 盘点任务表-子单据关联的编码服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 17:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "盘点任务表-子单据关联的编码", groupName = "盘点任务单") +public class InventoryChildCodeServiceImpl extends SkyeyeBusinessServiceImpl implements InventoryChildCodeService { + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotBlank(commonPageInfo.getObjectId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(InventoryChildCode::getParentId), commonPageInfo.getObjectId()); + } + return queryWrapper; + } + + @Override + public void saveList(String orderId, List beans) { + deleteByOrderId(orderId); + if (CollectionUtil.isNotEmpty(beans)) { + for (InventoryChildCode inventoryChildCode : beans) { + inventoryChildCode.setOrderId(orderId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(InventoryChildCode::getOrderId), orderId); + remove(queryWrapper); + } + + @Override + public List selectByOrderId(String... orderId) { + List orderIdList = Arrays.asList(orderId); + if (CollectionUtil.isEmpty(orderIdList)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(InventoryChildCode::getOrderId), orderIdList); + List list = list(queryWrapper); + return list; + } + + @Override + public List selectByParentId(String... parentId) { + List parentIds = Arrays.asList(parentId); + if (CollectionUtil.isEmpty(parentIds)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(InventoryChildCode::getParentId), parentIds); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildServiceImpl.java new file mode 100644 index 0000000..5b9ecf6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryChildServiceImpl.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.exception.CustomException; +import com.skyeye.inventory.classenum.InventoryChildState; +import com.skyeye.inventory.dao.InventoryChildDao; +import com.skyeye.inventory.entity.InventoryChild; +import com.skyeye.inventory.entity.InventoryChildCode; +import com.skyeye.inventory.service.InventoryChildCodeService; +import com.skyeye.inventory.service.InventoryChildService; +import com.skyeye.inventory.service.InventoryService; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.classenum.MaterialNormsCodeType; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.service.ErpCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: InventoryChildServiceImpl + * @Description: 盘点任务表-子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 16:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "盘点任务表-子单据", groupName = "盘点任务单") +public class InventoryChildServiceImpl extends SkyeyeLinkDataServiceImpl implements InventoryChildService { + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private MaterialNormsCodeService materialNormsCodeService; + + @Autowired + private InventoryChildCodeService inventoryChildCodeService; + + @Autowired + protected MaterialService materialService; + + @Autowired + private ErpCommonService erpCommonService; + + @Autowired + private InventoryService inventoryService; + + @Autowired + private ErpDepotService erpDepotService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(InventoryChild::getOperatorId), userId); + List stateList = Arrays.asList(FlowableChildStateEnum.ADEQUATE.getKey(), InventoryChildState.COMPLATE.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(InventoryChild::getState), stateList); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + erpDepotService.setMationForMap(beans, "depotId", "depotMation"); + beans.forEach(bean -> { + Integer type = Integer.parseInt(bean.get("type").toString()); + bean.put("typeMation", MaterialNormsCodeType.getMation(type)); + }); + return beans; + } + + @Override + public InventoryChild selectById(String id) { + InventoryChild inventoryChild = super.selectById(id); + materialService.setDataMation(inventoryChild, InventoryChild::getMaterialId); + materialNormsService.setDataMation(inventoryChild, InventoryChild::getNormsId); + erpDepotService.setDataMation(inventoryChild, InventoryChild::getDepotId); + inventoryChild.setTypeMation(MaterialNormsCodeType.getMation(inventoryChild.getType())); + return inventoryChild; + } + + @Override + public Integer calcAllPlanInventoryNum(List inventoryChildList) { + Integer allPlanInventoryNum = 0; + for (InventoryChild inventoryChild : inventoryChildList) { + // 查询规格库存信息 + MaterialNorms materialNorms = materialNormsService.queryMaterialNorms(inventoryChild.getNormsId(), inventoryChild.getDepotId()); + int depotAllStock = ObjectUtil.isNotEmpty(materialNorms.getDepotTock()) ? materialNorms.getDepotTock().getAllStock() : CommonNumConstants.NUM_ZERO; + inventoryChild.setPlanNumber(depotAllStock); + inventoryChild.setRealNumber(CommonNumConstants.NUM_ZERO); + inventoryChild.setProfitNum(CommonNumConstants.NUM_ZERO); + inventoryChild.setLossNum(CommonNumConstants.NUM_ZERO); + inventoryChild.setProfitPrice(CommonNumConstants.NUM_ZERO.toString()); + inventoryChild.setLossPrice(CommonNumConstants.NUM_ZERO.toString()); + + allPlanInventoryNum += depotAllStock; + } + return allPlanInventoryNum; + } + + @Override + public void saveLinkList(String pId, List beans) { + beans.forEach(bean -> { + String oddNumber = iCodeRuleService.getNextCodeByClassName(getServiceClassName(), BeanUtil.beanToMap(bean)); + bean.setOddNumber(oddNumber); + }); + super.saveLinkList(pId, beans); + List inventoryChildCodeList = new ArrayList<>(); + for (InventoryChild inventoryChild : beans) { + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCode(inventoryChild.getDepotId(), + inventoryChild.getNormsId(), inventoryChild.getType(), MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + for (MaterialNormsCode materialNormsCode : materialNormsCodeList) { + InventoryChildCode inventoryChildCode = new InventoryChildCode(); + inventoryChildCode.setCodeNum(materialNormsCode.getCodeNum()); + inventoryChildCode.setParentId(inventoryChild.getId()); + inventoryChildCode.setType(materialNormsCode.getType()); + inventoryChildCode.setInDepot(MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + inventoryChildCode.setOrderId(pId); + inventoryChildCode.setMaterialId(inventoryChild.getMaterialId()); + inventoryChildCode.setNormsId(inventoryChild.getNormsId()); + inventoryChildCodeList.add(inventoryChildCode); + } + } + inventoryChildCodeService.saveList(pId, inventoryChildCodeList); + } + + @Override + public void complateInventoryChild(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + Integer realNumber = Integer.parseInt(params.get("realNumber").toString()); + String profitNormsCode = params.get("profitNormsCode").toString(); + String lossNormsCode = params.get("lossNormsCode").toString(); + // 盘盈信息 + Integer profitNum = Integer.parseInt(params.get("profitNum").toString()); + List profitNormsCodeList = Arrays.asList(profitNormsCode.split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + // 盘亏信息 + Integer lossNum = Integer.parseInt(params.get("lossNum").toString()); + List lossNormsCodeList = Arrays.asList(lossNormsCode.split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + // 查询盘点子单据 + InventoryChild inventoryChild = selectById(id); + + // 校验盘点数量 计划数量 + 盘盈数量 - 盘亏数量 + Integer checkNumber = inventoryChild.getPlanNumber() + profitNum - lossNum; + if (realNumber.compareTo(checkNumber) != 0) { + throw new CustomException("盘点后数量错误,须遵守计划数量 + 盘盈数量 - 盘亏数量 = 实际盘点数量,请确认"); + } + + Material material = materialService.selectById(inventoryChild.getMaterialId()); + MaterialNorms norms = materialNormsService.selectById(inventoryChild.getNormsId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 单品盘点 + if (profitNum != profitNormsCodeList.size() && CommonNumConstants.NUM_ZERO.compareTo(profitNum) != 0) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的盘盈数量与明细数量不一致,请确认", material.getName(), norms.getName())); + } + if (lossNum != lossNormsCodeList.size() && CommonNumConstants.NUM_ZERO.compareTo(lossNum) != 0) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的盘亏数量与明细数量不一致,请确认", material.getName(), norms.getName())); + } + // 获取本次盘点的商品条形码 + List inventoryChildCodeList = inventoryChildCodeService.selectByParentId(inventoryChild.getId()); + List inventoryChildCodeNumList = inventoryChildCodeList.stream().map(InventoryChildCode::getCodeNum) + .distinct().collect(Collectors.toList()); + // 处理盘盈信息 + handleProfitNorms(profitNormsCodeList, inventoryChild, inventoryChildCodeNumList); + // 处理盘亏信息 + handleLossNorms(lossNormsCodeList, inventoryChild, inventoryChildCodeNumList); + } + + Integer changeNumber = realNumber - inventoryChild.getPlanNumber(); + if (changeNumber < 0) { + // 盘点数量减少,库存数量减少 + erpCommonService.editMaterialNormsDepotStock(inventoryChild.getDepotId(), inventoryChild.getMaterialId(), + inventoryChild.getNormsId(), changeNumber, DepotPutOutType.OUT.getKey()); + } else if (changeNumber > 0) { + // 盘点数量增加,库存数量增加 + erpCommonService.editMaterialNormsDepotStock(inventoryChild.getDepotId(), inventoryChild.getMaterialId(), + inventoryChild.getNormsId(), changeNumber, DepotPutOutType.PUT.getKey()); + } + + // 更新盘点子单据信息 + updateInventory(inventoryChild, realNumber, profitNum, lossNum, profitNormsCode, lossNormsCode); + } + + private void handleProfitNorms(List profitNormsCodeList, InventoryChild inventoryChild, List inventoryChildCodeNumList) { + if (CollectionUtil.isNotEmpty(profitNormsCodeList)) { + // 1. 和库存作对比 + // 从数据库查询未入库/入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, + profitNormsCodeList, MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey(), MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + List diffList = profitNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】已出库或者编码不存在,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和本次盘点的商品条形码作对比 + diffList = profitNormsCodeList.stream() + .filter(num -> !inventoryChildCodeNumList.contains(num)).collect(Collectors.toList()); + if (diffList.size() != profitNormsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】存在于本次盘点商品明细中,不属于盘盈类型,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 3. 更新库存状态 + String warehousingTime = DateUtil.getTimeAndToString(); + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setInDepot(MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + materialNormsCode.setDepotId(inventoryChild.getDepotId()); + materialNormsCode.setWarehousingTime(warehousingTime); + materialNormsCode.setFromObjectId(inventoryChild.getId()); + materialNormsCode.setFromObjectKey(getServiceClassName()); + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + + private void handleLossNorms(List lossNormsCodeList, InventoryChild inventoryChild, List inventoryChildCodeNumList) { + if (CollectionUtil.isNotEmpty(lossNormsCodeList)) { + // 1. 和库存作对比 + // 从数据库查询入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(inventoryChild.getDepotId(), + lossNormsCodeList, MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + List diffList = lossNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在该仓库中/未入库/已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和本次盘点的商品条形码作对比 + diffList = lossNormsCodeList.stream() + .filter(num -> !inventoryChildCodeNumList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在于本次盘点商品明细中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 3. 更新库存状态 + String outboundTime = DateUtil.getTimeAndToString(); + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setInDepot(MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCode.setOutboundTime(outboundTime); + materialNormsCode.setToObjectId(inventoryChild.getId()); + materialNormsCode.setToObjectKey(getServiceClassName()); + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + + private void updateInventory(InventoryChild inventoryChild, Integer realNumber, Integer profitNum, Integer lossNum, String profitNormsCode, String lossNormsCode) { + // 根据id查询盘点子单据并更新相关信息 + inventoryChild.setRealNumber(realNumber); + inventoryChild.setProfitNum(profitNum); + inventoryChild.setProfitNormsCode(profitNormsCode); + inventoryChild.setLossNum(lossNum); + inventoryChild.setLossNormsCode(lossNormsCode); + inventoryChild.setProfitPrice(CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(profitNum), inventoryChild.getUnitPrice())); + inventoryChild.setLossPrice(CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(lossNum), inventoryChild.getUnitPrice())); + inventoryChild.setState(InventoryChildState.COMPLATE.getKey()); + updateEntity(inventoryChild, StrUtil.EMPTY); + // 更新盘点任务单据的已盘点数量 + inventoryService.setInventoriedNum(inventoryChild.getParentId(), inventoryChild.getPlanNumber()); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryServiceImpl.java new file mode 100644 index 0000000..f9440cb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/inventory/service/impl/InventoryServiceImpl.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.inventory.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.exception.CustomException; +import com.skyeye.inventory.dao.InventoryDao; +import com.skyeye.inventory.entity.Inventory; +import com.skyeye.inventory.entity.InventoryChild; +import com.skyeye.inventory.service.InventoryChildCodeService; +import com.skyeye.inventory.service.InventoryChildService; +import com.skyeye.inventory.service.InventoryService; +import com.skyeye.material.classenum.MaterialNormsCodeType; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: InventoryServiceImpl + * @Description: 盘点任务单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/18 15:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "盘点任务单", groupName = "盘点任务单", flowable = true) +public class InventoryServiceImpl extends SkyeyeFlowableServiceImpl implements InventoryService { + + @Autowired + private InventoryChildService inventoryChildService; + + @Autowired + private InventoryChildCodeService inventoryChildCodeService; + + @Autowired + private MaterialService materialService; + + @Autowired + private ErpDepotService erpDepotService; + + @Override + protected void validatorEntity(Inventory entity) { + chectErpOrderItem(entity.getInventoryChildList()); + Integer allPlanInventoryNum = inventoryChildService.calcAllPlanInventoryNum(entity.getInventoryChildList()); + entity.setAllNum(allPlanInventoryNum); + entity.setInventoryNum(CommonNumConstants.NUM_ZERO); + } + + private void chectErpOrderItem(List inventoryChildList) { + if (CollectionUtil.isEmpty(inventoryChildList)) { + throw new CustomException("请最少选择一条产品信息"); + } + List normsIds = inventoryChildList.stream() + .map(bean -> String.format("%s_%s", bean.getDepotId(), bean.getNormsId())) + .distinct().collect(Collectors.toList()); + if (inventoryChildList.size() != normsIds.size()) { + throw new CustomException("单据中不允许存在重复仓库的产品规格信息"); + } + } + + @Override + public void writeChild(Inventory entity, String userId) { + // 删除关联的条形码数据 + inventoryChildCodeService.deleteByOrderId(entity.getId()); + // 保存子表数据 + inventoryChildService.saveLinkList(entity.getId(), entity.getInventoryChildList()); + super.writeChild(entity, userId); + } + + @Override + public Inventory getDataFromDb(String id) { + Inventory inventory = super.getDataFromDb(id); + List inventoryChildList = inventoryChildService.selectByPId(inventory.getId()); + inventory.setInventoryChildList(inventoryChildList); + return inventory; + } + + @Override + public Inventory selectById(String id) { + Inventory inventory = super.selectById(id); + // 设置产品信息 + materialService.setDataMation(inventory.getInventoryChildList(), InventoryChild::getMaterialId); + inventory.getInventoryChildList().forEach(inventoryChild -> { + MaterialNorms norms = inventoryChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(inventoryChild.getNormsId(), bean.getId())).findFirst().orElse(null); + inventoryChild.setNormsMation(norms); + inventoryChild.setTypeMation(MaterialNormsCodeType.getMation(inventoryChild.getType())); + }); + // 盘点人信息 + iAuthUserService.setDataMation(inventory.getInventoryChildList(), InventoryChild::getOperatorId); + // 仓库信息 + erpDepotService.setDataMation(inventory.getInventoryChildList(), InventoryChild::getDepotId); + return inventory; + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + inventoryChildService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public void revokePostpose(Inventory entity) { + super.revokePostpose(entity); + inventoryChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsFailed(Inventory entity) { + inventoryChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + @Override + public void approvalEndIsSuccess(Inventory entity) { + inventoryChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + public void deletePostpose(String id) { + // 删除子表数据 + inventoryChildService.deleteByPId(id); + // 删除关联的条形码数据 + inventoryChildCodeService.deleteByOrderId(id); + } + + @Override + public void setInventoriedNum(String id, Integer addNum) { + Inventory inventory = selectById(id); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Inventory::getInventoryNum), inventory.getInventoryNum() + addNum); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/job/impl/MaterialNormsGenerateCodeServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/job/impl/MaterialNormsGenerateCodeServiceImpl.java new file mode 100644 index 0000000..d43f26c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/job/impl/MaterialNormsGenerateCodeServiceImpl.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.job.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.eve.coderule.service.ICodeRuleService; +import com.skyeye.eve.rest.barcode.BarCodeMation; +import com.skyeye.eve.rest.barcode.BarCodeMationBox; +import com.skyeye.eve.service.IBarCodeService; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.MaterialService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +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 java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialNormsGenerateCodeServiceImpl + * @Description: 批量生成条形码的处理类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 8:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.material-norms-code-generate-barcode}", + consumerGroup = "${topic.material-norms-code-generate-barcode}", + selectorExpression = "${spring.profiles.active}") +public class MaterialNormsGenerateCodeServiceImpl implements RocketMQListener { + + private static Logger LOGGER = LoggerFactory.getLogger(MaterialNormsGenerateCodeServiceImpl.class); + + @Autowired + private IBarCodeService iBarCodeService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsCodeService materialNormsCodeService; + + @Autowired + private ICodeRuleService iCodeRuleService; + + @Value("${spring.application.name}") + private String springApplicationName; + + @Override + public void onMessage(String data) { + LOGGER.info("start material norms get Bar Code, data is {}", data); + Map map = JSONUtil.toBean(data, null); + List> list = JSONUtil.toList(map.get("list").toString(), null); + String className = map.get("className").toString(); + + List materialIdList = list.stream().map(bean -> bean.get("materialId").toString()).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + // 生成条形码的总数量 + Integer number = 0; + for (Map bean : list) { + String materialId = bean.get("materialId").toString(); + Material material = materialMap.get(materialId); + if (material.getItemCode() == MaterialItemCode.DISABLE.getKey()) { + continue; + } + number += Integer.parseInt(bean.get("operNumber").toString()); + } + if (number == 0) { + LOGGER.warn("material norms code number is Zero!!"); + return; + } + // 获取指定数量的编码 + List codeList = iCodeRuleService.getNextCodeByClassName(className, + MapUtil.newHashMap(), number); + if (CollectionUtil.isEmpty(codeList)) { + LOGGER.warn("codeList is Null"); + return; + } + // 保存条形码信息 + List materialNormsCodeList = new ArrayList<>(); + String createTime = DateUtil.getTimeAndToString(); + int startIndex = 0; + for (Map bean : list) { + String materialId = bean.get("materialId").toString(); + String normsId = bean.get("normsId").toString(); + Material material = materialMap.get(materialId); + if (material.getItemCode() == MaterialItemCode.DISABLE.getKey()) { + continue; + } + int operNumber = Integer.parseInt(bean.get("operNumber").toString()); + for (int i = startIndex; i < startIndex + operNumber; i++) { + MaterialNormsCode materialNormsCode = new MaterialNormsCode(); + materialNormsCode.setCodeNum(codeList.get(i)); + materialNormsCode.setMaterialId(materialId); + materialNormsCode.setNormsId(normsId); + materialNormsCode.setInDepot(MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey()); + materialNormsCode.setCreateTime(createTime); + materialNormsCodeList.add(materialNormsCode); + } + startIndex += operNumber; + } + materialNormsCodeService.createEntity(materialNormsCodeList, StrUtil.EMPTY); + + // 生成条形码logo + List barCodeMationList = new ArrayList<>(); + materialNormsCodeList.forEach(materialNormsCode -> { + String barCodePath = FileUtil.getImageBarCodePath(materialNormsCode.getCodeNum(), + FileConstants.FileUploadPath.ERP_MATERIAL_NORMS_CODE.getType()[0]); + BarCodeMation barCodeMation = new BarCodeMation(); + barCodeMation.setCodeNum(materialNormsCode.getCodeNum()); + barCodeMation.setObjectId(materialNormsCode.getId()); + barCodeMation.setImagePath(barCodePath); + barCodeMationList.add(barCodeMation); + }); + + BarCodeMationBox barCodeMationBox = new BarCodeMationBox(); + barCodeMationBox.setBarCodeList(barCodeMationList); + barCodeMationBox.setCodeImplClass(className); + barCodeMationBox.setSpringApplicationName(springApplicationName); + iBarCodeService.writeBarCode(barCodeMationBox); + + LOGGER.info("end material norms get Bar Code, data is {}", data); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinChildStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinChildStateEnum.java new file mode 100644 index 0000000..9ff913e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinChildStateEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MachinChildStateEnum + * @Description: 工序验收单状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinChildStateEnum implements SkyeyeEnumClass { + + WAIT_FOR_CHECKIG("waitForCheckig", "待验收", true, false), + CHECKIG_COMPLETED("checkigCompleted", "验收完成", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinFromType.java new file mode 100644 index 0000000..ffd0587 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MachinFromType + * @Description: 加工单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinFromType implements SkyeyeEnumClass { + + PRODUCTION(1, "生产计划", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPickStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPickStateEnum.java new file mode 100644 index 0000000..ff86b19 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPickStateEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MachinPickStateEnum + * @Description: 加工单领料状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinPickStateEnum implements SkyeyeEnumClass { + + NOT_PICKED("notPicked", "未领料", true, false), + PICKED("picked", "已领料", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPutFromType.java new file mode 100644 index 0000000..4f945b3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinPutFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MachinPutFromType + * @Description: 加工入库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinPutFromType implements SkyeyeEnumClass { + + FARM_TASK(1, "车间任务", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinStateEnum.java new file mode 100644 index 0000000..59b9d62 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/classenum/MachinStateEnum.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: MachinStateEnum + * @Description: 加工单状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinStateEnum implements SkyeyeEnumClass { + + COMPLETED("completed", "已完成", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinController.java new file mode 100644 index 0000000..6852565 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinController.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machin.entity.Machin; +import com.skyeye.machin.service.MachinService; +import com.skyeye.pick.entity.PatchMaterial; +import com.skyeye.pick.entity.RequisitionMaterial; +import com.skyeye.pick.entity.ReturnMaterial; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MachinController + * @Description: 加工单管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/12 18:34 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "加工单管理", tags = "加工单管理", modelName = "加工单管理") +public class MachinController { + + @Autowired + private MachinService machinService; + + /** + * 获取加工单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpmachin001", value = "获取加工单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MachinController/queryMachinOrderList") + public void queryMachinOrderList(InputObject inputObject, OutputObject outputObject) { + machinService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑加工单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMachin", value = "新增/编辑加工单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Machin.class) + @RequestMapping("/post/MachinController/writeMachin") + public void writeMachin(InputObject inputObject, OutputObject outputObject) { + machinService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询加工单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinById", value = "根据id查询加工单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "加工单id", required = "required")}) + @RequestMapping("/post/MachinController/queryMachinById") + public void queryMachinById(InputObject inputObject, OutputObject outputObject) { + machinService.selectById(inputObject, outputObject); + } + + /** + * 删除加工单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMachinById", value = "删除加工单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/deleteMachinById") + public void deleteMachinById(InputObject inputObject, OutputObject outputObject) { + machinService.deleteById(inputObject, outputObject); + } + + /** + * 加工单提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpmachin007", value = "提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/MachinController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + machinService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销加工单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeMachin", value = "撤销加工单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/MachinController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + machinService.revoke(inputObject, outputObject); + } + + /** + * 根据id查询加工单信息(甘特图) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinForGanttById", value = "根据id查询加工单信息(甘特图)", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "加工单id", required = "required")}) + @RequestMapping("/post/MachinController/queryMachinForGanttById") + public void queryMachinForGanttById(InputObject inputObject, OutputObject outputObject) { + machinService.queryMachinForGanttById(inputObject, outputObject); + } + + /** + * 转领料单/补料单时,根据id查询加工单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinTransRequestById", value = "转领料单/补料单时,根据id查询加工单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/queryMachinTransRequestById") + public void queryMachinTransRequestById(InputObject inputObject, OutputObject outputObject) { + machinService.queryMachinTransRequestById(inputObject, outputObject); + } + + /** + * 加工单信息转领料单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertMachinToPickRequest", value = "加工单信息转领料单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RequisitionMaterial.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/insertMachinToPickRequest") + public void insertMachinToPickRequest(InputObject inputObject, OutputObject outputObject) { + machinService.insertMachinToPickRequest(inputObject, outputObject); + } + + /** + * 加工单信息转补料单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertMachinToPickPatch", value = "加工单信息转补料单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PatchMaterial.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/insertMachinToPickPatch") + public void insertMachinToPickPatch(InputObject inputObject, OutputObject outputObject) { + machinService.insertMachinToPickPatch(inputObject, outputObject); + } + + /** + * 转退料单时,根据id查询加工单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinTransReturnById", value = "转退料单时,根据id查询加工单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/queryMachinTransReturnById") + public void queryMachinTransReturnById(InputObject inputObject, OutputObject outputObject) { + machinService.queryMachinTransReturnById(inputObject, outputObject); + } + + /** + * 加工单信息转退料单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertMachinToPickReturn", value = "加工单信息转退料单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReturnMaterial.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinController/insertMachinToPickReturn") + public void insertMachinToPickReturn(InputObject inputObject, OutputObject outputObject) { + machinService.insertMachinToPickReturn(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinPutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinPutController.java new file mode 100644 index 0000000..134b525 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/controller/MachinPutController.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.machin.entity.MachinPut; +import com.skyeye.machin.service.MachinPutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MachinPutController + * @Description: 加工入库单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 22:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "加工入库单", tags = "加工入库单", modelName = "加工单管理") +public class MachinPutController { + + @Autowired + private MachinPutService machinPutService; + + @ApiOperation(id = "queryMachinPutList", value = "获取加工入库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MachinPutController/queryMachinPutList") + public void queryMachinPutList(InputObject inputObject, OutputObject outputObject) { + machinPutService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeMachinPut", value = "新增/编辑加工入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = MachinPut.class) + @RequestMapping("/post/MachinPutController/writeOtherOutLets") + public void writeOtherOutLets(InputObject inputObject, OutputObject outputObject) { + machinPutService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryMachinPutTransById", value = "转仓库入库单时,根据id查询加工入库单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinPutController/queryMachinPutTransById") + public void queryMachinPutTransById(InputObject inputObject, OutputObject outputObject) { + machinPutService.queryMachinPutTransById(inputObject, outputObject); + } + + @ApiOperation(id = "insertMachinPutToTurnDepot", value = "加工入库单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinPutController/insertMachinPutToTurnDepot") + public void insertMachinPutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + machinPutService.insertMachinPutToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinChildDao.java new file mode 100644 index 0000000..410e911 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machin.entity.MachinChild; + +/** + * @ClassName: MachinChildDao + * @Description: 加工单子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 16:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinDao.java new file mode 100644 index 0000000..98bed4b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machin.entity.Machin; + +/** + * @ClassName: MachinDao + * @Description: 加工单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 20:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinPutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinPutDao.java new file mode 100644 index 0000000..ae1267d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/dao/MachinPutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machin.entity.MachinPut; + +/** + * @ClassName: MachinPutDao + * @Description: 加工入库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 22:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinPutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/Machin.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/Machin.java new file mode 100644 index 0000000..0134bec --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/Machin.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.bom.entity.BomChild; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Machin + * @Description: 加工单 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 16:54 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_MACHIN_CACHE_KEY, cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "erp_machin_header", autoResultMap = true) +@ApiModel("加工单实体类") +public class Machin extends SkyeyeFlowable { + + @TableField(exist = false) + @Property(value = "树的名称(订单编号)") + private String name; + + @TableField("from_type_id") + @ApiModelProperty(value = "来源单据类型,参考#MachinFromType") + private Integer fromTypeId; + + @TableField("from_id") + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField(value = "department_id") + @ApiModelProperty(value = "部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField("pick_state") + @Property(value = "领料状态,参考#MachinPickStateEnum") + private String pickState; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "子单据信息(工序信息)", required = "required,json") + private List machinChildList; + + @TableField(exist = false) + @Property(value = "条形码信息") + private Map barCodeMation; + + @TableField(exist = false) + @Property(value = "加工单所需的原材料信息") + private List needRawMaterialList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinChild.java new file mode 100644 index 0000000..d7b0ab6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinChild.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.bom.entity.Bom; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.procedure.entity.WayProcedure; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: MachinChild + * @Description: 加工单子单据 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 15:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_child", autoResultMap = true) +@ApiModel("加工单子单据实体类") +public class MachinChild extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @Property(value = "新的id") + private String newId; + + @TableField(value = "parent_id") + @Property(value = "加工单id") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField(value = "plan_start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String planStartTime; + + @TableField(value = "plan_end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String planEndTime; + + @TableField("delivery_time") + @ApiModelProperty(value = "交货日期", required = "required") + private String deliveryTime; + + @TableField(value = "bom_id") + @ApiModelProperty(value = "bom方案id") + private String bomId; + + @TableField(exist = false) + @Property(value = "bom方案信息") + private Bom bomMation; + + @TableField(exist = false) + @Property(value = "该规格对应的所有bom方案信息列表") + private List bomList; + + @TableField(value = "way_procedure_id") + @ApiModelProperty(value = "工艺id") + private String wayProcedureId; + + @TableField(exist = false) + @Property(value = "工艺信息") + private WayProcedure wayProcedureMation; + + @TableField(exist = false) + @Property(value = "工序是否完成加工的状态,true:完成,false:未完成") + private Boolean checkComplateFlag; + + @TableField(exist = false) + @Property(value = "最后加工完成的数量") + private Integer lastProcedureNum; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinPut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinPut.java new file mode 100644 index 0000000..990ccfd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/entity/MachinPut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: MachinPut + * @Description: 加工入库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 21:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:machinPut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("加工入库单实体类") +public class MachinPut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinChildService.java new file mode 100644 index 0000000..100829e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinChildService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.machin.entity.MachinChild; + +import java.util.List; + +/** + * @ClassName: MachinChildService + * @Description: 加工单子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/3 13:29 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinChildService extends SkyeyeBusinessService { + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + List selectByParentId(List parentIds); + + void saveList(String parentId, List machinChildList); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinPutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinPutService.java new file mode 100644 index 0000000..db0a17d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinPutService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machin.entity.MachinPut; + +/** + * @ClassName: MachinPutService + * @Description: 加工入库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 22:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinPutService extends SkyeyeErpOrderService { + + void queryMachinPutTransById(InputObject inputObject, OutputObject outputObject); + + void insertMachinPutToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinService.java new file mode 100644 index 0000000..3b58d1e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/MachinService.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machin.entity.Machin; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinService + * @Description: 加工单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 17:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinService extends SkyeyeFlowableService { + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + + void editPickStateById(String id, String pickState); + + Map calcMaterialNormsNumByFromId(String fromId); + + void setMachinMationByFromId(List> beans, String idKey, String mationKey); + + void queryMachinForGanttById(InputObject inputObject, OutputObject outputObject); + + void queryMachinTransRequestById(InputObject inputObject, OutputObject outputObject); + + void insertMachinToPickRequest(InputObject inputObject, OutputObject outputObject); + + void insertMachinToPickPatch(InputObject inputObject, OutputObject outputObject); + + void queryMachinTransReturnById(InputObject inputObject, OutputObject outputObject); + + void insertMachinToPickReturn(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinChildServiceImpl.java new file mode 100644 index 0000000..84a1521 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinChildServiceImpl.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.machin.dao.MachinChildDao; +import com.skyeye.machin.entity.MachinChild; +import com.skyeye.machin.service.MachinChildService; +import com.skyeye.machinprocedure.entity.MachinProcedure; +import com.skyeye.machinprocedure.service.MachinProcedureService; +import com.skyeye.procedure.entity.WayProcedure; +import com.skyeye.procedure.service.WayProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: MachinChildServiceImpl + * @Description: 加工单子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/3 13:29 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加工单子单据", groupName = "加工单管理", manageShow = false) +public class MachinChildServiceImpl extends SkyeyeBusinessServiceImpl implements MachinChildService { + + @Autowired + private WayProcedureService wayProcedureService; + + @Autowired + private BomService bomService; + + @Autowired + private MachinProcedureService machinProcedureService; + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinChild::getParentId), parentId); + remove(queryWrapper); + // 删除加工单子单据工序信息 + machinProcedureService.deleteByParentId(parentId); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinChild::getParentId), parentId); + List machinChildList = list(queryWrapper); + return machinChildList; + } + + @Override + public List selectByParentId(List parentIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MachinChild::getParentId), parentIds); + List machinChildList = list(queryWrapper); + return machinChildList; + } + + @Override + public void saveList(String parentId, List machinChildList) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(machinChildList)) { + for (MachinChild machinChild : machinChildList) { + machinChild.setParentId(parentId); + } + createEntity(machinChildList, StrUtil.EMPTY); + } + } + + @Override + public void createPostpose(List machinChildList, String userId) { + // 加工单id + String machinId = machinChildList.stream().findFirst().get().getParentId(); + // 加工单子单据工序信息对象 + List machinProcedureList = new ArrayList<>(); + machinChildList.forEach(machinChild -> { + // 设置加工单子单据的工序信息 + resetMachinProcedure(machinProcedureList, machinChild.getWayProcedureId(), machinChild.getMaterialId(), machinChild.getNormsId(), + machinChild.getId(), StrUtil.EMPTY); + // 设置加工单子单据bom清单的工序信息 + if (StrUtil.isNotEmpty(machinChild.getBomId())) { + Bom bom = bomService.selectById(machinChild.getBomId()); + bom.getBomChildList().forEach(bomChild -> { + resetMachinProcedure(machinProcedureList, bomChild.getWayProcedureId(), bomChild.getMaterialId(), bomChild.getNormsId(), + machinChild.getId(), bomChild.getId()); + }); + } + }); + machinProcedureService.saveList(machinId, machinProcedureList); + } + + private void resetMachinProcedure(List machinProcedureList, String wayProcedureId, + String materialId, String normsId, String childId, String bomChildId) { + if (StrUtil.isNotEmpty(wayProcedureId)) { + // 获取工艺信息 + WayProcedure wayProcedure = wayProcedureService.selectById(wayProcedureId); + wayProcedure.getWorkProcedureList().forEach(wayProcedureChild -> { + MachinProcedure machinProcedure = new MachinProcedure(); + machinProcedure.setChildId(childId); + machinProcedure.setBomChildId(bomChildId); + machinProcedure.setMaterialId(materialId); + machinProcedure.setNormsId(normsId); + machinProcedure.setWayProcedureId(wayProcedureId); + machinProcedure.setProcedureId(wayProcedureChild.getProcedureId()); + machinProcedure.setOrderBy(wayProcedureChild.getOrderBy()); + machinProcedureList.add(machinProcedure); + }); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinPutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinPutServiceImpl.java new file mode 100644 index 0000000..c79160d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinPutServiceImpl.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.exception.CustomException; +import com.skyeye.machin.classenum.MachinPutFromType; +import com.skyeye.machin.dao.MachinPutDao; +import com.skyeye.machin.entity.MachinPut; +import com.skyeye.machin.service.MachinPutService; +import com.skyeye.machinprocedure.service.MachinProcedureFarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinPutServiceImpl + * @Description: 加工入库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/6 22:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加工入库单", groupName = "加工单管理", flowable = true) +public class MachinPutServiceImpl extends SkyeyeErpOrderServiceImpl implements MachinPutService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private DepotPutService depotPutService; + + @Autowired + private MachinProcedureFarmService machinProcedureFarmService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + return super.getQueryWrapper(commonPageInfo); + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + // 部门 + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + + machinProcedureFarmService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(MachinPut entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + } + + @Override + public void createPrepose(MachinPut entity) { + super.createPrepose(entity); + entity.setFromTypeId(MachinPutFromType.FARM_TASK.getKey()); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public MachinPut selectById(String id) { + MachinPut machinPut = super.selectById(id); + iDepmentService.setDataMation(machinPut, MachinPut::getDepartmentId); + return machinPut; + } + + @Override + public void queryMachinPutTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + MachinPut machinPut = selectById(id); + // 该加工入库单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(machinPut.getId()); + // 设置未下达商品数量-----加工入库单数量 - 已入库数量 + super.setOrCheckOperNumber(machinPut.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + machinPut.setErpOrderItemList(machinPut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(machinPut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertMachinPutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取加工入库单状态 + MachinPut machinPut = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(machinPut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(machinPut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.MACHIN_PUT.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinServiceImpl.java new file mode 100644 index 0000000..2f84101 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machin/service/impl/MachinServiceImpl.java @@ -0,0 +1,722 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machin.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.entity.BomChild; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.machin.classenum.MachinFromType; +import com.skyeye.machin.classenum.MachinPickStateEnum; +import com.skyeye.machin.dao.MachinDao; +import com.skyeye.machin.entity.Machin; +import com.skyeye.machin.entity.MachinChild; +import com.skyeye.machin.service.MachinChildService; +import com.skyeye.machin.service.MachinService; +import com.skyeye.machinprocedure.classenum.MachinProcedureState; +import com.skyeye.machinprocedure.entity.MachinProcedure; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; +import com.skyeye.machinprocedure.service.MachinProcedureFarmService; +import com.skyeye.machinprocedure.service.MachinProcedureService; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.PickFromType; +import com.skyeye.pick.entity.PatchMaterial; +import com.skyeye.pick.entity.RequisitionMaterial; +import com.skyeye.pick.entity.ReturnMaterial; +import com.skyeye.pick.service.PatchMaterialService; +import com.skyeye.pick.service.RequisitionMaterialService; +import com.skyeye.pick.service.ReturnMaterialService; +import com.skyeye.procedure.entity.WayProcedure; +import com.skyeye.procedure.entity.WayProcedureChild; +import com.skyeye.procedure.service.WayProcedureService; +import com.skyeye.production.classenum.ProductionChildType; +import com.skyeye.production.classenum.ProductionMachinOrderState; +import com.skyeye.production.entity.Production; +import com.skyeye.production.entity.ProductionChild; +import com.skyeye.production.service.ProductionService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinServiceImpl + * @Description: 加工单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加工单管理", groupName = "加工单管理", flowable = true) +public class MachinServiceImpl extends SkyeyeFlowableServiceImpl implements MachinService { + + @Autowired + private ProductionService productionService; + + @Autowired + private MachinChildService machinChildService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private BomService bomService; + + @Autowired + private WayProcedureService wayProcedureService; + + @Autowired + private MachinProcedureService machinProcedureService; + + @Autowired + private MachinProcedureFarmService machinProcedureFarmService; + + @Autowired + private RequisitionMaterialService requisitionMaterialService; + + @Autowired + private PatchMaterialService patchMaterialService; + + @Autowired + private ReturnMaterialService returnMaterialService; + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + // 生产计划单 + productionService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(Machin entity) { + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(Machin entity) { + super.createPrepose(entity); + entity.setPickState(MachinPickStateEnum.NOT_PICKED.getKey()); + } + + @Override + public void writePostpose(Machin entity, String userId) { + // 保存子单据信息 + machinChildService.saveList(entity.getId(), entity.getMachinChildList()); + super.writePostpose(entity, userId); + } + + @Override + public void writeChild(Machin entity, String userId) { + refreshCache(entity.getId()); + super.writeChild(entity, userId); + } + + @Override + public Machin getDataFromDb(String id) { + Machin machin = super.getDataFromDb(id); + // 查询子单据信息 + machin.setMachinChildList(machinChildService.selectByParentId(machin.getId())); + return machin; + } + + @Override + public Machin selectById(String id) { + Machin machin = super.selectById(id); + // 部门信息 + iDepmentService.setDataMation(machin, Machin::getDepartmentId); + // 配件商品规格信息 + materialService.setDataMation(machin.getMachinChildList(), MachinChild::getMaterialId); + materialNormsService.setDataMation(machin.getMachinChildList(), MachinChild::getNormsId); + if (machin.getFromTypeId() == MachinFromType.PRODUCTION.getKey()) { + // 生产计划单 + productionService.setDataMation(machin, Machin::getFromId); + } + // 设置工序/工序信息,车间任务 + Map machinProcedureMap = machinProcedureService.queryMachinProcedureMapByMachinId(id); + Map> procedureFarmMap = machinProcedureFarmService.queryMachinProcedureFarmMapByMachinId(id); + // 查询bom方案 + List bomIds = machin.getMachinChildList().stream().filter(bean -> StrUtil.isNotEmpty(bean.getBomId())) + .map(MachinChild::getBomId).distinct().collect(Collectors.toList()); + Map bomMap = bomService.selectMapByIds(bomIds); + + // 获取规格对应的所有bom信息 + List normsId = machin.getMachinChildList().stream() + .map(MachinChild::getNormsId).distinct().collect(Collectors.toList()); + Map> listMap = bomService.getBomListByNormsId(normsId.toArray(new String[]{})); + machin.getMachinChildList().forEach(machinChild -> { + machinChild.setBomList(listMap.get(machinChild.getNormsId())); + // 判断产品的所有工序是否已完成 + Boolean[] checkComplateFlag = new Boolean[]{true}; + // 最后一个工序所完成的数量 + Integer[] lastProcedureNum = new Integer[]{0}; + // 1. 设置加工单子单据bom清单的工序信息 + if (StrUtil.isNotEmpty(machinChild.getBomId())) { + Bom bom = bomMap.get(machinChild.getBomId()); + bom.getBomChildList().forEach(bomChild -> { + WayProcedure bomWayProcedure = resetMachinProcedure(bomChild.getWayProcedureId(), bomChild.getMaterialId(), bomChild.getNormsId(), + machinChild.getId(), bomChild.getId(), machinProcedureMap, procedureFarmMap, checkComplateFlag, lastProcedureNum); + bomChild.setWayProcedureMation(bomWayProcedure); + }); + machinChild.setBomMation(bom); + } + + // 2. 设置加工单子单据的工序信息 + WayProcedure wayProcedure = resetMachinProcedure(machinChild.getWayProcedureId(), machinChild.getMaterialId(), machinChild.getNormsId(), + machinChild.getId(), StrUtil.EMPTY, machinProcedureMap, procedureFarmMap, checkComplateFlag, lastProcedureNum); + machinChild.setWayProcedureMation(wayProcedure); + machinChild.setCheckComplateFlag(checkComplateFlag[0]); + machinChild.setLastProcedureNum(lastProcedureNum[0]); + }); + + return machin; + } + + private WayProcedure resetMachinProcedure(String wayProcedureId, String materialId, String normsId, String childId, + String bomChildId, Map machinProcedureMap, + Map> procedureFarmMap, Boolean[] checkComplateFlag, + Integer[] lastProcedureNum) { + if (StrUtil.isNotEmpty(wayProcedureId)) { + // 获取工艺信息 + WayProcedure wayProcedure = wayProcedureService.selectById(wayProcedureId); + wayProcedure.getWorkProcedureList().forEach(wayProcedureChild -> { + String key = String.format(Locale.ROOT, "%s-%s-%s-%s-%s-%s", + childId, bomChildId, materialId, normsId, wayProcedureId, wayProcedureChild.getProcedureId()); + MachinProcedure machinProcedure = machinProcedureMap.get(key); + if (machinProcedure.getState() == MachinProcedureState.WAIT_STARTED.getKey()) { + // 工序未开始 + checkComplateFlag[0] = false; + } + // 设置工序关联的车间任务 + List machinProcedureFarmList = procedureFarmMap.get(machinProcedure.getId()); + // 计算已经完成的数量 + lastProcedureNum[0] = calcMachinProcedureFarmPassNum(machinProcedureFarmList); + machinProcedure.setMachinProcedureFarmList(machinProcedureFarmList); + wayProcedureChild.setMachinProcedureMation(machinProcedure); + }); + return wayProcedure; + } + return null; + } + + private Integer calcMachinProcedureFarmPassNum(List machinProcedureFarmList) { + if (CollectionUtil.isEmpty(machinProcedureFarmList)) { + return CommonNumConstants.NUM_ZERO; + } + // 获取已经审批通过的工序验收单 + List machinProcedureAcceptList = machinProcedureFarmList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getMachinProcedureAcceptList())) + .flatMap(bean -> bean.getMachinProcedureAcceptList().stream()) + .filter(bean -> StrUtil.equals(bean.getState(), FlowableStateEnum.PASS.getKey())).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(machinProcedureAcceptList)) { + return CommonNumConstants.NUM_ZERO; + } + return machinProcedureAcceptList.stream().collect(Collectors.summingInt(MachinProcedureAccept::getQualifiedNum)); + } + + @Override + public void deletePreExecution(String id) { + Machin machin = selectById(id); + if (!FlowableStateEnum.DRAFT.getKey().equals(machin.getState()) + && !FlowableStateEnum.REJECT.getKey().equals(machin.getState()) + && !FlowableStateEnum.REVOKE.getKey().equals(machin.getState())) { + throw new CustomException("只有草稿、驳回、撤销状态的可删除."); + } + } + + @Override + public void deletePostpose(String id) { + // 删除子单据信息 + machinChildService.deleteByParentId(id); + } + + @Override + public void approvalEndIsSuccess(Machin entity) { + entity = selectById(entity.getId()); + // 修改来源单据的状态信息 + checkMaterialNorms(entity, true); + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List machinList = list(queryWrapper); + Map machinMap = machinList.stream() + .collect(Collectors.toMap(Machin::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + Machin entity = machinMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + private void checkMaterialNorms(Machin entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前加工单的商品数量 + Map orderNormsNum = entity.getMachinChildList().stream() + .collect(Collectors.toMap(MachinChild::getNormsId, MachinChild::getOperNumber)); + // 获取同一个来源单据下已经审批通过的加工单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == MachinFromType.PRODUCTION.getKey()) { + // 生产计划单 + Production production = productionService.selectById(entity.getFromId()); + // 获取需要【加工】的商品 + List productionChildList = production.getProductionChildList().stream() + .filter(bean -> bean.getProductionType() == ProductionChildType.SELF_CONTROL.getKey()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(productionChildList)) { + throw new CustomException("该生产计划单下未包含需要加工的商品."); + } + List fromNormsIds = productionChildList.stream() + .map(ProductionChild::getNormsId).collect(Collectors.toList()); + // 求差集(生产计划单不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该生产计划单下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + productionChildList.forEach(productionChild -> { + // 生产计划单数量 - 当前加工单数量 - 已经审批通过的加工单数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(productionChild.getOperNumber(), productionChild.getNormsId(), + orderNormsNum, executeNum); + if (setData) { + productionChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + productionChildList = productionChildList.stream() + .filter(productionChild -> productionChild.getOperNumber() > 0).collect(Collectors.toList()); + // 该生产计划单的商品已经全部下达了加工单 + if (CollectionUtil.isEmpty(productionChildList)) { + productionService.editMachinOrderState(production.getId(), ProductionMachinOrderState.COMPLATE_ISSUE.getKey()); + } else { + productionService.editMachinOrderState(production.getId(), ProductionMachinOrderState.PARTIAL_ISSUE.getKey()); + } + } + } + } + + @Override + public void editPickStateById(String id, String pickState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Machin::getPickState), pickState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(Machin::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Machin::getState), FlowableStateEnum.PASS.getKey()); + List machinList = list(queryWrapper); + List ids = machinList.stream().map(Machin::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List machinChildList = machinChildService.selectByParentId(ids); + Map collect = machinChildList.stream() + .collect(Collectors.groupingBy(MachinChild::getNormsId, Collectors.summingInt(MachinChild::getOperNumber))); + return collect; + } + + @Override + public void setMachinMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List machinList = list(queryWrapper); + Map machinMap = machinList.stream() + .collect(Collectors.toMap(Machin::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + Machin entity = machinMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + @Override + public void queryMachinForGanttById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Machin machin = selectById(id); + // 生成唯一的主键id + machin.getMachinChildList().forEach(machinChild -> { + String machinChildId = ToolUtil.getSurFaceId(); + machinChild.setNewId(machinChildId); + if (StrUtil.isNotEmpty(machinChild.getBomId())) { + Bom bom = machinChild.getBomMation(); + Map newMaterialIdMap = new HashMap<>(); + bom.getBomChildList().forEach(bomChild -> { + newMaterialIdMap.put(bomChild.getMaterialId(), ToolUtil.getSurFaceId()); + }); + bom.getBomChildList().forEach(bomChild -> { + String bomChildId = ToolUtil.getSurFaceId(); + bomChild.setNewId(bomChildId); + if (StrUtil.equals(bomChild.getParentId(), CommonNumConstants.NUM_ZERO.toString())) { + bomChild.setNewParentId(machinChildId); + } else { + bomChild.setNewParentId(newMaterialIdMap.get(bomChild.getMaterialId())); + } + if (ObjectUtil.isNotEmpty(bomChild.getWayProcedureMation())) { + bomChild.getWayProcedureMation().getWorkProcedureList().forEach(wayProcedureChild -> { + wayProcedureChild.setNewId(ToolUtil.getSurFaceId()); + }); + } + }); + } + + if (ObjectUtil.isNotEmpty(machinChild.getWayProcedureMation())) { + machinChild.getWayProcedureMation().getWorkProcedureList().forEach(wayProcedureChild -> { + wayProcedureChild.setNewId(ToolUtil.getSurFaceId()); + }); + } + }); + + Map mathinTime = new HashMap<>(); + List dateArray = new ArrayList<>(); + machin.getMachinChildList().forEach(machinChild -> { + dateArray.add(machinChild.getPlanStartTime()); + dateArray.add(machinChild.getPlanEndTime()); + }); + showResult(dateArray.toArray(new String[]{}), mathinTime); + // 构造数据 + List> node = new ArrayList<>(); + List> link = new ArrayList<>(); + machin.getMachinChildList().forEach(machinChild -> { + // 产品信息 + Map materialNode = getNode(machinChild.getNewId(), machinChild.getMaterialMation().getName(), CommonNumConstants.NUM_ZERO.toString(), + machinChild.getPlanStartTime(), machinChild.getPlanEndTime(), true, machinChild); + node.add(materialNode); + resetMachinProcedure(machinChild.getWayProcedureMation(), node, link, machinChild.getNewId(), mathinTime, materialNode); + // bom清单 + if (StrUtil.isNotEmpty(machinChild.getBomId())) { + Bom bom = machinChild.getBomMation(); + bom.getBomChildList().forEach(bomChild -> { + Map childMaterialNode = getNode(bomChild.getNewId(), bomChild.getMaterialMation().getName(), bomChild.getNewParentId(), + machinChild.getPlanStartTime(), machinChild.getPlanEndTime(), true, bomChild); + node.add(childMaterialNode); + link.add(getLink(bomChild.getNewParentId(), bomChild.getNewId())); + link.get(link.size() - 1).put("color", "#009688"); + resetMachinProcedure(bomChild.getWayProcedureMation(), node, link, bomChild.getNewId(), mathinTime, childMaterialNode); + }); + } + }); + + node.forEach(item -> { + if (!MapUtil.checkKeyIsNull(item, "start_date")) { + dateArray.add(item.get("start_date").toString()); + } + if (!MapUtil.checkKeyIsNull(item, "end_date")) { + dateArray.add(item.get("end_date").toString()); + } + }); + showResult(dateArray.toArray(new String[]{}), mathinTime); + + Map retult = new HashMap<>(); + retult.put("node", node); + retult.put("link", link); + retult.put("mathinTime", mathinTime); + outputObject.setBean(retult); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private static void showResult(String[] dateArray, Map mathinTime) { + Map dateMap = new TreeMap<>(); + int i, arrayLen; + arrayLen = dateArray.length; + for (i = 0; i < arrayLen; i++) { + String dateKey = dateArray[i]; + if (dateMap.containsKey(dateKey)) { + int value = dateMap.get(dateKey) + 1; + dateMap.put(dateKey, value); + } else { + dateMap.put(dateKey, 1); + } + } + Set keySet = dateMap.keySet(); + String[] sorttedArray = new String[keySet.size()]; + Iterator iter = keySet.iterator(); + int index = 0; + while (iter.hasNext()) { + String key = iter.next(); + sorttedArray[index++] = key; + } + int sorttedArrayLen = sorttedArray.length; + mathinTime.put("start_date", sorttedArray[0]); + mathinTime.put("end_date", sorttedArray[sorttedArrayLen - 1]); + } + + private void resetMachinProcedure(WayProcedure wayProcedureMation, List> node, + List> link, String parentId, Map mathinTime, + Map materialNode) { + if (ObjectUtil.isEmpty(wayProcedureMation)) { + return; + } + String prveId = parentId; + // 获取工艺信息 + for (WayProcedureChild wayProcedureChild : wayProcedureMation.getWorkProcedureList()) { + MachinProcedure machinProcedure = wayProcedureChild.getMachinProcedureMation(); + if (ObjectUtil.isEmpty(machinProcedure)) { + node.add(getNode(wayProcedureChild.getNewId(), wayProcedureChild.getProcedureMation().getName(), parentId, + mathinTime.get("start_date").toString(), mathinTime.get("end_date").toString(), false, machinProcedure)); + node.get(node.size() - 1).put("notAddWorkProcedure", true); + } else { + node.add(getNode(wayProcedureChild.getNewId(), wayProcedureChild.getProcedureMation().getName(), parentId, + machinProcedure.getPlanStartTime(), machinProcedure.getPlanEndTime(), false, machinProcedure)); + List dateArray = new ArrayList<>(); + if (StrUtil.isNotEmpty(machinProcedure.getPlanStartTime())) { + dateArray.add(machinProcedure.getPlanStartTime()); + } + if (StrUtil.isNotEmpty(machinProcedure.getPlanEndTime())) { + dateArray.add(machinProcedure.getPlanEndTime()); + } + dateArray.add(materialNode.get("start_date").toString()); + dateArray.add(materialNode.get("end_date").toString()); + showResult(dateArray.toArray(new String[]{}), materialNode); + } + link.add(getLink(prveId, wayProcedureChild.getNewId())); + link.get(link.size() - 1).put("color", "#FFB800"); + prveId = wayProcedureChild.getNewId(); + } + } + + private Map getNode(String id, String name, String parentId, String startTime, String endTime, Boolean type, Object object) { + Map retult = new HashMap<>(); + retult.put("id", id); + retult.put("text", name); + retult.put("parent", parentId); + if (type) { + retult.put("types", "project"); + } + retult.put("start_date", startTime); + retult.put("end_date", endTime); + retult.put("open", true); + retult.put("data", object); + return retult; + } + + private Map getLink(String id, String parentId) { + Map retult = new HashMap<>(); + retult.put("id", id + "CC"); + retult.put("source", id); + retult.put("target", parentId); + retult.put("type", CommonNumConstants.NUM_ZERO); + return retult; + } + + @Override + public void queryMachinTransRequestById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Machin machin = selectById(id); + // 获取需要的原材料 + List needRawMaterial = getNeedRawMaterial(machin); + // 获取已经领料的数量 + Map requestNum = requisitionMaterialService.calcMaterialNormsNumByFromId(id); + // 获取已经补料的数量 + Map patchNum = patchMaterialService.calcMaterialNormsNumByFromId(id); + // 设置未申领的原材料信息 + needRawMaterial.forEach(machinChild -> { + // 设置未下达领料单/补料单的商品数量-----原材料需求数量 - 已领料的数量 - 已补料的数量 + Integer surplusNum = machinChild.getNeedNum() + - (requestNum.containsKey(machinChild.getNormsId()) ? requestNum.get(machinChild.getNormsId()) : 0) + - (patchNum.containsKey(machinChild.getNormsId()) ? patchNum.get(machinChild.getNormsId()) : 0); + if (surplusNum < 0) { + // 超出需求数量,设置为0,方便补料时进行补料 + surplusNum = 0; + } + // 设置未下达领料单/补料单的数量 + machinChild.setNeedNum(surplusNum); + }); + // 不需要过滤掉数量为0的商品信息,方便补料时进行补料 + machin.setNeedRawMaterialList(needRawMaterial); + + outputObject.setBean(machin); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 获取需要的原材料 + * + * @param machin 加工单 + * @return + */ + private List getNeedRawMaterial(Machin machin) { + List needRawMaterial = new ArrayList<>(); + for (MachinChild machinChild : machin.getMachinChildList()) { + if (StrUtil.isNotEmpty(machinChild.getBomId())) { + Bom bom = machinChild.getBomMation(); + List bomChildList = new ArrayList<>(bom.getBomChildList()); + bomChildList.forEach(bomChild -> { + // 计算需要的原材料数量 = 订单数量 / bom方案制造的数量 * bom子项的需求数量 + String divide = CalculationUtil.divide(String.valueOf(machinChild.getOperNumber()), String.valueOf(bom.getMakeNum()), CommonNumConstants.NUM_TWO); + divide = CalculationUtil.multiply(divide, String.valueOf(bomChild.getNeedNum()), CommonNumConstants.NUM_ZERO); + bomChild.setNeedNum(Integer.parseInt(divide)); + }); + needRawMaterial.addAll(bomChildList); + } + } + // 根据规格id去重并合并所需数量 + Map needRawMaterialMap = new HashMap<>(); + needRawMaterial.forEach(bomChild -> { + if (needRawMaterialMap.containsKey(bomChild.getNormsId())) { + BomChild existBomChild = needRawMaterialMap.get(bomChild.getNormsId()); + existBomChild.setNeedNum(existBomChild.getNeedNum() + bomChild.getNeedNum()); + } else { + needRawMaterialMap.put(bomChild.getNormsId(), bomChild); + } + }); + needRawMaterial = new ArrayList<>(needRawMaterialMap.values()); + return needRawMaterial; + } + + @Override + public void insertMachinToPickRequest(InputObject inputObject, OutputObject outputObject) { + RequisitionMaterial requisitionMaterial = inputObject.getParams(RequisitionMaterial.class); + // 获取加工单状态 + Machin order = selectById(requisitionMaterial.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以进行下达领料单/补料单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + requisitionMaterial.setFromId(requisitionMaterial.getId()); + requisitionMaterial.setFromTypeId(PickFromType.MACHIN.getKey()); + requisitionMaterial.setId(StrUtil.EMPTY); + requisitionMaterialService.createEntity(requisitionMaterial, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达领料单."); + } + } + + @Override + public void insertMachinToPickPatch(InputObject inputObject, OutputObject outputObject) { + PatchMaterial patchMaterial = inputObject.getParams(PatchMaterial.class); + // 获取加工单状态 + Machin order = selectById(patchMaterial.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以进行下达领料单/补料单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + patchMaterial.setFromId(patchMaterial.getId()); + patchMaterial.setFromTypeId(PickFromType.MACHIN.getKey()); + patchMaterial.setId(StrUtil.EMPTY); + patchMaterialService.createEntity(patchMaterial, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达补料单."); + } + } + + @Override + public void queryMachinTransReturnById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Machin machin = selectById(id); + // 获取已经领料的数量 + Map requestNum = requisitionMaterialService.calcMaterialNormsNumByFromId(id); + // 获取已经补料的数量 + Map patchNum = patchMaterialService.calcMaterialNormsNumByFromId(id); + // 获取已经退料的数量 + Map returnNum = returnMaterialService.calcMaterialNormsNumByFromId(id); + machin.getMachinChildList().forEach(machinChild -> { + // 设置未下达退料单的商品数量-----已领料的数量 + 已补料的数量 - 订单数量 - 已退料的数量 + Integer surplusNum = (requestNum.containsKey(machinChild.getNormsId()) ? requestNum.get(machinChild.getNormsId()) : 0) + + (patchNum.containsKey(machinChild.getNormsId()) ? patchNum.get(machinChild.getNormsId()) : 0) + - machinChild.getLastProcedureNum() + - (returnNum.containsKey(machinChild.getNormsId()) ? returnNum.get(machinChild.getNormsId()) : 0); + // 设置未下达退料单的数量 + machinChild.setOperNumber(surplusNum); + }); + outputObject.setBean(machin); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertMachinToPickReturn(InputObject inputObject, OutputObject outputObject) { + ReturnMaterial returnMaterial = inputObject.getParams(ReturnMaterial.class); + // 获取加工单状态 + Machin order = selectById(returnMaterial.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以进行下达退料单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + returnMaterial.setFromId(returnMaterial.getId()); + returnMaterial.setFromTypeId(PickFromType.MACHIN.getKey()); + returnMaterial.setId(StrUtil.EMPTY); + returnMaterialService.createEntity(returnMaterial, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达退料单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureAcceptChildType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureAcceptChildType.java new file mode 100644 index 0000000..d9030a0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureAcceptChildType.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.classenum; + +import cn.hutool.core.map.MapUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: MachinProcedureAcceptChildType + * @Description: 工序验收子单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 15:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinProcedureAcceptChildType implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + SCRAP(2, "报废", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static Map getMation(Integer type) { + for (MachinProcedureAcceptChildType bean : MachinProcedureAcceptChildType.values()) { + if (type == bean.getKey()) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureFarmState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureFarmState.java new file mode 100644 index 0000000..0ba7c09 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureFarmState.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.classenum; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: MachinProcedureFarmState + * @Description: 车间任务状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 14:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinProcedureFarmState implements SkyeyeEnumClass { + + WAIT_RECEIVE("waitReceive", "待接收", "red", true, false), + WAIT_EXECUTED("waitExecuted", "待执行", "blue", true, false), + PARTIAL_COMPLETION("partialCompletion", "部分完成", "orange", true, false), + ALL_COMPLETED("allCompleted", "全部完成", "green", true, false), + EXCESS_COMPLETED("excessCompleted", "超额完成", "lightgreen", true, false); + + private String key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + + public static Map getMation(String type) { + for (MachinProcedureFarmState bean : MachinProcedureFarmState.values()) { + if (StrUtil.equals(bean.getKey(), type)) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureState.java new file mode 100644 index 0000000..ce23cd2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/classenum/MachinProcedureState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MachinProcedureState + * @Description: 加工单子单据工序信息状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 14:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MachinProcedureState implements SkyeyeEnumClass { + + WAIT_STARTED(1, "待开工", true, false), + PARTIAL_COMPLETION(2, "部分完工", true, false), + ALL_COMPLETED(3, "全部完工", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureAcceptController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureAcceptController.java new file mode 100644 index 0000000..03656fa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureAcceptController.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; +import com.skyeye.machinprocedure.service.MachinProcedureAcceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MachinProcedureAcceptController + * @Description: 工序验收控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工序验收", tags = "工序验收", modelName = "工序验收") +public class MachinProcedureAcceptController { + + @Autowired + private MachinProcedureAcceptService machinProcedureAcceptService; + + /** + * 查询工序验收列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinProcedureAcceptList", value = "查询工序验收列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MachinProcedureAcceptController/queryMachinProcedureAcceptList") + public void queryMachinProcedureAcceptList(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑工序验收 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMachinProcedureAccept", value = "新增/编辑加工单子单据工序验收", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MachinProcedureAccept.class) + @RequestMapping("/post/MachinProcedureAcceptController/writeMachinProcedureAccept") + public void writeMachinProcedureAccept(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除工序验收 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMachinProcedureAcceptById", value = "根据id删除工序验收", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureAcceptController/deleteMachinProcedureAcceptById") + public void deleteMachinProcedureAcceptById(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询工序验收 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinProcedureAcceptById", value = "根据id查询工序验收", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureAcceptController/queryMachinProcedureAcceptById") + public void queryMachinProcedureAcceptById(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.selectById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitMachinProcedureAcceptToApproval", value = "提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/MachinProcedureAcceptController/submitMachinProcedureAcceptToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeMachinProcedureAccept", value = "撤销申请", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/MachinProcedureAcceptController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + machinProcedureAcceptService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureController.java new file mode 100644 index 0000000..43513a6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureController.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machinprocedure.service.MachinProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MachinProcedureController + * @Description: 加工单子单据工序信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 15:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "加工单子单据工序信息", tags = "加工单子单据工序信息", modelName = "加工单管理") +public class MachinProcedureController { + + @Autowired + private MachinProcedureService machinProcedureService; + + /** + * 查询工序的任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMachinProcedureById", value = "查询工序的任务信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureController/queryMachinProcedureById") + public void queryMachinProcedureById(InputObject inputObject, OutputObject outputObject) { + machinProcedureService.selectById(inputObject, outputObject); + } + + /** + * 设置工序的任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setMachinProcedureById", value = "设置计划时间", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "planStartTime", name = "planStartTime", value = "计划开始时间", required = "required"), + @ApiImplicitParam(id = "planEndTime", name = "planEndTime", value = "计划结束时间", required = "required"), + @ApiImplicitParam(id = "actualStartTime", name = "actualStartTime", value = "实际开始时间"), + @ApiImplicitParam(id = "actualEndTime", name = "actualEndTime", value = "实际结束时间"), + @ApiImplicitParam(id = "machinProcedureFarmList", name = "machinProcedureFarmList", value = "加工单子单据工序关联车间信息,参考#MachinProcedureFarm实体类", required = "json")}) + @RequestMapping("/post/MachinProcedureController/setMachinProcedureById") + public void setMachinProcedureById(InputObject inputObject, OutputObject outputObject) { + machinProcedureService.setMachinProcedureById(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureFarmController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureFarmController.java new file mode 100644 index 0000000..b9d2744 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/controller/MachinProcedureFarmController.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machinprocedure.service.MachinProcedureFarmService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MachinProcedureFarmController + * @Description: 车间任务控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车间任务", tags = "车间任务", modelName = "车间任务") +public class MachinProcedureFarmController { + + @Autowired + private MachinProcedureFarmService machinProcedureFarmService; + + @ApiOperation(id = "queryMachinProcedureFarmList", value = "获取车间任务信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MachinProcedureFarmController/queryMachinProcedureFarmList") + public void queryMachinProcedureFarmList(InputObject inputObject, OutputObject outputObject) { + machinProcedureFarmService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "receiveMachinProcedureFarm", value = "车间任务接收", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureFarmController/receiveMachinProcedureFarm") + public void receiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject) { + machinProcedureFarmService.receiveMachinProcedureFarm(inputObject, outputObject); + } + + @ApiOperation(id = "receptionReceiveMachinProcedureFarm", value = "车间任务反接收", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureFarmController/receptionReceiveMachinProcedureFarm") + public void receptionReceiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject) { + machinProcedureFarmService.receptionReceiveMachinProcedureFarm(inputObject, outputObject); + } + + @ApiOperation(id = "queryMachinProcedureFarmToInOrOutList", value = "车间任务转加工入库单时,根据车间任务id查询对应的成品信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MachinProcedureFarmController/queryMachinProcedureFarmToInOrOutList") + public void queryMachinProcedureFarmToInOrOutList(InputObject inputObject, OutputObject outputObject) { + machinProcedureFarmService.queryMachinProcedureFarmToInOrOutList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildCodeDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildCodeDao.java new file mode 100644 index 0000000..7eeb7f3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChildCode; + +/** + * @ClassName: MachinProcedureAcceptChildCodeDao + * @Description: 加工单子单据工序验收耗材表关联的条形码编号数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 14:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptChildCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildDao.java new file mode 100644 index 0000000..87874ae --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptChildDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChild; + +/** + * @ClassName: MachinProcedureAcceptChildDao + * @Description: 工序验收子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/25 17:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptChildDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptDao.java new file mode 100644 index 0000000..26b607a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureAcceptDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; + +/** + * @ClassName: MachinProcedureAcceptDao + * @Description: 工序验收数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureDao.java new file mode 100644 index 0000000..73be993 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machinprocedure.entity.MachinProcedure; + +/** + * @ClassName: MachinProcedureDao + * @Description: 加工单子单据工序信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 15:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureFarmDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureFarmDao.java new file mode 100644 index 0000000..5160a21 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/dao/MachinProcedureFarmDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; + +/** + * @ClassName: MachinProcedureFarmDao + * @Description: 车间任务数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 18:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureFarmDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedure.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedure.java new file mode 100644 index 0000000..c4e3b15 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedure.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.procedure.entity.WorkProcedure; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: MachinProcedure + * @Description: 加工单子单据工序信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 12:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_procedure", autoResultMap = true) +@ApiModel("加工单子单据工序信息实体类") +public class MachinProcedure extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "parent_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "加工单id") + private String parentId; + + @TableField(value = "child_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "加工单子单据id") + private String childId; + + @TableField(value = "bom_child_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "bom子件清单的id") + private String bomChildId; + + @TableField(value = "way_procedure_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "工艺id") + private String wayProcedureId; + + @TableField(value = "material_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "商品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "procedure_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "工序id") + private String procedureId; + + @TableField(exist = false) + @Property(value = "工序") + private WorkProcedure procedureMation; + + @TableField(value = "order_by", updateStrategy = FieldStrategy.NEVER) + @Property(value = "排序") + private Integer orderBy; + + @TableField("state") + @Property("状态,参考#MachinProcedureState") + private Integer state; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "plan_start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String planStartTime; + + @TableField(value = "plan_end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String planEndTime; + + @TableField(value = "actual_start_time") + @ApiModelProperty(value = "实际开始时间") + private String actualStartTime; + + @TableField(value = "actual_end_time") + @ApiModelProperty(value = "实际结束时间") + private String actualEndTime; + + @TableField(exist = false) + @Property(value = "关联的车间任务") + private List machinProcedureFarmList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAccept.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAccept.java new file mode 100644 index 0000000..9f24fbb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAccept.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.equipment.entity.Equipment; +import com.skyeye.farm.entity.Farm; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureAccept + * @Description: 工序验收实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_procedure_accept", autoResultMap = true) +@ApiModel("工序验收实体类") +public class MachinProcedureAccept extends SkyeyeFlowable { + + @TableField(value = "machin_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "加工单id") + private String machinId; + + @TableField(value = "machin_procedure_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "加工单子单据工序id") + private String machinProcedureId; + + @TableField(value = "machin_procedure_farm_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "车间任务id") + private String machinProcedureFarmId; + + @TableField("accept_num") + @ApiModelProperty(value = "验收数量", required = "required,num") + private Integer acceptNum; + + @TableField("qualified_num") + @ApiModelProperty(value = "合格数量", required = "required,num") + private Integer qualifiedNum; + + @TableField("rework_num") + @ApiModelProperty(value = "返工数量", required = "required,num") + private Integer reworkNum; + + @TableField(value = "rework_reason") + @ApiModelProperty(value = "返工原因") + private String reworkReason; + + @TableField("scrap_num") + @ApiModelProperty(value = "报废数量", required = "required,num") + private Integer scrapNum; + + @TableField(value = "scrap_reason") + @ApiModelProperty(value = "报废原因") + private String scrapReason; + + @TableField(value = "department_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "部门id") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "farm_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "车间id") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField(value = "equipment_id") + @ApiModelProperty(value = "设备id") + private String equipmentId; + + @TableField(exist = false) + @Property(value = "设备信息") + private Equipment equipmentMation; + + @TableField(value = "next_farm_id") + @ApiModelProperty(value = "流转车间id") + private String nextFarmId; + + @TableField(exist = false) + @Property(value = "流转车间信息") + private Farm nextFarmMation; + + @TableField(value = "accept_user_id") + @ApiModelProperty(value = "验收人id") + private String acceptUserId; + + @TableField(exist = false) + @Property(value = "验收人信息") + private Map acceptUserMation; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "正常耗材", required = "json") + private List machinProcedureAcceptChildList; + + @TableField(exist = false) + @ApiModelProperty(value = "报废耗材", required = "json") + private List machinScrapProcedureAcceptChildList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChild.java new file mode 100644 index 0000000..6752f12 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChild.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureAcceptChild + * @Description: 工序验收子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/25 17:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_procedure_accept_child", autoResultMap = true) +@ApiModel("工序验收子单据实体类") +public class MachinProcedureAcceptChild extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "parent_id") + @Property(value = "加工单id") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField(exist = false) + @ApiModelProperty(value = "商品规格条形码编号") + private String normsCode; + + @TableField(exist = false) + @Property(value = "商品规格条形码编号集合") + private List normsCodeList; + + @TableField(value = "type") + @ApiModelProperty(value = "类型,参考#MachinProcedureAcceptChildType", required = "required,num") + private Integer type; + + @TableField(exist = false) + @Property(value = "类型信息") + private Map typeMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChildCode.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChildCode.java new file mode 100644 index 0000000..5f76e15 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureAcceptChildCode.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: MachinProcedureAcceptChildCode + * @Description: 加工单子单据工序验收耗材表关联的条形码编号 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_procedure_accept_child_code") +@ApiModel("加工单子单据工序验收耗材表关联的条形码编号") +public class MachinProcedureAcceptChildCode extends CommonInfo { + + @TableId("id") + private String id; + + @TableField("order_id") + @Property(value = "订单id") + private String orderId; + + @TableField("parent_id") + @Property(value = "子单据id") + private String parentId; + + @TableField("material_id") + @Property(value = "产品id") + private String materialId; + + @TableField("norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField("norms_code") + @Property(value = "条形码编号") + private String normsCode; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureFarm.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureFarm.java new file mode 100644 index 0000000..77f9236 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/entity/MachinProcedureFarm.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.farm.entity.Farm; +import com.skyeye.machin.entity.Machin; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureFarm + * @Description: 车间任务实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 18:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_machin_procedure_farm", autoResultMap = true) +@ApiModel("车间任务实体类") +public class MachinProcedureFarm extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "odd_number", updateStrategy = FieldStrategy.NEVER) + @Property(value = "单据编号", fuzzyLike = true) + private String oddNumber; + + @TableField(value = "machin_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "加工单id") + private String machinId; + + @TableField(exist = false) + @Property(value = "加工单信息") + private Machin machinMation; + + @TableField(value = "machin_procedure_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "加工单子单据工序id") + private String machinProcedureId; + + @TableField(exist = false) + @Property(value = "加工单子单据工序信息") + private MachinProcedure machinProcedureMation; + + @TableField(value = "farm_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "车间id", required = "required") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField("target_num") + @ApiModelProperty(value = "目标数量", required = "required,num") + private Integer targetNum; + + @TableField(value = "state") + @Property(value = "状态,参考#MachinProcedureFarmState") + private String state; + + @TableField(exist = false) + @Property(value = "状态信息") + private Map stateMation; + + @TableField(exist = false) + @Property(value = "车间工序验收任务列表") + private List machinProcedureAcceptList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildCodeService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildCodeService.java new file mode 100644 index 0000000..f2fb089 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildCodeService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChildCode; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureAcceptChildCodeService + * @Description: 加工单子单据工序验收耗材表关联的条形码编号服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 14:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptChildCodeService extends SkyeyeBusinessService { + + void saveList(String orderId, List beans); + + void deleteByOrderId(String orderId); + + List selectByOrderId(String... orderId); + + Map> selectMapByOrderId(String... orderId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildService.java new file mode 100644 index 0000000..17ba044 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptChildService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChild; + +import java.util.List; + +/** + * @ClassName: MachinProcedureAcceptChildService + * @Description: 工序验收子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/25 17:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptChildService extends SkyeyeBusinessService { + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + void saveList(String parentId, List machinProcedureAcceptChildList); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptService.java new file mode 100644 index 0000000..27ebb20 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureAcceptService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureAcceptService + * @Description: 工序验收服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureAcceptService extends SkyeyeFlowableService { + + Integer calcNumByMachinProcedureFarmId(String machinProcedureFarmId); + + Map> queryMachinProcedureAcceptByMachinProcedureFarmId(String... machinProcedureFarmId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureFarmService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureFarmService.java new file mode 100644 index 0000000..4b1aedc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureFarmService.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureFarmService + * @Description: 车间任务服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 19:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureFarmService extends SkyeyeBusinessService { + + Map> queryMachinProcedureFarmMapByMachinId(String machinId); + + void receiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject); + + void receptionReceiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject); + + void editStateById(String id, String state); + + void deleteMachinProcedureFarmByMachinProcedureId(String machinProcedureId); + + List queryMachinProcedureFarmByMachinProcedureId(String machinProcedureId); + + List queryAllMachinProcedureFarmByMachinProcedureId(String machinProcedureId); + + void queryMachinProcedureFarmToInOrOutList(InputObject inputObject, OutputObject outputObject); + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureService.java new file mode 100644 index 0000000..e185695 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/MachinProcedureService.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machinprocedure.entity.MachinProcedure; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MachinProcedureService + * @Description: 加工单子单据工序信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 15:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MachinProcedureService extends SkyeyeBusinessService { + + void deleteByParentId(String parentId); + + void saveList(String parentId, List machinProcedureList); + + void setMachinProcedureById(InputObject inputObject, OutputObject outputObject); + + Map queryMachinProcedureMapByMachinId(String machinId); + + void editStateById(String id, Integer state); + + /** + * 判断当前工序的前置工序是否部分完成/全部完成 + * + * @param machinProcedureId 当前加工单子单据工序id + * @return true: 前置工序全部完成/部分完成; false: 前置工序未完成 + */ + boolean checkPrevMachinProcedureIsCompleted(String machinProcedureId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildCodeServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildCodeServiceImpl.java new file mode 100644 index 0000000..a413a4e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildCodeServiceImpl.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.machinprocedure.dao.MachinProcedureAcceptChildCodeDao; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChildCode; +import com.skyeye.machinprocedure.service.MachinProcedureAcceptChildCodeService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinProcedureAcceptChildCodeServiceImpl + * @Description: 加工单子单据工序验收耗材表关联的条形码编号服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 14:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class MachinProcedureAcceptChildCodeServiceImpl extends SkyeyeBusinessServiceImpl implements MachinProcedureAcceptChildCodeService { + + @Override + public void saveList(String orderId, List beans) { + deleteByOrderId(orderId); + if (CollectionUtil.isNotEmpty(beans)) { + for (MachinProcedureAcceptChildCode machinProcedureAcceptChildCode : beans) { + machinProcedureAcceptChildCode.setOrderId(orderId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureAcceptChildCode::getOrderId), orderId); + remove(queryWrapper); + } + + @Override + public List selectByOrderId(String... orderId) { + List orderIdList = Arrays.asList(orderId); + if (CollectionUtil.isEmpty(orderIdList)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MachinProcedureAcceptChildCode::getOrderId), orderIdList); + List list = list(queryWrapper); + return list; + } + + @Override + public Map> selectMapByOrderId(String... orderId) { + List machinProcedureAcceptChildCodeList = selectByOrderId(orderId); + Map> listMap = machinProcedureAcceptChildCodeList.stream(). + collect(Collectors.groupingBy(bean -> String.format(Locale.ROOT, "%s_%s", bean.getParentId(), bean.getNormsId()), + Collectors.mapping(MachinProcedureAcceptChildCode::getNormsCode, Collectors.toList()))); + return listMap; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildServiceImpl.java new file mode 100644 index 0000000..732b639 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptChildServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.machinprocedure.dao.MachinProcedureAcceptChildDao; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChild; +import com.skyeye.machinprocedure.service.MachinProcedureAcceptChildService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: MachinProcedureAcceptChildServiceImpl + * @Description: 工序验收子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/25 17:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工序验收子单据", groupName = "工序验收", manageShow = false) +public class MachinProcedureAcceptChildServiceImpl extends SkyeyeBusinessServiceImpl implements MachinProcedureAcceptChildService { + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureAcceptChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureAcceptChild::getParentId), parentId); + List machinProcedureAcceptChildList = list(queryWrapper); + return machinProcedureAcceptChildList; + } + + @Override + public void saveList(String parentId, List machinProcedureAcceptChildList) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(machinProcedureAcceptChildList)) { + for (MachinProcedureAcceptChild machinProcedureAcceptChild : machinProcedureAcceptChildList) { + machinProcedureAcceptChild.setParentId(parentId); + } + createEntity(machinProcedureAcceptChildList, StrUtil.EMPTY); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptServiceImpl.java new file mode 100644 index 0000000..316d79e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureAcceptServiceImpl.java @@ -0,0 +1,404 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.exception.CustomException; +import com.skyeye.machin.entity.Machin; +import com.skyeye.machinprocedure.classenum.MachinProcedureAcceptChildType; +import com.skyeye.machinprocedure.classenum.MachinProcedureFarmState; +import com.skyeye.machinprocedure.dao.MachinProcedureAcceptDao; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChild; +import com.skyeye.machinprocedure.entity.MachinProcedureAcceptChildCode; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; +import com.skyeye.machinprocedure.service.*; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.pick.classenum.PickNormsCodeUseState; +import com.skyeye.pick.service.DepartmentStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinProcedureAcceptServiceImpl + * @Description: 工序验收服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 20:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工序验收", groupName = "工序验收", flowable = true) +public class MachinProcedureAcceptServiceImpl extends SkyeyeFlowableServiceImpl implements MachinProcedureAcceptService { + + @Autowired + private MachinProcedureService machinProcedureService; + + @Autowired + private MachinProcedureFarmService machinProcedureFarmService; + + @Autowired + private MachinProcedureAcceptChildService machinProcedureAcceptChildService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private DepartmentStockService departmentStockService; + + @Autowired + protected MaterialNormsCodeService materialNormsCodeService; + + @Autowired + private MachinProcedureAcceptChildCodeService machinProcedureAcceptChildCodeService; + + @Override + public void validatorEntity(MachinProcedureAccept entity) { + if (StrUtil.isEmpty(entity.getId())) { + MachinProcedureFarm machinProcedureFarm = machinProcedureFarmService.selectById(entity.getMachinProcedureFarmId()); + entity.setMachinId(machinProcedureFarm.getMachinId()); + entity.setDepartmentId(machinProcedureFarm.getFarmMation().getDepartmentId()); + entity.setFarmId(machinProcedureFarm.getFarmId()); + entity.setMachinProcedureId(machinProcedureFarm.getMachinProcedureId()); + } else { + MachinProcedureAccept oldEntity = super.selectById(entity.getId()); + entity.setMachinId(oldEntity.getMachinId()); + entity.setDepartmentId(oldEntity.getDepartmentId()); + entity.setFarmId(oldEntity.getFarmId()); + entity.setMachinProcedureId(oldEntity.getMachinProcedureId()); + } + + // 实际验收总数量 = 合格数量 + 返工数量 + 报废数量 + int tempNum = entity.getQualifiedNum() + entity.getReworkNum() + entity.getScrapNum(); + if (entity.getAcceptNum() != tempNum) { + throw new CustomException("验收数量不等于【合格数量】 + 【返工数量】 + 【报废数量】,请确认."); + } + + boolean isCompleted = machinProcedureService.checkPrevMachinProcedureIsCompleted(entity.getMachinProcedureId()); + if (!isCompleted) { + throw new CustomException("请先完成上一个工序的验收"); + } + + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, true); + } + + @Override + public void writePostpose(MachinProcedureAccept entity, String userId) { + List childList = new ArrayList<>(); + mergeAcceptChild(entity, childList); + machinProcedureAcceptChildService.saveList(entity.getId(), childList); + // 保存商品规格编码信息 + saveErpOrderItemCode(entity); + super.writePostpose(entity, userId); + } + + private void saveErpOrderItemCode(MachinProcedureAccept entity) { + List materialIdList = entity.getMachinProcedureAcceptChildList().stream() + .map(MachinProcedureAcceptChild::getMaterialId).distinct().collect(Collectors.toList()); + List scrapMaterialIdList = entity.getMachinScrapProcedureAcceptChildList().stream() + .map(MachinProcedureAcceptChild::getMaterialId).distinct().collect(Collectors.toList()); + materialIdList.addAll(scrapMaterialIdList); + materialIdList = materialIdList.stream().distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + // 保存单据子表关联的条形码编号信息 + List machinProcedureAcceptChildCodeList = new ArrayList<>(); + // 正常耗材 + for (MachinProcedureAcceptChild machinProcedureAcceptChild : entity.getMachinProcedureAcceptChildList()) { + Material material = materialMap.get(machinProcedureAcceptChild.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + // 过滤掉空的,并且去重 + List normsCodeList = Arrays.asList(machinProcedureAcceptChild.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (machinProcedureAcceptChild.getOperNumber() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】的条形码数量与明细数量不一致,请确认", material.getName())); + } + normsCodeList.forEach(normsCode -> { + MachinProcedureAcceptChildCode erpOrderItemCode = new MachinProcedureAcceptChildCode(); + erpOrderItemCode.setNormsCode(normsCode); + erpOrderItemCode.setMaterialId(machinProcedureAcceptChild.getMaterialId()); + erpOrderItemCode.setNormsId(machinProcedureAcceptChild.getNormsId()); + erpOrderItemCode.setParentId(machinProcedureAcceptChild.getId()); + machinProcedureAcceptChildCodeList.add(erpOrderItemCode); + }); + } + } + // 报废耗材 + for (MachinProcedureAcceptChild machinProcedureAcceptChild : entity.getMachinScrapProcedureAcceptChildList()) { + Material material = materialMap.get(machinProcedureAcceptChild.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + // 过滤掉空的,并且去重 + List normsCodeList = Arrays.asList(machinProcedureAcceptChild.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (machinProcedureAcceptChild.getOperNumber() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】的条形码数量与明细数量不一致,请确认", material.getName())); + } + normsCodeList.forEach(normsCode -> { + MachinProcedureAcceptChildCode erpOrderItemCode = new MachinProcedureAcceptChildCode(); + erpOrderItemCode.setNormsCode(normsCode); + erpOrderItemCode.setMaterialId(machinProcedureAcceptChild.getMaterialId()); + erpOrderItemCode.setNormsId(machinProcedureAcceptChild.getNormsId()); + erpOrderItemCode.setParentId(machinProcedureAcceptChild.getId()); + machinProcedureAcceptChildCodeList.add(erpOrderItemCode); + }); + } + } + machinProcedureAcceptChildCodeService.saveList(entity.getId(), machinProcedureAcceptChildCodeList); + } + + @Override + public MachinProcedureAccept getDataFromDb(String id) { + MachinProcedureAccept machinProcedureAccept = super.getDataFromDb(id); + // 设置耗材信息 + List machinProcedureAcceptChildList = machinProcedureAcceptChildService.selectByParentId(id); + // 查询单据子表关联的条形码编号信息 + Map> codeMap = machinProcedureAcceptChildCodeService.selectMapByOrderId(id); + machinProcedureAcceptChildList.forEach(machinProcedureAcceptChild -> { + String key = String.format(Locale.ROOT, "%s_%s", machinProcedureAcceptChild.getId(), machinProcedureAcceptChild.getNormsId()); + List codeList = codeMap.get(key); + if (CollectionUtil.isNotEmpty(codeList)) { + machinProcedureAcceptChild.setNormsCodeList(codeList); + machinProcedureAcceptChild.setNormsCode(Joiner.on("\n").join(codeList)); + } + }); + + Map> childMap = machinProcedureAcceptChildList.stream() + .collect(Collectors.groupingBy(MachinProcedureAcceptChild::getType)); + machinProcedureAccept.setMachinProcedureAcceptChildList(childMap.get(MachinProcedureAcceptChildType.NORMAL.getKey())); + machinProcedureAccept.setMachinScrapProcedureAcceptChildList(childMap.get(MachinProcedureAcceptChildType.SCRAP.getKey())); + return machinProcedureAccept; + } + + @Override + public MachinProcedureAccept selectById(String id) { + MachinProcedureAccept machinProcedureAccept = super.selectById(id); + // 设置产品/规格信息 + materialService.setDataMation(machinProcedureAccept.getMachinProcedureAcceptChildList(), MachinProcedureAcceptChild::getMaterialId); + materialNormsService.setDataMation(machinProcedureAccept.getMachinProcedureAcceptChildList(), MachinProcedureAcceptChild::getNormsId); + + materialService.setDataMation(machinProcedureAccept.getMachinScrapProcedureAcceptChildList(), MachinProcedureAcceptChild::getMaterialId); + materialNormsService.setDataMation(machinProcedureAccept.getMachinScrapProcedureAcceptChildList(), MachinProcedureAcceptChild::getNormsId); + + if (CollectionUtil.isNotEmpty(machinProcedureAccept.getMachinProcedureAcceptChildList())) { + machinProcedureAccept.getMachinProcedureAcceptChildList().forEach(machinProcedureAcceptChild -> { + machinProcedureAcceptChild.setTypeMation(MachinProcedureAcceptChildType.getMation(machinProcedureAcceptChild.getType())); + }); + } + + if (CollectionUtil.isNotEmpty(machinProcedureAccept.getMachinScrapProcedureAcceptChildList())) { + machinProcedureAccept.getMachinScrapProcedureAcceptChildList().forEach(machinProcedureAcceptChild -> { + machinProcedureAcceptChild.setTypeMation(MachinProcedureAcceptChildType.getMation(machinProcedureAcceptChild.getType())); + }); + } + + iAuthUserService.setDataMation(machinProcedureAccept, MachinProcedureAccept::getAcceptUserId); + + return machinProcedureAccept; + } + + @Override + public void deletePostpose(String id) { + machinProcedureAcceptChildService.deleteByParentId(id); + // 删除关联的编码信息 + machinProcedureAcceptChildCodeService.deleteByOrderId(id); + } + + @Override + public void approvalEndIsSuccess(MachinProcedureAccept entity) { + // 获取车间任务 + MachinProcedureFarm machinProcedureFarm = machinProcedureFarmService.selectById(entity.getMachinProcedureFarmId()); + // 获取该任务下已经完成的量 + Integer allComplateNum = calcNumByMachinProcedureFarmId(entity.getMachinProcedureFarmId()); + // 计算未完成的量 = 车间任务目标量 - 已完成的量 - 当前单据合格的量 + Integer noComplateNum = machinProcedureFarm.getTargetNum() - allComplateNum - entity.getQualifiedNum(); + if (noComplateNum == 0) { + machinProcedureFarmService.editStateById(machinProcedureFarm.getId(), MachinProcedureFarmState.ALL_COMPLETED.getKey()); + } else if (noComplateNum > 0) { + machinProcedureFarmService.editStateById(machinProcedureFarm.getId(), MachinProcedureFarmState.PARTIAL_COMPLETION.getKey()); + } else if (noComplateNum < 0) { + machinProcedureFarmService.editStateById(machinProcedureFarm.getId(), MachinProcedureFarmState.EXCESS_COMPLETED.getKey()); + } + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, false); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + public List checkNormsCodeAndSave(MachinProcedureAccept entity, Boolean onlyCheck) { + // 合并正常消耗和报废耗材 + List childList = new ArrayList<>(); + mergeAcceptChild(entity, childList); + // 查询商品/规格信息 + List materialIdList = childList.stream().map(MachinProcedureAcceptChild::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = childList.stream().map(MachinProcedureAcceptChild::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行耗材处理的条形码编码 + List allNormsCodeList = new ArrayList<>(); + Map normsCodeType = new HashMap<>(); + int allCodeNum = checkErpOrderItemDetail(childList, materialMap, normsMap, allNormsCodeList, normsCodeType); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 校验数量 + Map stock = departmentStockService.queryNormsDepartmentStock(entity.getDepartmentId(), entity.getFarmId(), normsIdList); + Map collect = childList.stream() + .collect(Collectors.groupingBy(MachinProcedureAcceptChild::getNormsId, Collectors.summingInt(MachinProcedureAcceptChild::getOperNumber))); + collect.forEach((normsId, changeNum) -> { + Integer departmentFarmStock = stock.containsKey(normsId) ? stock.get(normsId) : 0; + if (changeNum > departmentFarmStock) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】超出当前仓库的库存,请确认", normsMap.get(normsId).getName())); + } + }); + // 2. 校验条形码 + // 2.1 从数据库查询出库状态的条形码信息, + // 2.2 只有部门信息不为空的说明已经领料,才可以进行工序耗材。 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getDepartmentId()) && StrUtil.equals(entity.getDepartmentId(), bean.getDepartmentId())) + .collect(Collectors.toList()); + // 2.3 如果车间不为空,则需要获取过滤出当前车间的库存 + if (StrUtil.isNotEmpty(entity.getFarmId())) { + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getFarmId()) && StrUtil.equals(entity.getFarmId(), bean.getFarmId())) + .collect(Collectors.toList()); + } + // 1.4 只有未使用的可以进行工序耗材 + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> PickNormsCodeUseState.WAIT_USE.getKey() == bean.getPickUseState()) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或已被使用,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setPickUseState(PickNormsCodeUseState.USED.getKey()); + materialNormsCode.setPickState(normsCodeType.get(materialNormsCode.getCodeNum())); + }); + materialNormsCodeService.updateEntityPick(materialNormsCodeList); + } + } + if (!onlyCheck) { + // 修改部门/车间的库存 + childList.forEach(acceptChild -> { + departmentStockService.updateDepartmentStock(entity.getDepartmentId(), entity.getFarmId(), acceptChild.getMaterialId(), + acceptChild.getNormsId(), acceptChild.getOperNumber(), DepotPutOutType.OUT.getKey()); + }); + } + return allNormsCodeList; + } + + private int checkErpOrderItemDetail(List childList, Map materialMap, + Map normsMap, List allNormsCodeList, + Map normsCodeType) { + int allCodeNum = 0; + for (MachinProcedureAcceptChild acceptChild : childList) { + Material material = materialMap.get(acceptChild.getMaterialId()); + MaterialNorms norms = normsMap.get(acceptChild.getNormsId()); + if (acceptChild.getOperNumber() == 0) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的数量不能为0,请确认", material.getName(), norms.getName())); + } + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + // 过滤掉空的,并且去重 + List normsCodeList = Arrays.asList(acceptChild.getNormsCode().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (acceptChild.getOperNumber() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "商品【%s】【%s】的条形码数量与明细数量不一致,请确认", material.getName(), norms.getName())); + } + allCodeNum += normsCodeList.size(); + acceptChild.setNormsCodeList(normsCodeList); + normsCodeList.forEach(normsCode -> { + normsCodeType.put(normsCode, acceptChild.getType()); + }); + allNormsCodeList.addAll(normsCodeList); + } + } + return allCodeNum; + } + + private static void mergeAcceptChild(MachinProcedureAccept entity, List childList) { + if (CollectionUtil.isNotEmpty(entity.getMachinProcedureAcceptChildList())) { + entity.getMachinProcedureAcceptChildList().forEach(child -> { + child.setType(MachinProcedureAcceptChildType.NORMAL.getKey()); + childList.add(child); + }); + } + if (CollectionUtil.isNotEmpty(entity.getMachinScrapProcedureAcceptChildList())) { + entity.getMachinScrapProcedureAcceptChildList().forEach(child -> { + child.setType(MachinProcedureAcceptChildType.SCRAP.getKey()); + childList.add(child); + }); + } + } + + @Override + public Integer calcNumByMachinProcedureFarmId(String machinProcedureFarmId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureAccept::getMachinProcedureFarmId), machinProcedureFarmId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Machin::getState), FlowableStateEnum.PASS.getKey()); + List machinList = list(queryWrapper); + Integer allNum = machinList.stream() + .collect(Collectors.summingInt(MachinProcedureAccept::getQualifiedNum)); + return allNum; + } + + @Override + public Map> queryMachinProcedureAcceptByMachinProcedureFarmId(String... machinProcedureFarmId) { + List machinProcedureFarmIdList = Arrays.asList(machinProcedureFarmId); + if (CollectionUtil.isEmpty(machinProcedureFarmIdList)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MachinProcedureAccept::getMachinProcedureFarmId), machinProcedureFarmIdList); + List machinList = list(queryWrapper); + Map> map = machinList.stream() + .collect(Collectors.groupingBy(MachinProcedureAccept::getMachinProcedureFarmId)); + return map; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureFarmServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureFarmServiceImpl.java new file mode 100644 index 0000000..b11d663 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureFarmServiceImpl.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.machin.entity.MachinChild; +import com.skyeye.machin.service.MachinPutService; +import com.skyeye.machin.service.MachinService; +import com.skyeye.machinprocedure.classenum.MachinProcedureFarmState; +import com.skyeye.machinprocedure.classenum.MachinProcedureState; +import com.skyeye.machinprocedure.dao.MachinProcedureFarmDao; +import com.skyeye.machinprocedure.entity.MachinProcedureAccept; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; +import com.skyeye.machinprocedure.service.MachinProcedureAcceptService; +import com.skyeye.machinprocedure.service.MachinProcedureFarmService; +import com.skyeye.machinprocedure.service.MachinProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinProcedureFarmServiceImpl + * @Description: 车间任务服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 19:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车间任务", groupName = "车间任务") +public class MachinProcedureFarmServiceImpl extends SkyeyeBusinessServiceImpl implements MachinProcedureFarmService { + + @Autowired + private FarmService farmService; + + @Autowired + private MachinService machinService; + + @Autowired + private MachinProcedureService machinProcedureService; + + @Autowired + private MachinProcedureAcceptService machinProcedureAcceptService; + + @Autowired + private MachinPutService machinPutService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + if (StrUtil.isEmpty(commonPageInfo.getType())) { + throw new CustomException("type不能为空"); + } + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "farm")) { + // 指定车间的任务 + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getFarmId), commonPageInfo.getObjectId()); + } else if (StrUtil.equals(commonPageInfo.getType(), "department")) { + // 我所在部门的所有车间的任务 + String departmentId = InputObject.getLogParamsStatic().get("departmentId").toString(); + List farmIdList = farmService.queryFarmIdListByDepartmentId(departmentId); + queryWrapper.in(MybatisPlusUtil.toColumns(MachinProcedureFarm::getFarmId), farmIdList); + } else if (StrUtil.equals(commonPageInfo.getType(), "all")) { + // 所有任务 + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + machinService.setMachinMationByFromId(beans, "machinId", "machinMation"); + farmService.setMationForMap(beans, "farmId", "farmMation"); + machinProcedureService.setMationForMap(beans, "machinProcedureId", "machinProcedureMation"); + return beans; + } + + @Override + public void createPrepose(MachinProcedureFarm entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(this.getClass().getName(), business); + entity.setOddNumber(oddNumber); + } + + @Override + public void createPrepose(List entity) { + String serviceClassName = getServiceClassName(); + entity.forEach(bean -> { + Map business = BeanUtil.beanToMap(bean); + String oddNumber = iCodeRuleService.getNextCodeByClassName(serviceClassName, business); + bean.setOddNumber(oddNumber); + }); + } + + @Override + public MachinProcedureFarm selectById(String id) { + MachinProcedureFarm machinProcedureFarm = super.selectById(id); + farmService.setDataMation(machinProcedureFarm, MachinProcedureFarm::getFarmId); + machinService.setDataMation(machinProcedureFarm, MachinProcedureFarm::getMachinId); + machinProcedureService.setDataMation(machinProcedureFarm, MachinProcedureFarm::getMachinProcedureId); + return machinProcedureFarm; + } + + @Override + public List selectByIds(String... ids) { + List machinProcedureFarms = super.selectByIds(ids); + farmService.setDataMation(machinProcedureFarms, MachinProcedureFarm::getFarmId); + return machinProcedureFarms; + } + + @Override + public Map> queryMachinProcedureFarmMapByMachinId(String machinId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getMachinId), machinId); + List machinProcedureFarmList = list(queryWrapper); + if (CollectionUtil.isEmpty(machinProcedureFarmList)) { + return MapUtil.newHashMap(); + } + // 设置车间的工序验收单信息 + List ids = machinProcedureFarmList.stream().map(MachinProcedureFarm::getId).collect(Collectors.toList()); + Map> machinProcedureAcceptMap = machinProcedureAcceptService + .queryMachinProcedureAcceptByMachinProcedureFarmId(ids.toArray(new String[]{})); + machinProcedureFarmList.forEach(machinProcedureFarm -> { + machinProcedureFarm.setMachinProcedureAcceptList(machinProcedureAcceptMap.get(machinProcedureFarm.getId())); + }); + Map> machinProcedureFarmMap = machinProcedureFarmList.stream() + .collect(Collectors.groupingBy(MachinProcedureFarm::getMachinProcedureId)); + return machinProcedureFarmMap; + } + + @Override + public void receiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + MachinProcedureFarm machinProcedureFarm = selectById(id); + if (StrUtil.equals(machinProcedureFarm.getState(), MachinProcedureFarmState.WAIT_RECEIVE.getKey())) { + // 待接收的车间任务可以进行接收 + editStateById(id, MachinProcedureFarmState.WAIT_EXECUTED.getKey()); + } + } + + @Override + public void receptionReceiveMachinProcedureFarm(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + MachinProcedureFarm machinProcedureFarm = selectById(id); + if (StrUtil.equals(machinProcedureFarm.getState(), MachinProcedureFarmState.WAIT_EXECUTED.getKey())) { + // 待执行的车间任务可以进行反接收 + editStateById(id, MachinProcedureFarmState.WAIT_RECEIVE.getKey()); + } + } + + @Override + public void editStateById(String id, String state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedureFarm::getState), state); + update(updateWrapper); + if (StrUtil.equals(state, MachinProcedureFarmState.PARTIAL_COMPLETION.getKey())) { + // 部分完成 + MachinProcedureFarm machinProcedureFarm = selectById(id); + machinProcedureService.editStateById(machinProcedureFarm.getMachinProcedureId(), MachinProcedureState.PARTIAL_COMPLETION.getKey()); + } else if (StrUtil.equals(state, MachinProcedureFarmState.ALL_COMPLETED.getKey()) + || StrUtil.equals(state, MachinProcedureFarmState.EXCESS_COMPLETED.getKey())) { + // 全部完成/超额完成 + MachinProcedureFarm machinProcedureFarm = selectById(id); + // 查询该工序下是否存在未接收/未执行/部分完成的车间任务 + List stateList = Arrays.asList(new String[]{MachinProcedureFarmState.WAIT_RECEIVE.getKey(), MachinProcedureFarmState.WAIT_EXECUTED.getKey(), + MachinProcedureFarmState.PARTIAL_COMPLETION.getKey()}); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getMachinProcedureId), machinProcedureFarm.getMachinProcedureId()); + queryWrapper.in(MybatisPlusUtil.toColumns(MachinProcedureFarm::getState), stateList); + long count = count(queryWrapper); + if (count == 0) { + machinProcedureService.editStateById(machinProcedureFarm.getMachinProcedureId(), MachinProcedureState.ALL_COMPLETED.getKey()); + } else { + machinProcedureService.editStateById(machinProcedureFarm.getMachinProcedureId(), MachinProcedureState.PARTIAL_COMPLETION.getKey()); + } + } + } + + @Override + public void deleteMachinProcedureFarmByMachinProcedureId(String machinProcedureId) { + // 只删除未接收的 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getMachinProcedureId), machinProcedureId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getState), MachinProcedureFarmState.WAIT_RECEIVE.getKey()); + remove(queryWrapper); + } + + @Override + public List queryMachinProcedureFarmByMachinProcedureId(String machinProcedureId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getMachinProcedureId), machinProcedureId); + queryWrapper.ne(MybatisPlusUtil.toColumns(MachinProcedureFarm::getState), MachinProcedureFarmState.WAIT_RECEIVE.getKey()); + List machinProcedureFarmList = list(queryWrapper); + return machinProcedureFarmList; + } + + @Override + public List queryAllMachinProcedureFarmByMachinProcedureId(String machinProcedureId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedureFarm::getMachinProcedureId), machinProcedureId); + List machinProcedureFarmList = list(queryWrapper); + farmService.setDataMation(machinProcedureFarmList, MachinProcedureFarm::getFarmId); + machinProcedureFarmList.forEach(machinProcedureFarm -> { + machinProcedureFarm.setStateMation(MachinProcedureFarmState.getMation(machinProcedureFarm.getState())); + }); + return machinProcedureFarmList; + } + + @Override + public void queryMachinProcedureFarmToInOrOutList(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + MachinProcedureFarm machinProcedureFarm = selectById(id); + // 加工单子单据id + String machinChildId = machinProcedureFarm.getMachinProcedureMation().getChildId(); + // 加工单子单据信息 + MachinChild machinChild = machinProcedureFarm.getMachinMation().getMachinChildList().stream() + .filter(bean -> StrUtil.equals(bean.getId(), machinChildId)) + .findFirst().orElse(null); + if (machinChild == null) { + throw new CustomException("该车间任务未关联加工单子单据或该加工单子单据不存在"); + } + // 根据车间任务id查询已经生成加工入库单的商品数量 + Map normsNumMap = machinPutService.calcMaterialNormsNumByFromId(id); + // 计算剩余数量:加工单子单据的数量 - 已经生成的加工入库单的数量 + Integer surplusNum = machinChild.getOperNumber() + - (normsNumMap.containsKey(machinChild.getNormsId()) ? normsNumMap.get(machinChild.getNormsId()) : 0); + surplusNum = surplusNum < 0 ? 0 : surplusNum; + machinChild.setOperNumber(surplusNum); + + Map result = new HashMap<>(); + result.put("erpOrderItemList", Arrays.asList(machinChild)); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !com.skyeye.common.util.MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List entityList = list(queryWrapper); + Map entityMap = entityList.stream().collect(Collectors.toMap(MachinProcedureFarm::getId, bean -> bean)); + for (Map bean : beans) { + if (!com.skyeye.common.util.MapUtil.checkKeyIsNull(bean, idKey)) { + MachinProcedureFarm entity = entityMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureServiceImpl.java new file mode 100644 index 0000000..9671306 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/machinprocedure/service/impl/MachinProcedureServiceImpl.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.machinprocedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.machinprocedure.classenum.MachinProcedureFarmState; +import com.skyeye.machinprocedure.classenum.MachinProcedureState; +import com.skyeye.machinprocedure.dao.MachinProcedureDao; +import com.skyeye.machinprocedure.entity.MachinProcedure; +import com.skyeye.machinprocedure.entity.MachinProcedureFarm; +import com.skyeye.machinprocedure.service.MachinProcedureFarmService; +import com.skyeye.machinprocedure.service.MachinProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MachinProcedureServiceImpl + * @Description: 加工单子单据工序信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/24 15:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加工单子单据工序信息", groupName = "加工单管理") +public class MachinProcedureServiceImpl extends SkyeyeBusinessServiceImpl implements MachinProcedureService { + + @Autowired + private MachinProcedureFarmService machinProcedureFarmService; + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public MachinProcedure selectById(String id) { + MachinProcedure machinProcedure = super.selectById(id); + List machinProcedureFarmList = machinProcedureFarmService.queryAllMachinProcedureFarmByMachinProcedureId(id); + machinProcedure.setMachinProcedureFarmList(machinProcedureFarmList); + return machinProcedure; + } + + @Override + public void saveList(String parentId, List machinProcedureList) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(machinProcedureList)) { + for (MachinProcedure machinProcedure : machinProcedureList) { + machinProcedure.setParentId(parentId); + machinProcedure.setState(MachinProcedureState.WAIT_STARTED.getKey()); + } + createEntity(machinProcedureList, StrUtil.EMPTY); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void setMachinProcedureById(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + + String machinProcedureFarmListStr = params.get("machinProcedureFarmList").toString(); + List machinProcedureFarmList = new ArrayList<>(); + if (StrUtil.isNotEmpty(machinProcedureFarmListStr)) { + machinProcedureFarmList = JSONUtil.toList(machinProcedureFarmListStr, MachinProcedureFarm.class); + } + params.put("machinProcedureFarmList", null); + MachinProcedure machinProcedure = JSONUtil.toBean(JSONUtil.toJsonStr(params), MachinProcedure.class); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, machinProcedure.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedure::getPlanStartTime), machinProcedure.getPlanStartTime()); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedure::getPlanEndTime), machinProcedure.getPlanEndTime()); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedure::getActualStartTime), machinProcedure.getActualStartTime()); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedure::getActualEndTime), machinProcedure.getActualEndTime()); + update(updateWrapper); + MachinProcedure machinProcedureMation = selectById(machinProcedure.getId()); + // 处理车间任务信息 + machinProcedureFarmList.forEach(machinProcedureFarm -> { + machinProcedureFarm.setMachinId(machinProcedureMation.getParentId()); + machinProcedureFarm.setMachinProcedureId(machinProcedureMation.getId()); + machinProcedureFarm.setState(MachinProcedureFarmState.WAIT_RECEIVE.getKey()); + }); + // 获取除了【待接收】状态之外的其他车间任务 + List oldMachinProcedureFarmList = machinProcedureFarmService.queryMachinProcedureFarmByMachinProcedureId(machinProcedure.getId()); + List inSqlIds = oldMachinProcedureFarmList.stream().map(MachinProcedureFarm::getId).collect(Collectors.toList()); + // 过滤掉已经存在的不是待接收状态的车间任务 + machinProcedureFarmList = machinProcedureFarmList.stream() + .filter(machinProcedureFarm -> !inSqlIds.contains(machinProcedureFarm.getId())) + .collect(Collectors.toList()); + // 删除原有的车间任务 + machinProcedureFarmService.deleteMachinProcedureFarmByMachinProcedureId(machinProcedure.getId()); + // 保存车间任务信息 + String userId = inputObject.getLogParams().get("id").toString(); + machinProcedureFarmService.createEntity(machinProcedureFarmList, userId); + } + + @Override + public Map queryMachinProcedureMapByMachinId(String machinId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getParentId), machinId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(MachinProcedure::getOrderBy)); + List machinProcedureList = list(queryWrapper); + Map machinProcedureMap = machinProcedureList.stream().collect(Collectors.toMap(bean -> + String.format(Locale.ROOT, "%s-%s-%s-%s-%s-%s", + bean.getChildId(), bean.getBomChildId(), bean.getMaterialId(), bean.getNormsId(), bean.getWayProcedureId(), bean.getProcedureId()), bean -> bean)); + return machinProcedureMap; + } + + @Override + public void editStateById(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(MachinProcedure::getState), state); + update(updateWrapper); + } + + /** + * 判断当前工序的前置工序是否部分完成/全部完成 + * + * @param machinProcedureId 当前加工单子单据工序id + * @return true: 前置工序全部完成/部分完成; false: 前置工序未完成 + */ + @Override + public boolean checkPrevMachinProcedureIsCompleted(String machinProcedureId) { + // 查询当前加工单子单据工序的信息 + MachinProcedure machinProcedure = selectById(machinProcedureId); + // 查询当前加工单子单据工序的前置工序 + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 主要的四个条件:加工单id、子单据id、bom子单据id、工艺路线id + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getParentId), machinProcedure.getParentId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getChildId), machinProcedure.getChildId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getBomChildId), machinProcedure.getBomChildId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getWayProcedureId), machinProcedure.getWayProcedureId()); + + queryWrapper.eq(MybatisPlusUtil.toColumns(MachinProcedure::getOrderBy), machinProcedure.getOrderBy() - 1); + MachinProcedure prevMachinProcedure = getOne(queryWrapper, false); + // 判断前置工序是否完成 + if (prevMachinProcedure == null) { + // 前置工序不存在,说明当前工序是第一个工序,可以开始 + return true; + } + if (prevMachinProcedure.getState() == MachinProcedureState.PARTIAL_COMPLETION.getKey() + || prevMachinProcedure.getState() == MachinProcedureState.ALL_COMPLETED.getKey()) { + // 前置工序部分完成/全部完成,可以开始当前工序 + return true; + } + return false; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialFromType.java new file mode 100644 index 0000000..5a10985 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialFromType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaterialFromType + * @Description: 商品来源类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialFromType implements SkyeyeEnumClass { + + SELF_PRODUCED(1, "自产", true, true), + OUTSOURCING(2, "外购", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialInOrderType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialInOrderType.java new file mode 100644 index 0000000..eee19ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialInOrderType.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: MaterialInOrderType + * @Description: 商品在单据中的类型 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialInOrderType implements SkyeyeEnumClass { + + GENERAL(0, "普通", false, false), + ASSEMBLY(1, "组合件", true, true), + GENERAL_SUBASSEMBLY(2, "普通子件", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer type) { + for (MaterialInOrderType bean : MaterialInOrderType.values()) { + if (type == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialItemCode.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialItemCode.java new file mode 100644 index 0000000..72ff8b1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialItemCode.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaterialItemCode + * @Description: 商品条形码开启类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/3 14:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialItemCode implements SkyeyeEnumClass { + + DISABLE(0, "禁用", true, true), + ONE_ITEM_CODE(1, "一物一码", true, false), + BY_BATCH(2, "按批次", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeInDepot.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeInDepot.java new file mode 100644 index 0000000..1e2e893 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeInDepot.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: MaterialNormsCodeInDepot + * @Description: 商品规格一物一码库存状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialNormsCodeInDepot implements SkyeyeEnumClass { + + NOT_IN_STOCK(1, "未入库", true, false), + WAREHOUSING(2, "入库", true, false), + OUTBOUND(3, "出库", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (MaterialNormsCodeInDepot bean : MaterialNormsCodeInDepot.values()) { + if (state == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeType.java new file mode 100644 index 0000000..8ec01bb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsCodeType.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import cn.hutool.core.map.MapUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: MaterialNormsCodeType + * @Description: 商品规格一物一码类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/25 11:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialNormsCodeType implements SkyeyeEnumClass { + + AUTHENTIC(1, "正品", true, false), + SCRAP_REPORTING(2, "报废品", true, false), + DEFECTIVE_PRODUCTS(3, "残次品", true, false), + SECOND_HAND_GOODS(4, "二手商品", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (MaterialNormsCodeType bean : MaterialNormsCodeType.values()) { + if (state == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + + public static Map getMation(Integer type) { + for (MaterialNormsCodeType bean : MaterialNormsCodeType.values()) { + if (type == bean.getKey()) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsStockType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsStockType.java new file mode 100644 index 0000000..76af67a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialNormsStockType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaterialNormsStockType + * @Description: 商品规格库存类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialNormsStockType implements SkyeyeEnumClass { + + INIT_STOCK(1, "初始化库存", true, true), + ORDER_STOCK(2, "单据操作的库存", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialShelvesState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialShelvesState.java new file mode 100644 index 0000000..bf18592 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialShelvesState.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import cn.hutool.core.map.MapUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: MaterialShelvesState + * @Description: 商品上下架状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 8:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialShelvesState implements SkyeyeEnumClass { + NOT_ON_SHELVE(1, "未上架", "red", true, false), + PART_ON_SHELVE(2, "部分上架", "blue", true, false), + ON_SHELVE(3, "全部上架", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + + public static Map getMation(Integer type) { + for (MaterialShelvesState bean : MaterialShelvesState.values()) { + if (type == bean.getKey()) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialType.java new file mode 100644 index 0000000..d0e43ad --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaterialType + * @Description: 商品类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialType implements SkyeyeEnumClass { + + FINISHED_PRODUCT(1, "成品", true, true), + PARTIALLY_PREPARED_PRODUCTS(2, "半成品", true, false), + MATTER(3, "物料", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialUnit.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialUnit.java new file mode 100644 index 0000000..d01ff09 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/classenum/MaterialUnit.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MaterialUnit + * @Description: 规格类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MaterialUnit implements SkyeyeEnumClass { + + SINGLE_SPECIFICATION(1, "单规格", true, true), + MULTI_SPECIFICATION(2, "多规格", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialController.java new file mode 100644 index 0000000..b7ae253 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialController.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialChooseQueryDo; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaterialController + * @Description: 商品管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商品管理", tags = "商品管理", modelName = "商品管理") +public class MaterialController { + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @ApiOperation(id = "material001", value = "获取商品信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MaterialController/queryMaterialList") + public void queryMaterialList(InputObject inputObject, OutputObject outputObject) { + materialService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeMaterialMation", value = "新增/编辑商品信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Material.class) + @RequestMapping("/post/MaterialController/writeMaterialMation") + public void writeMaterialMation(InputObject inputObject, OutputObject outputObject) { + materialService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "material006", value = "删除商品信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/deleteMaterialById") + public void deleteMaterialById(InputObject inputObject, OutputObject outputObject) { + materialService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "material010", value = "获取商品列表信息展示为表格方便选择", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MaterialChooseQueryDo.class) + @RequestMapping("/post/MaterialController/queryMaterialListToTable") + public void queryMaterialListToTable(InputObject inputObject, OutputObject outputObject) { + materialService.queryMaterialListToTable(inputObject, outputObject); + } + + @ApiOperation(id = "material011", value = "根据商品规格id以及仓库id获取库存", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "normsIds", name = "normsIds", value = "规格id,多个用逗号隔开", required = "required"), + @ApiImplicitParam(id = "depotId", name = "depotId", value = "仓库id")}) + @RequestMapping("/post/MaterialController/queryMaterialTockByNormsId") + public void queryMaterialTockByNormsId(InputObject inputObject, OutputObject outputObject) { + materialService.queryMaterialTockByNormsId(inputObject, outputObject); + } + + @ApiOperation(id = "queryMaterialListById", value = "根据id获取商品信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/queryMaterialListById") + public void queryMaterialListById(InputObject inputObject, OutputObject outputObject) { + materialService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "queryMaterialListByIds", value = "根据id批量获取商品信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/queryMaterialListByIds") + public void queryMaterialListByIds(InputObject inputObject, OutputObject outputObject) { + materialService.selectByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryMaterialNormsListByIds", value = "根据规格id批量获取产品规格信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/queryMaterialNormsListByIds") + public void queryMaterialNormsListById(InputObject inputObject, OutputObject outputObject) { + materialNormsService.selectByIds(inputObject, outputObject); + } + + @ApiOperation(id = "material016", value = "获取商品库存信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = MaterialChooseQueryDo.class) + @RequestMapping("/post/MaterialController/queryMaterialReserveList") + public void queryMaterialReserveList(InputObject inputObject, OutputObject outputObject) { + materialService.queryMaterialReserveList(inputObject, outputObject); + } + + @ApiOperation(id = "material017", value = "获取预警商品库存信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MaterialController/queryMaterialInventoryWarningList") + public void queryMaterialInventoryWarningList(InputObject inputObject, OutputObject outputObject) { + materialService.queryMaterialInventoryWarningList(inputObject, outputObject); + } + + @ApiOperation(id = "queryAllMaterialList", value = "获取所有商品列表", method = "GET", allUse = "2") + @RequestMapping("/post/MaterialController/queryAllMaterialList") + public void queryAllMaterialList(InputObject inputObject, OutputObject outputObject) { + materialService.queryAllMaterialList(inputObject, outputObject); + } + + @ApiOperation(id = "queryNormsListByMaterialId", value = "根据产品id获取规格信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "materialId", name = "materialId", value = "产品id")}) + @RequestMapping("/post/MaterialController/queryNormsListByMaterialId") + public void queryNormsListByMaterialId(InputObject inputObject, OutputObject outputObject) { + materialNormsService.queryNormsListByMaterialId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeController.java new file mode 100644 index 0000000..764264b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeController.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.MaterialNormsCodeQueryDo; +import com.skyeye.material.service.MaterialNormsCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaterialNormsCodeController + * @Description: 商品条形码控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 14:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商品条形码", tags = "商品条形码", modelName = "商品管理") +public class MaterialNormsCodeController { + + @Autowired + private MaterialNormsCodeService materialNormsCodeService; + + /** + * 获取商品规格一物一码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMaterialNormsCodeList", value = "获取商品规格一物一码信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MaterialNormsCodeQueryDo.class) + @RequestMapping("/post/MaterialNormsCodeController/queryMaterialNormsCodeList") + public void queryMaterialNormsCodeList(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.queryPageList(inputObject, outputObject); + } + + /** + * 生成条形码 + * 自动过滤不需要生成条形码的商品 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertMaterialNormsCode", value = "生成条形码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "list", name = "list", value = "商品信息,必须包含materialId,normsId,operNumber", required = "required,json")}) + @RequestMapping("/post/MaterialNormsCodeController/insertMaterialNormsCode") + public void insertMaterialNormsCode(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.insertMaterialNormsCode(inputObject, outputObject); + } + + /** + * 删除商品条形码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMaterialNormsCodeById", value = "删除商品条形码", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialNormsCodeController/deleteMaterialNormsCodeById") + public void deleteMaterialNormsCodeById(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.deleteById(inputObject, outputObject); + } + + /** + * 根据条件获取条形码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNormsBarCodeList", value = "根据条件获取条形码信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MaterialNormsCodeQueryDo.class) + @RequestMapping("/post/MaterialNormsCodeController/queryNormsBarCodeList") + public void queryNormsBarCodeList(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.queryNormsBarCodeList(inputObject, outputObject); + } + + /** + * 获取物料库存明细信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryNormsStockDetailList", value = "获取物料库存明细信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MaterialNormsCodeQueryDo.class) + @RequestMapping("/post/MaterialNormsCodeController/queryNormsStockDetailList") + public void queryNormsStockDetailList(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.queryNormsStockDetailList(inputObject, outputObject); + } + + /** + * 获取门店物料库存明细信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStoreNormsStockDetailList", value = "获取门店物料库存明细信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = MaterialNormsCodeQueryDo.class) + @RequestMapping("/post/MaterialNormsCodeController/queryStoreNormsStockDetailList") + public void queryStoreNormsStockDetailList(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.queryStoreNormsStockDetailList(inputObject, outputObject); + } + + /** + * 根据编码等信息查询门店规格条形码信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMaterialNormsCode", value = "根据编码等信息查询门店规格条形码信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id", required = "required"), + @ApiImplicitParam(id = "normsCodeList", name = "normsCodeList", value = "规格编码,多个用逗号隔开", required = "required"), + @ApiImplicitParam(id = "storeUseState", name = "storeUseState", value = "门店使用状态")}) + @RequestMapping("/post/MaterialNormsCodeController/queryMaterialNormsCode") + public void queryMaterialNormsCode(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.queryMaterialNormsCode(inputObject, outputObject); + } + + /** + * 根据编码等信息修改门店规格条形码使用状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editStoreMaterialNormsCodeUseState", value = "根据编码等信息修改门店规格条形码使用状态", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "规格条形码信息id,多个逗号隔开", required = "required,json"), + @ApiImplicitParam(id = "storeUseState", name = "storeUseState", value = "门店使用状态", required = "required")}) + @RequestMapping("/post/MaterialNormsCodeController/editStoreMaterialNormsCodeUseState") + public void editStoreMaterialNormsCodeUseState(InputObject inputObject, OutputObject outputObject) { + materialNormsCodeService.editStoreMaterialNormsCodeUseState(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeHisController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeHisController.java new file mode 100644 index 0000000..4358ff9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialNormsCodeHisController.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.material.service.MaterialNormsCodeHisService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaterialNormsCodeHisController + * @Description: 商品规格一物一码条形码变更历史 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 17:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商品条形码变更历史", tags = "商品条形码变更历史", modelName = "商品管理") +public class MaterialNormsCodeHisController { + + @Autowired + private MaterialNormsCodeHisService materialNormsCodeHisService; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialUnitGroupController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialUnitGroupController.java new file mode 100644 index 0000000..e71b5b7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/controller/MaterialUnitGroupController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.unit.MaterialUnitGroup; +import com.skyeye.material.service.MaterialUnitGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaterialUnitGroupController + * @Description: 计量单位管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "计量单位", tags = "计量单位", modelName = "计量单位") +public class MaterialUnitGroupController { + + @Autowired + private MaterialUnitGroupService materialUnitGroupService; + + /** + * 获取计量单位列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "materialunit001", value = "获取计量单位列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MaterialUnitGroupController/queryMaterialUnitList") + public void queryMaterialUnitList(InputObject inputObject, OutputObject outputObject) { + materialUnitGroupService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑计量单位 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMaterialUnitMation", value = "新增/编辑计量单位", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = MaterialUnitGroup.class) + @RequestMapping("/post/MaterialUnitGroupController/writeMaterialUnitMation") + public void writeMaterialUnitMation(InputObject inputObject, OutputObject outputObject) { + materialUnitGroupService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除计量单位 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "materialunit003", value = "删除计量单位", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "计量单位组id", required = "required")}) + @RequestMapping("/post/MaterialUnitGroupController/deleteMaterialUnitMationById") + public void deleteMaterialUnitMationById(InputObject inputObject, OutputObject outputObject) { + materialUnitGroupService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有的计量单位 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "materialunit006", value = "获取所有的计量单位", method = "GET", allUse = "2") + @RequestMapping("/post/MaterialUnitGroupController/queryAllMaterialUnitList") + public void queryAllMaterialUnitList(InputObject inputObject, OutputObject outputObject) { + materialUnitGroupService.queryAllMaterialUnitList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java new file mode 100644 index 0000000..93015f0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.Material; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialDao + * @Description: 商品信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialDao extends SkyeyeBaseMapper { + + List> queryMaterialInventoryWarningList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeDao.java new file mode 100644 index 0000000..e6a8302 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.MaterialNormsCode; + +/** + * @ClassName: MaterialNormsCodeDao + * @Description: 商品条形码数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 8:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeHisDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeHisDao.java new file mode 100644 index 0000000..4895d7d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsCodeHisDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.MaterialNormsCodeHis; + +/** + * @ClassName: MaterialNormsCodeHisDao + * @Description: 商品规格一物一码条形码变更历史数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 17:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsCodeHisDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsDao.java new file mode 100644 index 0000000..dc78331 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.MaterialNorms; + +/** + * @ClassName: MaterialNormsDao + * @Description: ERP商品规格参数数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 10:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsStockDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsStockDao.java new file mode 100644 index 0000000..94f7db4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialNormsStockDao.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.MaterialNormsStock; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialNormsStockDao + * @Description: ERP商品规格初始化库存数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 17:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsStockDao extends SkyeyeBaseMapper { + + /** + * 查询指定仓库某个规格商品的库存 + * + * @param normsIds 规格id集合 + * @param depotId 仓库id + * @return {currentTock: 库存数量, normsId: 规格id} + */ + List> queryMaterialStockByNormsId(@Param("normsIds") List normsIds, @Param("depotId") String depotId); + + /** + * 根据规格id获取初始化库存信息 + * + * @param normsIds 规格id集合 + * @param type 类型 1.初始化库存 2.单据操作的库存 + * @return + */ + List queryNormsStockByNormsId(@Param("normsIds") List normsIds, @Param("depotId") String depotId, @Param("type") Integer type); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialProcedureDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialProcedureDao.java new file mode 100644 index 0000000..759e80c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialProcedureDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.MaterialProcedure; + +/** + * @ClassName: MaterialProcedureDao + * @Description: ERP商品表与工序管理的关系数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 11:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialProcedureDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitDao.java new file mode 100644 index 0000000..a5c9a2b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.unit.MaterialUnit; + +/** + * @ClassName: MaterialUnitDao + * @Description: 计量单位信息数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/30 11:34 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialUnitDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitGroupDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitGroupDao.java new file mode 100644 index 0000000..3c1dbb7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/dao/MaterialUnitGroupDao.java @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.unit.MaterialUnitGroup; + +public interface MaterialUnitGroupDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/Material.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/Material.java new file mode 100644 index 0000000..1ecde33 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/Material.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.brand.entity.Brand; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.material.entity.unit.MaterialUnit; +import com.skyeye.material.entity.unit.MaterialUnitGroup; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Material + * @Description: 商品信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 15:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.ERP_MATERIAL_CACHE_KEY) +@TableName(value = "erp_material", autoResultMap = true) +@ApiModel("商品信息") +public class Material extends BaseGeneralInfo { + + @TableField(value = "category_id") + @ApiModelProperty(value = "所属分类id", required = "required") + private String categoryId; + + @TableField(value = "unit") + @ApiModelProperty(value = "规格类型,参考#MaterialUnit", required = "required,num") + private Integer unit; + + @TableField(value = "model") + @ApiModelProperty(value = "型号", required = "required", fuzzyLike = true) + private String model; + + @TableField(value = "unit_name") + @ApiModelProperty(value = "计量单位 当unit=1时,必有") + private String unitName; + + @TableField(value = "unit_group_id") + @ApiModelProperty(value = "计量单位组id 当unit=2时,必填") + private String unitGroupId; + + @TableField(exist = false) + @Property(value = "计量单位组信息 当unit=2时,必有") + private MaterialUnitGroup unitGroupMation; + + @TableField(value = "first_in_unit") + @ApiModelProperty(value = "首选入库单位") + private String firstInUnit; + + @TableField(exist = false) + @Property(value = "首选入库单位信息") + private MaterialUnit firstInUnitMation; + + @TableField(value = "first_out_unit") + @ApiModelProperty(value = "首选出库单位") + private String firstOutUnit; + + @TableField(exist = false) + @Property(value = "首选出库单位信息") + private MaterialUnit firstOutUnitMation; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(value = "norms_spec", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "商品规格类型,多规格时具备该数据") + private List> normsSpec; + + @TableField(exist = false) + @ApiModelProperty(value = "商品规格信息", required = "required,json") + private List materialNorms; + + @TableField(value = "from_type") + @ApiModelProperty(value = "商品来源类型,参考#MaterialFromType", required = "required,num") + private Integer fromType; + + @TableField(value = "`type`") + @ApiModelProperty(value = "商品类型,参考#MaterialType", required = "required,num") + private Integer type; + + @TableField(value = "item_code", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "条形码开启类型,参考#MaterialItemCode") + private Integer itemCode; + + @TableField(exist = false) + @ApiModelProperty(value = "工序的json字符串") + private List materialProcedure; + + @TableField("is_used") + @Property(value = "是否使用中,参考#IsUsedEnum") + private Integer isUsed; + + @TableField(value = "shelves_state") + @Property(value = "上下架状态,参考#MaterialShelvesState") + private Integer shelvesState; + + @TableField(value = "brand_id") + @ApiModelProperty(value = "品牌id") + private String brandId; + + @TableField(exist = false) + @ApiModelProperty(value = "品牌信息") + private Brand brandMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialChooseQueryDo.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialChooseQueryDo.java new file mode 100644 index 0000000..3435774 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialChooseQueryDo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: MaterialChooseQueryDo + * @Description: 列表信息展示为选择性表格列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 21:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("列表信息展示为选择性表格列表查询条件实体类") +public class MaterialChooseQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "所属分类id") + private String categoryId; + + @ApiModelProperty(value = "仓库id") + private String depotId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNorms.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNorms.java new file mode 100644 index 0000000..3b6fd31 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNorms.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: MaterialNormsMation + * @Description: ERP商品规格参数实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.ERP_NORMS_CACHE_KEY) +@TableName(value = "erp_material_norms") +@ApiModel("ERP商品规格参数实体类") +public class MaterialNorms extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @Property(value = "规格名称") + private String name; + + @TableField(value = "material_id") + @Property(value = "商品id") + private String materialId; + + @TableField(value = "logo") + @ApiModelProperty(value = "商品规格图片") + private String logo; + + @TableField(value = "table_num") + @ApiModelProperty(value = "商品规格编号,同一个商品下唯一。多规格的商品具备该字段") + private String tableNum; + + @TableField(value = "safety_tock") + @ApiModelProperty(value = "安全存量,当库存低于这个存量时,做邮件等提醒", required = "required,num") + private String safetyTock; + + @TableField(value = "retail_price") + @ApiModelProperty(value = "零售价", required = "required,double") + private String retailPrice; + + @TableField(value = "low_price") + @ApiModelProperty(value = "最低售价", required = "required,double") + private String lowPrice; + + @TableField(value = "estimate_purchase_price") + @ApiModelProperty(value = "采购价/成本价", required = "required,double") + private String estimatePurchasePrice; + + @TableField(value = "sale_price") + @ApiModelProperty(value = "销售价", required = "required,double") + private String salePrice; + + @TableField(exist = false) + @ApiModelProperty(value = "规格初始化库存信息") + private List normsStock; + + @TableField(exist = false) + @Property(value = "单据操作的库存信息") + private List orderStock; + + @TableField(value = "enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField(exist = false) + @Property(value = "总库存") + private NormsCalcStock overAllStock; + + @TableField(exist = false) + @Property(value = "指定仓库的库存") + private NormsCalcStock depotTock; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCode.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCode.java new file mode 100644 index 0000000..30ab09f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCode.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.depot.entity.Depot; +import com.skyeye.farm.entity.Farm; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: MaterialNormsCode + * @Description: 商品条形码实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 8:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_material_norms_code") +@ApiModel("商品条形码实体类") +public class MaterialNormsCode extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @Property(value = "规格物品编码", fuzzyLike = true) + private String codeNum; + + @TableField(value = "material_id", updateStrategy = FieldStrategy.NEVER) + @Property("商品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id", updateStrategy = FieldStrategy.NEVER) + @Property("规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "depot_id") + @Property(value = "仓库id") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "department_id") + @ApiModelProperty(value = "部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间id") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField("pick_use_state") + @Property(value = "加工时,物料使用状态,参考#PickNormsCodeUseState") + private Integer pickUseState; + + @TableField("pick_state") + @Property(value = "加工使用结果状态,参考#MachinProcedureAcceptChildType") + private Integer pickState; + + @TableField(value = "store_id") + @Property(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + + @TableField("store_use_state") + @Property(value = "门店使用状态,参考#StoreNormsCodeUseState") + private Integer storeUseState; + + @TableField(value = "in_depot") + @Property(value = "库存状态,参考#MaterialNormsCodeInDepot") + private Integer inDepot; + + @TableField(value = "type") + @Property(value = "类型,参考#MaterialNormsCodeType") + private Integer type; + + @TableField(value = "from_object_id") + @Property(value = "来源单据的id") + private String fromObjectId; + + @TableField(value = "from_object_key") + @Property(value = "来源单据的key") + private String fromObjectKey; + + @TableField(value = "warehousing_time") + @Property(value = "入库时间") + private String warehousingTime; + + @TableField(value = "to_object_id") + @Property(value = "出库单据的id") + private String toObjectId; + + @TableField(value = "to_object_key") + @Property(value = "出库单据的key") + private String toObjectKey; + + @TableField(value = "outbound_time") + @Property(value = "出库时间") + private String outboundTime; + + @TableField(exist = false) + @Property(value = "条形码信息") + private Map barCodeMation; + + @TableField(value = "create_time", updateStrategy = FieldStrategy.NEVER) + @Property(value = "创建时间") + private String createTime; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeHis.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeHis.java new file mode 100644 index 0000000..63776d4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeHis.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: MaterialNormsCodeHis + * @Description: 商品规格一物一码条形码变更历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 17:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_material_norms_code_his") +@ApiModel("商品规格一物一码条形码变更历史实体类") +public class MaterialNormsCodeHis extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "norms_code_id", updateStrategy = FieldStrategy.NEVER) + @Property("条形码id") + private String normsCodeId; + + @TableField(value = "type") + @Property(value = "类型,参考#MaterialNormsCodeType") + private Integer type; + + @TableField(value = "operator_id") + @Property(value = "操作单据id") + private String operatorId; + + @TableField(value = "operator_key") + @Property(value = "操作单据的key") + private String operatorKey; + + @TableField(value = "operator_time") + @Property(value = "操作时间") + private String operatorTime; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeQueryDo.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeQueryDo.java new file mode 100644 index 0000000..08cef8c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsCodeQueryDo.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: MaterialNormsCodeQueryDo + * @Description: 商品规格一物一码查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 21:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("商品规格一物一码查询条件实体类") +public class MaterialNormsCodeQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "产品id") + private String materialId; + + @ApiModelProperty("规格id") + private String normsId; + + @ApiModelProperty(value = "部门id") + private String departmentId; + + @ApiModelProperty(value = "车间id") + private String farmId; + + @ApiModelProperty(value = "仓库id") + private String depotId; + + @ApiModelProperty(value = "来源单据的id") + private String fromObjectId; + + @ApiModelProperty(value = "出库单据的id") + private String toObjectId; + + @ApiModelProperty(value = "库存状态,参考#MaterialNormsCodeInDepot") + private Integer inDepot; + + @ApiModelProperty(value = "加工时,物料使用状态,参考#PickNormsCodeUseState") + private Integer pickUseState; + + @ApiModelProperty(value = "加工使用结果状态,参考#MachinProcedureAcceptChildType") + private Integer pickState; + + @ApiModelProperty(value = "获取的数量") + private Integer number; + + @ApiModelProperty(value = "门店ID") + private String storeId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsStock.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsStock.java new file mode 100644 index 0000000..5dd31b7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialNormsStock.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.classenum.MaterialNormsStockType; +import lombok.Data; + +/** + * @ClassName: MaterialNormsStock + * @Description: 规格初始化库存信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 15:06 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_material_norms_stock") +@ApiModel("ERP规格初始化库存信息") +public class MaterialNormsStock extends CommonInfo { + + @TableField(value = "material_id") + @Property("商品id") + private String materialId; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "norms_id") + @Property("规格id") + private String normsId; + + @TableField(value = "stock") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer stock; + + @TableField(value = "type") + @Property("商品规格库存类型,参考#MaterialNormsStockType") + private Integer type = MaterialNormsStockType.INIT_STOCK.getKey(); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialProcedure.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialProcedure.java new file mode 100644 index 0000000..d3bb7b5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/MaterialProcedure.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.procedure.entity.WorkProcedure; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: MaterialProcedure + * @Description: ERP商品表与工序管理的关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_material_procedure") +@ApiModel("ERP商品表与工序管理的关系实体类") +public class MaterialProcedure extends OperatorUserInfo implements Serializable { + + @Property(value = "商品id") + @TableField(value = "material_id") + private String materialId; + + @TableField(value = "procedure_id") + @ApiModelProperty(value = "工序id", required = "required") + private String procedureId; + + @TableField(exist = false) + @Property(value = "工序") + private WorkProcedure procedureMation; + + @TableField("unit_price") + @ApiModelProperty(value = "商品关联工序的单价", required = "required,double") + private String unitPrice; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/NormsCalcStock.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/NormsCalcStock.java new file mode 100644 index 0000000..cfab451 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/NormsCalcStock.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: NormsCalcStock + * @Description: ERP商品规格库存实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("ERP商品规格参数实体类") +public class NormsCalcStock extends CommonInfo { + + @Property(value = "总库存") + private Integer allStock; + + @Property(value = "初始化的总库存") + private Integer initialTock; + + @Property(value = "可盘点的总库存") + private Integer inventoryTock; + + public NormsCalcStock(int allStock, int initialTock, int inventoryTock) { + this.allStock = allStock; + this.initialTock = initialTock; + this.inventoryTock = inventoryTock; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnit.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnit.java new file mode 100644 index 0000000..0c13b72 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnit.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity.unit; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: MaterialUnit + * @Description: 计量单位实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 15:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"groupId", "name"}) +@RedisCacheField(name = "erp:unit") +@TableName(value = "erp_unit") +@ApiModel("计量单位实体类") +public class MaterialUnit extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "计量单位名称", required = "required") + private String name; + + @TableField(value = "number") + @ApiModelProperty(value = "单位换算 例如:一箱=12瓶,则该字段为12", required = "required,num") + private Integer number; + + /** + * 所属分组id + */ + @TableField(value = "group_id") + private String groupId; + + @TableField(value = "base_unit") + @ApiModelProperty(value = "是否是基础单位,参考#WhetherEnum", required = "required,num") + private Integer baseUnit; + + @TableField(exist = false) + @Property(value = "是否是基础单位") + private Map baseUnitMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnitGroup.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnitGroup.java new file mode 100644 index 0000000..219bb34 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/entity/unit/MaterialUnitGroup.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity.unit; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: MaterialUnitGroup + * @Description: 计量单位分组实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 15:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "erp:unitGroup") +@TableName(value = "erp_unit_group") +@ApiModel("计量单位分组实体类") +public class MaterialUnitGroup extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "组名称", required = "required") + private String name; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @ApiModelProperty(value = "计量单位信息", required = "required,json") + private List unitList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeHisService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeHisService.java new file mode 100644 index 0000000..0842555 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeHisService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.material.entity.MaterialNormsCodeHis; + +/** + * @ClassName: MaterialNormsCodeHisService + * @Description: 商品规格一物一码条形码变更历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 17:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsCodeHisService extends SkyeyeBusinessService { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeService.java new file mode 100644 index 0000000..ac62c3f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsCodeService.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.MaterialNormsCode; + +import java.util.List; + +/** + * @ClassName: MaterialNormsCodeService + * @Description: 商品条形码服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 8:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsCodeService extends SkyeyeBusinessService { + + void insertMaterialNormsCode(InputObject inputObject, OutputObject outputObject); + + /** + * 根据编码获取未入库的编码信息 + * + * @param depotId 仓库id + * @param codeNumList 编码 + * @param indepot 库存状态 + * @return + */ + List queryMaterialNormsCodeByCodeNum(String depotId, List codeNumList, Integer... indepot); + + /** + * 获取仓库中指定商品规格的编码信息 + * + * @param depotId 仓库id + * @param normsId 商品id + * @param type 类型 + * @param indepot 库存状态 + * @return + */ + List queryMaterialNormsCode(String depotId, String normsId, Integer type, Integer indepot); + + void queryNormsBarCodeList(InputObject inputObject, OutputObject outputObject); + + /** + * 修改条形码物料状态信息 + * + * @param materialNormsCodeList + */ + void updateEntityPick(List materialNormsCodeList); + + void queryNormsStockDetailList(InputObject inputObject, OutputObject outputObject); + + void queryStoreNormsStockDetailList(InputObject inputObject, OutputObject outputObject); + + void queryMaterialNormsCode(InputObject inputObject, OutputObject outputObject); + + void editStoreMaterialNormsCodeUseState(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsService.java new file mode 100644 index 0000000..5413971 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsService.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialNormsService + * @Description: ERP商品规格参数服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 15:38 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsService extends SkyeyeBusinessService { + + void saveMaterialNorms(String userId, Material material); + + /** + * 根据商品id删除规格信息 + * + * @param materialId 商品id + */ + void deleteMaterialNormsByMaterialId(String materialId); + + /** + * 根据产品id批量获取产品规格单位信息 + * + * @param depotId 仓库id + * @param materialIds 商品id + * @return + */ + Map> queryMaterialNormsList(String depotId, String... materialIds); + + MaterialNorms queryMaterialNorms(String normsId, String depotId); + + /** + * 根据产品id获取规格信息(包含规格所属单位信息) + * + * @param materialId 商品id + * @return + */ + List queryNormsUnitListByMaterialId(String materialId); + + void calcDepotStock(MaterialNorms materialNorms, String depotId); + + void queryNormsListByMaterialId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsStockService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsStockService.java new file mode 100644 index 0000000..010846c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialNormsStockService.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.material.entity.MaterialNormsStock; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialNormsStockService + * @Description: ERP商品规格初始化库存服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 17:47 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialNormsStockService extends SkyeyeBusinessService { + + /** + * 根据商品id删除对应的初始化库存信息 + * + * @param materialId 商品id + */ + void deleteNormsInitStockByMaterialId(String materialId); + + /** + * 根据规格id获取商品规格的当前库存信息 + * + * @param normsIds 规格id集合 + * @param depotId 仓库id + * @return + */ + Map queryMaterialNormsStock(List normsIds, String depotId); + + /** + * 批量获取指定规格的初始化库存信息 + * + * @param normsIds 规格id集合 + * @return + */ + Map> queryNormsStockByNormsId(List normsIds, Integer type); + + /** + * 根据规格id设置商品规格的当前库存信息 + * + * @param beans 返回对象的集合 + * @param pointNormsIdKey 指定的normsId的key + * @param depotId 仓库id + */ + void restMaterialNormCurrentTock(List> beans, String pointNormsIdKey, String depotId); + + /** + * 根据规格id设置商品规格的当前库存信息 + * + * @param bean 返回对象的集合 + * @param pointNormsIdKey 指定的normsId的key + * @param depotId 仓库id + */ + void restMaterialNormCurrentTock(Map bean, String pointNormsIdKey, String depotId); + + /** + * 保存由单据操作生成的库存信息 + * + * @param materialId 商品id + * @param depotId 仓库id + * @param normsId 规格id + * @param stock 库存数量 + */ + Integer saveMaterialNormsOrderStock(String materialId, String depotId, String normsId, int stock); + + /** + * 保存初始化库存信息 + * + * @param materialId + * @param normsStock + * @param userId + */ + void saveMaterialNormsInitStock(String materialId, List normsStock, String userId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialProcedureService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialProcedureService.java new file mode 100644 index 0000000..8363faa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialProcedureService.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.material.entity.MaterialProcedure; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialProcedureService + * @Description: ERP商品表与工序管理的关系服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 22:44 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialProcedureService extends SkyeyeBusinessService { + + /** + * 根据商品id删除关联的工序信息 + * + * @param materialId 商品id + */ + void deleteMaterialProcedureByMaterialId(String materialId); + + /** + * 保存商品与工序的关联关系信息 + * + * @param materialId + * @param materialProcedureList + * @param userId + */ + void saveMaterialProcedure(String materialId, List materialProcedureList, String userId); + + /** + * 根据商品id查询关联的工序信息 + * + * @param materialId 商品id + */ + List queryMaterialProcedureByMaterialId(String materialId); + + /** + * 根据商品id查询关联的工序信息 + * + * @param materialIds 商品id + */ + Map> queryMaterialProcedureByMaterialIds(List materialIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialService.java new file mode 100644 index 0000000..846c498 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.Material; + +/** + * @ClassName: MaterialService + * @Description: 商品信息管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialService extends SkyeyeBusinessService { + + void queryMaterialListToTable(InputObject inputObject, OutputObject outputObject); + + void queryMaterialTockByNormsId(InputObject inputObject, OutputObject outputObject); + + void queryMaterialReserveList(InputObject inputObject, OutputObject outputObject); + + void queryMaterialInventoryWarningList(InputObject inputObject, OutputObject outputObject); + + void queryAllMaterialList(InputObject inputObject, OutputObject outputObject); + + /** + * 设置为使用中 + * + * @param id + */ + void setUsed(String id); + + void setShelvesState(String id, Integer shelvesState); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitGroupService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitGroupService.java new file mode 100644 index 0000000..80c0f88 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitGroupService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.unit.MaterialUnitGroup; + +/** + * @ClassName: MaterialUnitGroupService + * @Description: 计量单位分组服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/23 15:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialUnitGroupService extends SkyeyeBusinessService { + + void queryAllMaterialUnitList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitService.java new file mode 100644 index 0000000..1701465 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/MaterialUnitService.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.material.entity.unit.MaterialUnit; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MaterialUnitService + * @Description: 计量单位信息接口服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/30 11:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialUnitService extends SkyeyeBusinessService { + + /** + * 批量保存计量单位信息 + * + * @param unitList 计量单位信息 + * @param userId 用户id + * @param groupId 所属组id + */ + void saveBatchList(List unitList, String userId, String groupId); + + /** + * 查询组下的所有计量单位信息 + * + * @param groupId 所属组id + * @return 计量单位信息 + */ + List queryUnitListByGroupId(String groupId); + + /** + * 根据所属组id删除组下面的计量单位信息 + * + * @param groupId 所属组id + */ + void deleteByGroupId(String groupId); + + /** + * 根据组id集合批量查询计量单位信息 + * + * @param groupIds 组id集合 + * @return + */ + Map> queryUnitListByGroupId(List groupIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeHisServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeHisServiceImpl.java new file mode 100644 index 0000000..ac6a381 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeHisServiceImpl.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.material.dao.MaterialNormsCodeHisDao; +import com.skyeye.material.entity.MaterialNormsCodeHis; +import com.skyeye.material.service.MaterialNormsCodeHisService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: MaterialNormsCodeHisServiceImpl + * @Description: 商品规格一物一码条形码变更历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 17:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品条形码变更历史", groupName = "商品管理") +public class MaterialNormsCodeHisServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialNormsCodeHisService { + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeServiceImpl.java new file mode 100644 index 0000000..14a6d7e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsCodeServiceImpl.java @@ -0,0 +1,346 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.PropertiesUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IBarCodeService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.dao.MaterialNormsCodeDao; +import com.skyeye.material.entity.*; +import com.skyeye.material.service.MaterialNormsCodeHisService; +import com.skyeye.material.service.MaterialNormsCodeService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.PickNormsCodeUseState; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.classenum.StoreNormsCodeUseState; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialNormsCodeServiceImpl + * @Description: 商品条形码服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 8:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品条形码", groupName = "商品管理") +public class MaterialNormsCodeServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialNormsCodeService { + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private ErpDepotService erpDepotService; + + @Autowired + private IBarCodeService iBarCodeService; + + @Autowired + private MaterialNormsCodeHisService materialNormsCodeHisService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private FarmService farmService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public void getQueryWrapper(InputObject inputObject, QueryWrapper wrapper) { + setCustomerWrapper(inputObject, wrapper); + } + + private static void setCustomerWrapper(InputObject inputObject, QueryWrapper wrapper) { + MaterialNormsCodeQueryDo commonPageInfo = inputObject.getParams(MaterialNormsCodeQueryDo.class); + if (StrUtil.isNotEmpty(commonPageInfo.getMaterialId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getMaterialId), commonPageInfo.getMaterialId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getNormsId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getNormsId), commonPageInfo.getNormsId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getDepotId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getDepotId), commonPageInfo.getDepotId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromObjectId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getFromObjectId), commonPageInfo.getFromObjectId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getToObjectId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getToObjectId), commonPageInfo.getToObjectId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getDepartmentId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getDepartmentId), commonPageInfo.getDepartmentId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFarmId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getFarmId), commonPageInfo.getFarmId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getStoreId())) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getStoreId), commonPageInfo.getStoreId()); + } + if (commonPageInfo.getInDepot() != null) { + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getInDepot), commonPageInfo.getInDepot()); + } + wrapper.orderByDesc(MybatisPlusUtil.toColumns(MaterialNormsCode::getCreateTime)); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(MaterialNormsCode::getCodeNum)); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> dataList = super.queryPageDataList(inputObject); + materialService.setMationForMap(dataList, "materialId", "materialMation"); + materialNormsService.setMationForMap(dataList, "normsId", "normsMation"); + erpDepotService.setMationForMap(dataList, "depotId", "depotMation"); + iBarCodeService.setBarCodeMationForMap(dataList, "id", getServiceClassName()); + return dataList; + } + + @Override + public void deletePreExecution(String id) { + MaterialNormsCode materialNormsCode = selectById(id); + if (materialNormsCode.getInDepot() != MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey()) { + throw new CustomException("已入库/已出库编码无法删除"); + } + } + + @Override + public void deletePostpose(String id) { + iBarCodeService.deleteByObjectId(id); + } + + @Override + public void updatePostpose(List entity, String userId) { + if (CollectionUtil.isEmpty(entity)) { + return; + } + // 计算出入库历史 + String currentTime = DateUtil.getTimeAndToString(); + List hisList = new ArrayList<>(); + entity.forEach(materialNormsCode -> { + MaterialNormsCodeHis materialNormsCodeHis = new MaterialNormsCodeHis(); + materialNormsCodeHis.setNormsCodeId(materialNormsCode.getId()); + materialNormsCodeHis.setType(MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + materialNormsCodeHis.setOperatorTime(currentTime); + if (materialNormsCode.getInDepot() == MaterialNormsCodeInDepot.WAREHOUSING.getKey()) { + // 入库 + materialNormsCodeHis.setOperatorId(materialNormsCode.getFromObjectId()); + materialNormsCodeHis.setOperatorKey(materialNormsCode.getFromObjectKey()); + } else if (materialNormsCode.getInDepot() == MaterialNormsCodeInDepot.OUTBOUND.getKey()) { + // 出库 + materialNormsCodeHis.setOperatorId(materialNormsCode.getToObjectId()); + materialNormsCodeHis.setOperatorKey(materialNormsCode.getToObjectKey()); + } + hisList.add(materialNormsCodeHis); + }); + materialNormsCodeHisService.createEntity(hisList, StrUtil.EMPTY); + } + + @Override + public void insertMaterialNormsCode(InputObject inputObject, OutputObject outputObject) { + List> list = JSONUtil.toList(inputObject.getParams().get("list").toString(), null); + if (CollectionUtil.isEmpty(list)) { + return; + } + List normsIdList = list.stream().map(bean -> bean.get("normsId").toString()).distinct().collect(Collectors.toList()); + if (list.size() != normsIdList.size()) { + throw new CustomException("存在重复的商品规格信息,请确认"); + } + List materialIdList = list.stream().map(bean -> bean.get("materialId").toString()).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map materialNormsMap = materialNormsService.selectMapByIds(normsIdList); + for (Map bean : list) { + String materialId = bean.get("materialId").toString(); + String normsId = bean.get("normsId").toString(); + Material material = materialMap.get(materialId); + MaterialNorms materialNorms = materialNormsMap.get(normsId); + if (ObjectUtil.isEmpty(material) || ObjectUtil.isEmpty(materialNorms)) { + throw new CustomException("商品/规格信息不存在,请确认"); + } + } + + // 创建任务 + Map jobBody = new HashMap<>(); + // 是否创建任务 + jobBody.put("whetherCreatTask", false); + jobBody.put("list", JSONUtil.toJsonStr(list)); + jobBody.put("className", MaterialNormsCodeServiceImpl.class.getName()); + String topic = PropertiesUtil.getPropertiesValue("${topic.material-norms-code-generate-barcode}"); + jobBody.put("topic", topic); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(jobBody)); + jobMateMation.setUserId(inputObject.getLogParams().get("id").toString()); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + @Override + public List queryMaterialNormsCodeByCodeNum(String depotId, List codeNumList, Integer... indepot) { + List codeNumTmpList = codeNumList.stream().distinct().collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MaterialNormsCode::getCodeNum), codeNumTmpList); + // 库存状态 + List indepotList = Arrays.asList(indepot); + if (CollectionUtil.isNotEmpty(indepotList)) { + queryWrapper.in(MybatisPlusUtil.toColumns(MaterialNormsCode::getInDepot), indepotList); + } + if (StrUtil.isNotEmpty(depotId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getDepotId), depotId); + } + + List normsCodeList = list(queryWrapper); + return normsCodeList; + } + + @Override + public List queryMaterialNormsCode(String depotId, String normsId, Integer type, Integer indepot) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 库存状态 + if (indepot != null) { + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getInDepot), indepot); + } + if (type != null) { + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getType), type); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getDepotId), depotId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getNormsId), normsId); + + List normsCodeList = list(queryWrapper); + return normsCodeList; + } + + @Override + public void queryNormsBarCodeList(InputObject inputObject, OutputObject outputObject) { + MaterialNormsCodeQueryDo commonPageInfo = inputObject.getParams(MaterialNormsCodeQueryDo.class); + QueryWrapper wrapper = new QueryWrapper<>(); + setCustomerWrapper(inputObject, wrapper); + + if (commonPageInfo.getNumber() != null) { + wrapper.last(String.format(Locale.ROOT, "limit %s", commonPageInfo.getNumber())); + } else { + wrapper.last(String.format(Locale.ROOT, "limit %s", 20)); + } + wrapper.select(MybatisPlusUtil.toColumns(MaterialNormsCode::getCodeNum)); + List materialNormsCodeList = list(wrapper); + List codeNumList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + outputObject.setBeans(codeNumList); + outputObject.settotal(codeNumList.size()); + } + + @Override + public void updateEntityPick(List materialNormsCodeList) { + if (CollectionUtil.isEmpty(materialNormsCodeList)) { + return; + } + String userId = InputObject.getLogParamsStatic().get("id").toString(); + updateEntity(materialNormsCodeList, userId); + } + + @Override + public void queryNormsStockDetailList(InputObject inputObject, OutputObject outputObject) { + MaterialNormsCodeQueryDo commonPageInfo = inputObject.getParams(MaterialNormsCodeQueryDo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper wrapper = new QueryWrapper<>(); + setCustomerWrapper(inputObject, wrapper); + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getPickUseState), PickNormsCodeUseState.WAIT_USE.getKey()); + List materialNormsCodeList = list(wrapper); + List> dataList = JSONUtil.toList(JSONUtil.toJsonStr(materialNormsCodeList), null); + materialService.setMationForMap(dataList, "materialId", "materialMation"); + materialNormsService.setMationForMap(dataList, "normsId", "normsMation"); + erpDepotService.setMationForMap(dataList, "depotId", "depotMation"); + iBarCodeService.setBarCodeMationForMap(dataList, "id", getServiceClassName()); + iDepmentService.setMationForMap(dataList, "departmentId", "departmentMation"); + farmService.setMationForMap(dataList, "farmId", "farmMation"); + outputObject.setBeans(dataList); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void queryStoreNormsStockDetailList(InputObject inputObject, OutputObject outputObject) { + MaterialNormsCodeQueryDo commonPageInfo = inputObject.getParams(MaterialNormsCodeQueryDo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper wrapper = new QueryWrapper<>(); + setCustomerWrapper(inputObject, wrapper); + wrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getStoreUseState), StoreNormsCodeUseState.WAIT_USE.getKey()); + List materialNormsCodeList = list(wrapper); + List> dataList = JSONUtil.toList(JSONUtil.toJsonStr(materialNormsCodeList), null); + materialService.setMationForMap(dataList, "materialId", "materialMation"); + materialNormsService.setMationForMap(dataList, "normsId", "normsMation"); + erpDepotService.setMationForMap(dataList, "depotId", "depotMation"); + iBarCodeService.setBarCodeMationForMap(dataList, "id", getServiceClassName()); + iShopStoreService.setMationForMap(dataList, "storeId", "storeMation"); + outputObject.setBeans(dataList); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void queryMaterialNormsCode(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String storeId = params.get("storeId").toString(); + List normsCodeList = Arrays.asList(params.get("normsCodeList").toString() + .split(CommonCharConstants.COMMA_MARK)) + .stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(normsCodeList)) { + return; + } + String storeUseState = params.get("storeUseState").toString(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getStoreId), storeId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getCodeNum), normsCodeList); + if (StrUtil.isNotEmpty(storeUseState)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsCode::getStoreUseState), storeUseState); + } + List materialNormsCodeList = list(queryWrapper); + outputObject.setBeans(materialNormsCodeList); + outputObject.settotal(materialNormsCodeList.size()); + } + + @Override + public void editStoreMaterialNormsCodeUseState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + List ids = Arrays.asList(params.get("ids").toString() + .split(CommonCharConstants.COMMA_MARK)) + .stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + String storeUseState = params.get("storeUseState").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in(CommonConstants.ID, ids); + updateWrapper.set(MybatisPlusUtil.toColumns(MaterialNormsCode::getStoreUseState), storeUseState); + update(updateWrapper); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsServiceImpl.java new file mode 100644 index 0000000..3ce8a07 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsServiceImpl.java @@ -0,0 +1,338 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialNormsStockType; +import com.skyeye.material.dao.MaterialNormsDao; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsStock; +import com.skyeye.material.entity.NormsCalcStock; +import com.skyeye.material.entity.unit.MaterialUnit; +import com.skyeye.material.entity.unit.MaterialUnitGroup; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialNormsStockService; +import com.skyeye.material.service.MaterialUnitGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialNormsServiceImpl + * @Description: ERP商品规格参数服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 15:39 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品规格", groupName = "商品管理", manageShow = false) +public class MaterialNormsServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialNormsService { + + @Autowired + private MaterialUnitGroupService materialUnitGroupService; + + @Autowired + private MaterialNormsStockService materialNormsStockService; + + @Override + public void saveMaterialNorms(String userId, Material material) { + if (CollectionUtil.isEmpty(material.getMaterialNorms())) { + throw new CustomException("商品规格信息不能为空."); + } + + // 商品规格 + setNormsName(material); + List materialNormsList = save(userId, material.getId(), material.getMaterialNorms()); + + // 初始化库存信息 + List normsStockList = new ArrayList<>(); + for (MaterialNorms materialNorms : materialNormsList) { + materialNorms.getNormsStock().forEach(normsStock -> { + normsStock.setMaterialId(material.getId()); + normsStock.setNormsId(materialNorms.getId()); + normsStock.setType(MaterialNormsStockType.INIT_STOCK.getKey()); + }); + normsStockList.addAll(materialNorms.getNormsStock()); + } + materialNormsStockService.saveMaterialNormsInitStock(material.getId(), normsStockList, userId); + } + + private void setNormsName(Material material) { + Map normsKeyToName = new HashMap<>(); + material.getNormsSpec().forEach(normsSpec -> { + String title = normsSpec.get("title").toString(); + List> options = (List>) normsSpec.get("options"); + Map collect = options.stream().collect(Collectors.toMap(bean -> bean.get("rowNum").toString(), + item -> String.format(Locale.ROOT, "%s:%s", title.trim(), item.get("title").toString()))); + normsKeyToName.putAll(collect); + }); + material.getMaterialNorms().forEach(materialNorms -> { + if (material.getUnit().equals(com.skyeye.material.classenum.MaterialUnit.SINGLE_SPECIFICATION.getKey())) { + // 单规格 + materialNorms.setName(material.getUnitName()); + } else { + MaterialUnitGroup materialUnitGroupMation = materialUnitGroupService.selectById(material.getUnitGroupId()); + Map unitToName = materialUnitGroupMation.getUnitList() + .stream().collect(Collectors.toMap(MaterialUnit::getId, MaterialUnit::getName)); + String[] tableNum = materialNorms.getTableNum().split(CommonCharConstants.HORIZONTAL_LINE_MARK); + String materialNormsName = String.format(Locale.ROOT, "计量单位:%s", unitToName.get(tableNum[0])); + for (int ii = 0; ii < tableNum.length; ii++) { + if (ii != 0) { + materialNormsName += ';' + normsKeyToName.get(tableNum[ii]); + } + } + materialNorms.setName(materialNormsName); + } + }); + } + + private List save(String userId, String materialId, List materialNormsList) { + for (MaterialNorms materialNorms : materialNormsList) { + materialNorms.setMaterialId(materialId); + } + List result = new ArrayList<>(); + List oldMaterialNorms = queryNormsUnitListByMaterialId(materialId); + List oldKeys = oldMaterialNorms.stream().map(bean -> bean.getTableNum()).collect(Collectors.toList()); + List newKeys = materialNormsList.stream().map(bean -> bean.getTableNum()).collect(Collectors.toList()); + + // (旧数据 - 新数据) 从数据库删除 + List deleteBeans = oldMaterialNorms.stream() + .filter(item -> !newKeys.contains(item.getTableNum())).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(deleteBeans)) { + List ids = deleteBeans.stream().map(MaterialNorms::getId).collect(Collectors.toList()); + deleteById(ids); + } + + // (新数据 - 旧数据) 添加到数据库 + List addBeans = materialNormsList.stream() + .filter(item -> !oldKeys.contains(item.getTableNum())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(addBeans)) { + createEntity(addBeans, userId); + result.addAll(addBeans); + } + + // 新数据与旧数据取交集 编辑 + List editBeans = materialNormsList.stream() + .filter(item -> oldKeys.contains(item.getTableNum())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(editBeans)) { + Map collect = oldMaterialNorms.stream().collect(Collectors.toMap(bean -> bean.getTableNum(), item -> item)); + if (CollectionUtil.isNotEmpty(collect)) { + editBeans.forEach(bean -> { + MaterialNorms materialNorms = collect.get(bean.getTableNum()); + bean.setId(materialNorms.getId()); + }); + updateEntity(editBeans, userId); + result.addAll(editBeans); + } + } + return result; + } + + /** + * 根据商品id删除规格信息 + * + * @param materialId 商品id + */ + @Override + public void deleteMaterialNormsByMaterialId(String materialId) { + List materialNorms = queryNormsUnitListByMaterialId(materialId); + List ids = materialNorms.stream().map(MaterialNorms::getId).collect(Collectors.toList()); + deleteById(ids); + // 根据商品id删除规格库存信息 + materialNormsStockService.deleteNormsInitStockByMaterialId(materialId); + } + + @Override + public Map> queryMaterialNormsList(String depotId, String... materialIds) { + List materialIdList = Arrays.asList(materialIds); + if (CollectionUtil.isEmpty(materialIdList)) { + return new HashMap<>(); + } + Map> materialNormsMap = queryMaterialNorms(depotId, materialIds); + return materialNormsMap; + } + + @Override + public MaterialNorms queryMaterialNorms(String normsId, String depotId) { + MaterialNorms materialNorms = selectById(normsId); + calcDepotStock(materialNorms, depotId); + return materialNorms; + } + + @Override + public MaterialNorms selectById(String id) { + MaterialNorms materialNorms = super.selectById(id); + // 查询单据操作库存信息 + Map> initStockMap = materialNormsStockService.queryNormsStockByNormsId(Arrays.asList(id), + MaterialNormsStockType.ORDER_STOCK.getKey()); + materialNorms.setOrderStock(initStockMap.get(materialNorms.getId())); + calcAllStock(materialNorms); + return materialNorms; + } + + @Override + public MaterialNorms getDataFromDb(String id) { + MaterialNorms materialNorms = super.getDataFromDb(id); + // 查询初始化库存信息 + Map> initStockMap = materialNormsStockService.queryNormsStockByNormsId(Arrays.asList(id), + MaterialNormsStockType.INIT_STOCK.getKey()); + materialNorms.setNormsStock(initStockMap.get(materialNorms.getId())); + return materialNorms; + } + + @Override + public List selectByIds(String... ids) { + List materialNormsList = super.selectByIds(ids); + // 查询单据操作库存信息 + Map> initStockMap = materialNormsStockService.queryNormsStockByNormsId(Arrays.asList(ids), + MaterialNormsStockType.ORDER_STOCK.getKey()); + for (MaterialNorms norm : materialNormsList) { + norm.setOrderStock(initStockMap.get(norm.getId())); + calcAllStock(norm); + } + return materialNormsList; + } + + @Override + public List getDataFromDb(List ids) { + List materialNormsList = super.getDataFromDb(ids); + // 查询初始化库存信息 + Map> initStockMap = materialNormsStockService.queryNormsStockByNormsId(ids, + MaterialNormsStockType.INIT_STOCK.getKey()); + for (MaterialNorms norm : materialNormsList) { + norm.setNormsStock(initStockMap.get(norm.getId())); + } + return materialNormsList; + } + + /** + * 计算产品规格的总库存 + * + * @param materialNorms + */ + private static void calcAllStock(MaterialNorms materialNorms) { + List allNormsStock = getAllNormsStocks(materialNorms); + if (CollectionUtil.isNotEmpty(allNormsStock)) { + // 总库存 + int allStock = allNormsStock.stream().mapToInt(MaterialNormsStock::getStock).sum(); + // 初始总库存 + int initialTock = allNormsStock.stream() + .filter(bean -> bean.getType().equals(MaterialNormsStockType.INIT_STOCK.getKey())) + .mapToInt(MaterialNormsStock::getStock).sum(); + // 可盘点总库存 + int inventoryTock = allStock - initialTock; + NormsCalcStock calcStock = new NormsCalcStock(allStock, initialTock, inventoryTock); + materialNorms.setOverAllStock(calcStock); + } + } + + private static List getAllNormsStocks(MaterialNorms materialNorms) { + List allNormsStock = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(materialNorms.getNormsStock())) { + allNormsStock.addAll(materialNorms.getNormsStock()); + } + if (CollectionUtil.isNotEmpty(materialNorms.getOrderStock())) { + allNormsStock.addAll(materialNorms.getOrderStock()); + } + return allNormsStock; + } + + @Override + public List queryNormsUnitListByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNorms::getMaterialId), materialId); + queryWrapper.select(CommonConstants.ID); + List materialNormsList = list(queryWrapper); + // 获取规格id + List normsIdList = materialNormsList.stream().map(MaterialNorms::getId).collect(Collectors.toList()); + return selectByIds(normsIdList.toArray(new String[]{})); + } + + public Map> queryMaterialNorms(String depotId, String... materialIds) { + Map> materialNormsMap = queryNormsUnitListByMaterialId(Arrays.asList(materialIds)); + if (StrUtil.isNotEmpty(depotId)) { + // 设置指定仓库的库存信息 + materialNormsMap.forEach((materialId, materialNormsList) -> { + for (MaterialNorms materialNorms : materialNormsList) { + calcDepotStock(materialNorms, depotId); + } + }); + } + return materialNormsMap; + } + + public Map> queryNormsUnitListByMaterialId(List materialIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MaterialNorms::getMaterialId), materialIds); + queryWrapper.select(CommonConstants.ID); + List materialNormsList = list(queryWrapper); + // 获取规格id + List normsIdList = materialNormsList.stream().map(MaterialNorms::getId).collect(Collectors.toList()); + List materialNorms = selectByIds(normsIdList.toArray(new String[]{})); + return materialNorms.stream().collect(Collectors.groupingBy(MaterialNorms::getMaterialId)); + } + + /** + * 计算产品规格的指定仓库的库存 + * + * @param materialNorms + */ + @Override + public void calcDepotStock(MaterialNorms materialNorms, String depotId) { + List allNormsStock = getAllNormsStocks(materialNorms); + if (CollectionUtil.isNotEmpty(allNormsStock)) { + // 指定仓库的库存 + int allStock = allNormsStock.stream() + .filter(bean -> StrUtil.equals(bean.getDepotId(), depotId)) + .mapToInt(MaterialNormsStock::getStock).sum(); + // 指定仓库的初始库存 + int initialTock = allNormsStock.stream() + .filter(bean -> bean.getType().equals(MaterialNormsStockType.INIT_STOCK.getKey()) && StrUtil.equals(bean.getDepotId(), depotId)) + .mapToInt(MaterialNormsStock::getStock).sum(); + // 指定仓库的可盘点库存 + int inventoryTock = allStock - initialTock; + NormsCalcStock calcStock = new NormsCalcStock(allStock, initialTock, inventoryTock); + materialNorms.setDepotTock(calcStock); + } + } + + /** + * 根据产品id获取规格信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryNormsListByMaterialId(InputObject inputObject, OutputObject outputObject) { + String materialId = inputObject.getParams().get("materialId").toString(); + if (StrUtil.isEmpty(materialId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNorms::getMaterialId), materialId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNorms::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(MaterialNorms::getOrderBy)); + List materialNormsList = list(queryWrapper); + outputObject.setBeans(materialNormsList); + outputObject.settotal(materialNormsList.size()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsStockServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsStockServiceImpl.java new file mode 100644 index 0000000..b758d80 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialNormsStockServiceImpl.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.material.classenum.MaterialNormsStockType; +import com.skyeye.material.dao.MaterialNormsStockDao; +import com.skyeye.material.entity.MaterialNormsStock; +import com.skyeye.material.service.MaterialNormsStockService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialNormsStockServiceImpl + * @Description: ERP商品规格初始化库存服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/21 17:48 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品规格库存", groupName = "商品管理", manageShow = false) +public class MaterialNormsStockServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialNormsStockService { + + @Autowired + private MaterialNormsStockDao materialNormsStockDao; + + /** + * 根据商品id删除对应的初始化库存信息 + * + * @param materialId 商品id + */ + @Override + public void deleteNormsInitStockByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getMaterialId), materialId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getType), MaterialNormsStockType.INIT_STOCK.getKey()); + remove(queryWrapper); + } + + /** + * 根据规格id获取商品规格的当前库存信息 + * + * @param normsIds 规格id集合 + * @param depotId 仓库id + * @return + */ + @Override + public Map queryMaterialNormsStock(List normsIds, String depotId) { + // 查询规格信息 + List> normStockList = materialNormsStockDao.queryMaterialStockByNormsId(normsIds, depotId); + if (CollectionUtil.isEmpty(normStockList)) { + normStockList = new ArrayList<>(); + } + Map normStockMap = normStockList.stream() + .collect(Collectors.toMap(item -> item.get("normsId").toString(), item -> Integer.parseInt(item.get("stock").toString()))); + normsIds.forEach(normsId -> { + if (normStockMap.get(normsId) == null) { + normStockMap.put(normsId, CommonNumConstants.NUM_ZERO); + } + }); + return normStockMap; + } + + /** + * 批量获取指定类型的规格库存信息 + * + * @param normsIds 规格id集合 + * @return + */ + @Override + public Map> queryNormsStockByNormsId(List normsIds, Integer type) { + if (CollectionUtil.isEmpty(normsIds)) { + return new HashMap<>(); + } + List beans = materialNormsStockDao.queryNormsStockByNormsId(normsIds, StringUtils.EMPTY, type); + Map> initStockMap = beans.stream().collect(Collectors.groupingBy(MaterialNormsStock::getNormsId)); + normsIds.forEach(normsId -> { + if (initStockMap.get(normsId) == null) { + initStockMap.put(normsId, new ArrayList<>()); + } + }); + return initStockMap; + } + + /** + * 根据商品规格id获取商规格的当前库存信息 + * + * @param beans 返回对象的集合 + * @param pointNormsIdKey 指定的normsId的key + * @param depotId 仓库id + */ + @Override + public void restMaterialNormCurrentTock(List> beans, String pointNormsIdKey, String depotId) { + if (CollectionUtil.isEmpty(beans) || StringUtils.isEmpty(pointNormsIdKey)) { + return; + } + // 获取规格id去除为空的并且去重 + List normsIds = beans.stream() + .map(bean -> MapUtil.checkKeyIsNull(bean, pointNormsIdKey) ? StringUtils.EMPTY : bean.get(pointNormsIdKey).toString()) + .filter(normsId -> StringUtils.isNotEmpty(normsId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(normsIds)) { + return; + } + // 查询规格信息 + Map normStockMap = this.queryMaterialNormsStock(normsIds, depotId); + beans.forEach(bean -> { + if (!MapUtil.checkKeyIsNull(bean, pointNormsIdKey)) { + // 获取规格 + Integer currentTock = normStockMap.get(bean.get(pointNormsIdKey).toString()); + if (currentTock == null) { + bean.put("currentTock", 0); + } else { + bean.put("currentTock", currentTock); + } + } else { + bean.put("currentTock", 0); + } + }); + } + + /** + * 根据商品规格id获取商规格的当前库存信息 + * + * @param bean 返回对象的集合 + * @param pointNormsIdKey 指定的normsId的key + * @param depotId 仓库id + */ + @Override + public void restMaterialNormCurrentTock(Map bean, String pointNormsIdKey, String depotId) { + if (CollectionUtil.isEmpty(bean) || StringUtils.isEmpty(pointNormsIdKey)) { + return; + } + // 获取规格id去除为空的并且去重 + List normsIds = Arrays.asList(bean.get(pointNormsIdKey).toString()); + if (CollectionUtil.isEmpty(normsIds)) { + return; + } + // 查询规格信息 + Map normStockMap = this.queryMaterialNormsStock(normsIds, depotId); + Integer currentTock = normStockMap.get(bean.get(pointNormsIdKey).toString()); + if (currentTock == null) { + bean.put("currentTock", 0); + } else { + bean.put("currentTock", currentTock); + } + } + + /** + * 保存由单据操作生成的库存信息 + * + * @param materialId 商品id + * @param depotId 仓库id + * @param normsId 规格id + * @param stock 库存数量 + */ + @Override + public Integer saveMaterialNormsOrderStock(String materialId, String depotId, String normsId, int stock) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getNormsId), normsId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getDepotId), depotId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getType), MaterialNormsStockType.ORDER_STOCK.getKey()); + MaterialNormsStock normsStock = getOne(queryWrapper); + if (ObjectUtil.isEmpty(normsStock)) { + normsStock = new MaterialNormsStock(); + normsStock.setMaterialId(materialId); + normsStock.setNormsId(normsId); + normsStock.setDepotId(depotId); + normsStock.setStock(stock); + normsStock.setType(MaterialNormsStockType.ORDER_STOCK.getKey()); + save(normsStock); + return normsStock.getStock(); + } else { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getNormsId), normsId); + updateWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getDepotId), depotId); + updateWrapper.eq(MybatisPlusUtil.toColumns(MaterialNormsStock::getType), MaterialNormsStockType.ORDER_STOCK.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(MaterialNormsStock::getStock), stock); + update(updateWrapper); + return normsStock.getStock(); + } + } + + /** + * 保存初始化库存信息 + * + * @param materialId + * @param normsStock + * @param userId + */ + @Override + public void saveMaterialNormsInitStock(String materialId, List normsStock, String userId) { + // 存储初始化库存数量 + deleteNormsInitStockByMaterialId(materialId); + if (CollectionUtil.isNotEmpty(normsStock)) { + createEntity(normsStock, userId); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialProcedureServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialProcedureServiceImpl.java new file mode 100644 index 0000000..590d38f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialProcedureServiceImpl.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.material.dao.MaterialProcedureDao; +import com.skyeye.material.entity.MaterialProcedure; +import com.skyeye.material.service.MaterialProcedureService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialProcedureServiceImpl + * @Description: ERP商品表与工序管理的关系服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/17 22:44 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品关联工序信息", groupName = "商品管理", manageShow = false) +public class MaterialProcedureServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialProcedureService { + + /** + * 根据商品id删除关联的工序信息 + * + * @param materialId 商品id + */ + @Override + public void deleteMaterialProcedureByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialProcedure::getMaterialId), materialId); + remove(queryWrapper); + } + + /** + * 保存商品与工序的关联关系信息 + * + * @param materialId + * @param materialProcedureList + * @param userId + */ + @Override + public void saveMaterialProcedure(String materialId, List materialProcedureList, String userId) { + deleteMaterialProcedureByMaterialId(materialId); + if (CollectionUtil.isNotEmpty(materialProcedureList)) { + for (MaterialProcedure materialProcedure : materialProcedureList) { + materialProcedure.setMaterialId(materialId); + } + createEntity(materialProcedureList, userId); + } + } + + /** + * 根据商品id查询关联的工序信息 + * + * @param materialId 商品id + */ + @Override + public List queryMaterialProcedureByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialProcedure::getMaterialId), materialId); + List materialProcedureList = list(queryWrapper); + return materialProcedureList; + } + + /** + * 根据商品id查询关联的工序信息 + * + * @param materialIds 商品id + */ + @Override + public Map> queryMaterialProcedureByMaterialIds(List materialIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MaterialProcedure::getMaterialId), materialIds); + List materialProcedureList = list(queryWrapper); + Map> listMap = materialProcedureList + .stream().collect(Collectors.groupingBy(MaterialProcedure::getMaterialId)); + return listMap; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java new file mode 100644 index 0000000..59491a9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java @@ -0,0 +1,390 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.brand.service.BrandService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.enumeration.IsUsedEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.entity.Depot; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialShelvesState; +import com.skyeye.material.classenum.MaterialUnit; +import com.skyeye.material.dao.MaterialDao; +import com.skyeye.material.entity.*; +import com.skyeye.material.service.*; +import com.skyeye.procedure.entity.WorkProcedure; +import com.skyeye.procedure.service.WorkProcedureService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialServiceImpl + * @Description: 商品信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品信息", groupName = "商品管理") +public class MaterialServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialService { + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private MaterialNormsStockService materialNormsStockService; + + @Autowired + private MaterialProcedureService materialProcedureService; + + @Autowired + private MaterialUnitGroupService materialUnitGroupService; + + @Autowired + private MaterialUnitService materialUnitService; + + @Autowired + private WorkProcedureService workProcedureService; + + @Autowired + private ErpDepotService erpDepotService; + + @Autowired + private BrandService brandService; + + @Override + public void validatorEntity(Material entity) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(Material::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(Material::getModel), entity.getModel())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Material checkMaterial = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(checkMaterial)) { + throw new CustomException("同种型号/名称的商品已经存在."); + } + if (entity.getUnit().equals(MaterialUnit.MULTI_SPECIFICATION.getKey())) { + // 多单位 + if (StrUtil.isBlank(entity.getUnitGroupId())) { + throw new CustomException("请选择单位."); + } + if (StrUtil.isBlank(entity.getFirstOutUnit())) { + throw new CustomException("请选择首选出库单位."); + } + if (StrUtil.isBlank(entity.getFirstInUnit())) { + throw new CustomException("请选择首选入库单位."); + } + } + } + + @Override + public void createPrepose(Material entity) { + if (entity.getItemCode() == null) { + throw new CustomException("请选择条形码开启类型."); + } + entity.setIsUsed(IsUsedEnum.NOT_USED.getKey()); + entity.setShelvesState(MaterialShelvesState.NOT_ON_SHELVE.getKey()); + } + + @Override + public void writePostpose(Material entity, String userId) { + super.writePostpose(entity, userId); + + // 保存商品规格信息以及初始化库存信息 + materialNormsService.saveMaterialNorms(userId, entity); + // 保存商品的工序信息 + materialProcedureService.saveMaterialProcedure(entity.getId(), entity.getMaterialProcedure(), userId); + } + + @Override + public void deletePreExecution(Material entity) { + if (entity.getIsUsed() == IsUsedEnum.IN_USE.getKey()) { + throw new CustomException("该商品已被使用,不能删除."); + } + } + + @Override + public void deletePostpose(String id) { + // 删除商品规格 + materialNormsService.deleteMaterialNormsByMaterialId(id); + // 删除商品关联的工序信息 + materialProcedureService.deleteMaterialProcedureByMaterialId(id); + } + + @Override + public Material selectById(String id) { + Material material = super.selectById(id); + if (material.getUnit().equals(MaterialUnit.MULTI_SPECIFICATION.getKey())) { + // 计量单位分组信息 + material.setUnitGroupMation(materialUnitGroupService.selectById(material.getUnitGroupId())); + // 首选入库单位信息 + material.setFirstInUnitMation(materialUnitService.selectById(material.getFirstInUnit())); + // 首选出入单位信息 + material.setFirstOutUnitMation(materialUnitService.selectById(material.getFirstOutUnit())); + } + // 产品工序信息 + if (CollectionUtil.isNotEmpty(material.getMaterialProcedure())) { + workProcedureService.setDataMation(material.getMaterialProcedure(), MaterialProcedure::getProcedureId); + } + // 仓库信息 + List normsStocks = material.getMaterialNorms().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsStock())) + .flatMap(norms -> norms.getNormsStock().stream()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(normsStocks)) { + List depotIds = normsStocks.stream().map(MaterialNormsStock::getDepotId).distinct().collect(Collectors.toList()); + Map depotMap = erpDepotService.selectMapByIds(depotIds); + material.getMaterialNorms().forEach(norms -> { + if (CollectionUtil.isEmpty(norms.getNormsStock())) { + return; + } + for (MaterialNormsStock normsStock : norms.getNormsStock()) { + normsStock.setDepotMation(depotMap.get(normsStock.getDepotId())); + } + }); + } + // 品牌信息 + brandService.setDataMation(material, Material::getBrandId); + + return material; + } + + @Override + public Material getDataFromDb(String id) { + Material material = super.getDataFromDb(id); + // 商品规格信息 + List materialNorms = materialNormsService.queryNormsUnitListByMaterialId(id); + material.setMaterialNorms(materialNorms); + // 商品关联工序信息 + List materialProcedures = materialProcedureService.queryMaterialProcedureByMaterialId(id); + material.setMaterialProcedure(materialProcedures); + + return material; + } + + @Override + public List selectByIds(String... ids) { + List materialList = super.selectByIds(ids); + materialList.forEach(material -> { + if (material.getUnit().equals(MaterialUnit.MULTI_SPECIFICATION.getKey())) { + // 计量单位分组信息 + material.setUnitGroupMation(materialUnitGroupService.selectById(material.getUnitGroupId())); + // 首选入库单位信息 + material.setFirstInUnitMation(materialUnitService.selectById(material.getFirstInUnit())); + // 首选出入单位信息 + material.setFirstOutUnitMation(materialUnitService.selectById(material.getFirstOutUnit())); + } + }); + + // 产品工序信息 + List materialProcedureList = materialList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getMaterialProcedure())) + .flatMap(bean -> bean.getMaterialProcedure().stream()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(materialProcedureList)) { + List procedureIds = materialProcedureList.stream().map(MaterialProcedure::getProcedureId).distinct().collect(Collectors.toList()); + Map procedureMap = workProcedureService.selectMapByIds(procedureIds); + materialList.forEach(material -> { + if (CollectionUtil.isEmpty(material.getMaterialProcedure())) { + return; + } + material.getMaterialProcedure().forEach(materialProcedure -> { + if (!procedureMap.containsKey(materialProcedure.getProcedureId())) { + return; + } + materialProcedure.setProcedureMation(procedureMap.get(materialProcedure.getProcedureId())); + }); + }); + } + + List materialNorms = materialList.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getMaterialNorms())) + .flatMap(norms -> norms.getMaterialNorms().stream()).collect(Collectors.toList()); + // 仓库信息 + List normsStocks = materialNorms.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsStock())) + .flatMap(norms -> norms.getNormsStock().stream()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(normsStocks)) { + List depotIds = normsStocks.stream().map(MaterialNormsStock::getDepotId).distinct().collect(Collectors.toList()); + Map depotMap = erpDepotService.selectMapByIds(depotIds); + materialList.forEach(material -> { + material.getMaterialNorms().forEach(norms -> { + if (CollectionUtil.isEmpty(norms.getNormsStock())) { + return; + } + for (MaterialNormsStock normsStock : norms.getNormsStock()) { + normsStock.setDepotMation(depotMap.get(normsStock.getDepotId())); + } + }); + }); + } + // 品牌信息 + brandService.setDataMation(materialList, Material::getBrandId); + + return materialList; + } + + @Override + protected List getDataFromDb(List idList) { + List materialList = super.getDataFromDb(idList); + // 商品规格信息 + Map> normsMap = materialNormsService.queryMaterialNormsList(StrUtil.EMPTY, idList.toArray(new String[]{})); + // 商品关联工序信息 + Map> materialProcedureMap = materialProcedureService.queryMaterialProcedureByMaterialIds(idList); + materialList.forEach(material -> { + material.setMaterialProcedure(materialProcedureMap.get(material.getId())); + material.setMaterialNorms(normsMap.get(material.getId())); + }); + return materialList; + } + + /** + * 获取商品列表信息展示为表格方便选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMaterialListToTable(InputObject inputObject, OutputObject outputObject) { + MaterialChooseQueryDo queryDo = inputObject.getParams(MaterialChooseQueryDo.class); + Page pages = PageHelper.startPage(queryDo.getPage(), queryDo.getLimit()); + QueryWrapper queryWrapper = super.getQueryWrapper(queryDo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List beans = list(queryWrapper); + + // 获取规格单位信息 + List materialIdList = beans.stream().map(Material::getId).collect(Collectors.toList()); + Map> materialNormsMap = materialNormsService.queryMaterialNormsList(queryDo.getDepotId(), + materialIdList.toArray(new String[]{})); + for (Material bean : beans) { + bean.setMaterialNorms(materialNormsMap.get(bean.getId())); + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 根据商品规格id以及仓库id获取库存 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMaterialTockByNormsId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + // 获取多个商品规格id + List normsIds = Arrays.asList(params.get("normsIds").toString().split(CommonCharConstants.COMMA_MARK)); + // 仓库id + String depotId = params.get("depotId").toString(); + // 获取所有库存信息 + Map bean = materialNormsStockService.queryMaterialNormsStock(normsIds, depotId); + outputObject.setBean(bean); + } + + /** + * 获取商品库存信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMaterialReserveList(InputObject inputObject, OutputObject outputObject) { + MaterialChooseQueryDo queryDo = inputObject.getParams(MaterialChooseQueryDo.class); + Page pages = PageHelper.startPage(queryDo.getPage(), queryDo.getLimit()); + QueryWrapper queryWrapper = super.getQueryWrapper(queryDo); + List beans = list(queryWrapper); + + // 获取规格单位信息 + List materialIdList = beans.stream().map(Material::getId).collect(Collectors.toList()); + Map> materialNormsMap = materialNormsService.queryMaterialNormsList(queryDo.getDepotId(), + materialIdList.toArray(new String[]{})); + for (Material bean : beans) { + bean.setMaterialNorms(materialNormsMap.get(bean.getId())); + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取预警商品库存信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMaterialInventoryWarningList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + pageInfo.setEnabled(EnableEnum.ENABLE_USING.getKey()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryMaterialInventoryWarningList(pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取所有商品列表 + * + * @param inputObject + * @param outputObject + */ + @Override + public void queryAllMaterialList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List materialList = list(queryWrapper); + outputObject.setBeans(materialList); + outputObject.settotal(materialList.size()); + } + + @Override + public void setUsed(String id) { + Material material = super.selectById(id); + if (material.getIsUsed() == null || material.getIsUsed() == IsUsedEnum.NOT_USED.getKey()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Material::getIsUsed), IsUsedEnum.IN_USE.getKey()); + update(updateWrapper); + refreshCache(id); + } + } + + @Override + public void setShelvesState(String id, Integer shelvesState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Material::getShelvesState), shelvesState); + updateWrapper.set(MybatisPlusUtil.toColumns(Material::getIsUsed), IsUsedEnum.IN_USE.getKey()); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitGroupServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitGroupServiceImpl.java new file mode 100644 index 0000000..0b422c6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitGroupServiceImpl.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.dao.MaterialUnitGroupDao; +import com.skyeye.material.entity.unit.MaterialUnit; +import com.skyeye.material.entity.unit.MaterialUnitGroup; +import com.skyeye.material.service.MaterialUnitGroupService; +import com.skyeye.material.service.MaterialUnitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialUnitServiceImpl + * @Description: 计量单位分组服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "计量单位分组", groupName = "计量单位") +public class MaterialUnitGroupServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialUnitGroupService { + + @Autowired + private MaterialUnitService materialUnitService; + + @Override + protected void writePostpose(MaterialUnitGroup entity, String userId) { + super.writePostpose(entity, userId); + // 保存计量单位信息 + materialUnitService.saveBatchList(entity.getUnitList(), userId, entity.getId()); + } + + @Override + public void deletePostpose(String id) { + // 删除计量单位信息 + materialUnitService.deleteByGroupId(id); + } + + @Override + public MaterialUnitGroup getDataFromDb(String id) { + MaterialUnitGroup materialUnitGroup = super.getDataFromDb(id); + // 查询单位信息 + materialUnitGroup.setUnitList(materialUnitService.queryUnitListByGroupId(id)); + return materialUnitGroup; + } + + @Override + public MaterialUnitGroup selectById(String id) { + MaterialUnitGroup materialUnitGroup = super.selectById(id); + materialUnitGroup.getUnitList().forEach(unit -> { + Map baseUnitMation = new HashMap<>(); + baseUnitMation.put("name", WhetherEnum.getName(unit.getBaseUnit())); + unit.setBaseUnitMation(baseUnitMation); + }); + return materialUnitGroup; + } + + @Override + protected List getDataFromDb(List idList) { + List materialUnitGroups = super.getDataFromDb(idList); + List ids = materialUnitGroups.stream().map(MaterialUnitGroup::getId).collect(Collectors.toList()); + // 查询单位信息 + Map> groupUnitMap = materialUnitService.queryUnitListByGroupId(ids); + materialUnitGroups.forEach(materialUnitGroup -> { + materialUnitGroup.setUnitList(groupUnitMap.get(materialUnitGroup.getId())); + }); + return materialUnitGroups; + } + + /** + * 获取计量单位展示为下拉框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllMaterialUnitList(InputObject inputObject, OutputObject outputObject) { + List materialUnitGroups = queryAllData(); + outputObject.setBeans(materialUnitGroups); + outputObject.settotal(materialUnitGroups.size()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitServiceImpl.java new file mode 100644 index 0000000..7268e1e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/material/service/impl/MaterialUnitServiceImpl.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.dao.MaterialUnitDao; +import com.skyeye.material.entity.unit.MaterialUnit; +import com.skyeye.material.service.MaterialUnitService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MaterialUnitServiceImpl + * @Description: 计量单位信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/30 11:34 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "计量单位", groupName = "计量单位", manageShow = false) +public class MaterialUnitServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialUnitService { + + /** + * 批量保存计量单位信息 + * + * @param unitList 计量单位信息 + * @param userId 用户id + * @param groupId 所属组id + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void saveBatchList(List unitList, String userId, String groupId) { + List collect = unitList.stream() + .filter(bean -> bean.getBaseUnit() == WhetherEnum.ENABLE_USING.getKey()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(collect)) { + throw new CustomException("至少需要一个基础单位"); + } + if (collect.size() > 1) { + throw new CustomException("分组中只允许一个基础单位"); + } + // 获取数据库中的数据 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(MaterialUnit::getGroupId), groupId); + wrapper.eq(MybatisPlusUtil.toColumns(MaterialUnit::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List oldList = super.list(wrapper); + Map nameToId = oldList.stream().collect(Collectors.toMap(MaterialUnit::getName, MaterialUnit::getId)); + List oldKeys = oldList.stream().map(bean -> bean.getName()).collect(Collectors.toList()); + List newKeys = unitList.stream().map(bean -> bean.getName()).collect(Collectors.toList()); + + // (旧数据 - 新数据) 从数据库删除 + List deleteBeans = oldList.stream().filter(item -> !newKeys.contains(item.getName())).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(deleteBeans)) { + List ids = deleteBeans.stream().map(bean -> bean.getId()).collect(Collectors.toList()); + deleteById(ids); + } + + // (新数据 - 旧数据) 添加到数据库 + List addBeans = unitList.stream().filter(item -> !oldKeys.contains(item.getName())).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(addBeans)) { + addBeans.forEach(bean -> { + bean.setGroupId(groupId); + }); + createEntity(addBeans, userId); + } + + // (新数据 包含 旧数据) 修改数据库 + List editBeans = unitList.stream().filter(item -> oldKeys.contains(item.getName())).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(editBeans)) { + editBeans.forEach(bean -> { + bean.setId(nameToId.get(bean.getName())); + bean.setGroupId(groupId); + }); + updateEntity(editBeans, userId); + } + } + + /** + * 查询组下的所有计量单位信息 + * + * @param groupId 所属组id + * @return 计量单位信息 + */ + @Override + public List queryUnitListByGroupId(String groupId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialUnit::getGroupId), groupId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialUnit::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(MaterialUnit::getNumber)); + return list(queryWrapper); + } + + + /** + * 根据所属组id删除组下面的计量单位信息 + * + * @param groupId 所属组id + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteByGroupId(String groupId) { + List unitList = queryUnitListByGroupId(groupId); + List ids = unitList.stream().map(MaterialUnit::getId).collect(Collectors.toList()); + deleteById(ids); + } + + /** + * 根据组id集合批量查询计量单位信息 + * + * @param groupIds 组id集合 + * @return + */ + @Override + public Map> queryUnitListByGroupId(List groupIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MaterialUnit::getGroupId), groupIds); + queryWrapper.eq(MybatisPlusUtil.toColumns(MaterialUnit::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List unitMationList = super.list(queryWrapper); + Map> collect = unitMationList.stream() + .sorted(Comparator.comparing(bean -> bean.getNumber())).collect(Collectors.groupingBy(MaterialUnit::getGroupId)); + return collect; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AllocationController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AllocationController.java new file mode 100644 index 0000000..e071d6e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AllocationController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.Allocation; +import com.skyeye.other.service.AllocationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AllocationController + * @Description: 调拨单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "调拨单", tags = "调拨单", modelName = "调拨单模块") +public class AllocationController { + + @Autowired + private AllocationService allocationService; + + /** + * 获取调拨单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "allocation001", value = "获取调拨单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AllocationController/queryAllocationList") + public void queryAllocationList(InputObject inputObject, OutputObject outputObject) { + allocationService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑调拨单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAllocation", value = "新增/编辑调拨单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Allocation.class) + @RequestMapping("/post/AllocationController/writeAllocation") + public void writeAllocation(InputObject inputObject, OutputObject outputObject) { + allocationService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AssemblySheetController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AssemblySheetController.java new file mode 100644 index 0000000..8601505 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/AssemblySheetController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.AssemblySheet; +import com.skyeye.other.service.AssemblySheetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AssemblySheetController + * @Description: 组装单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "组装单", tags = "组装单", modelName = "组装单模块") +public class AssemblySheetController { + + @Autowired + private AssemblySheetService assemblySheetService; + + /** + * 获取组装单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "assemblysheet001", value = "获取组装单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AssemblySheetController/queryAssemblySheetList") + public void queryAssemblySheetList(InputObject inputObject, OutputObject outputObject) { + assemblySheetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑组装单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAssemblySheet", value = "新增/编辑组装单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AssemblySheet.class) + @RequestMapping("/post/AssemblySheetController/writeAssemblySheet") + public void writeAssemblySheet(InputObject inputObject, OutputObject outputObject) { + assemblySheetService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherOutLetsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherOutLetsController.java new file mode 100644 index 0000000..602bd6d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherOutLetsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.other.entity.OtherOutLets; +import com.skyeye.other.service.OtherOutLetsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OtherOutLetsController + * @Description: 其他出库单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "其他出库单", tags = "其他出库单", modelName = "其他订单模块") +public class OtherOutLetsController { + + @Autowired + private OtherOutLetsService otherOutLetsService; + + /** + * 获取其他出库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "otheroutlets001", value = "获取其他出库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OtherOutLetsController/queryOtherOutLetsList") + public void queryOtherOutLetsList(InputObject inputObject, OutputObject outputObject) { + otherOutLetsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑其他出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeOtherOutLets", value = "新增/编辑其他出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = OtherOutLets.class) + @RequestMapping("/post/OtherOutLetsController/writeOtherOutLets") + public void writeOtherOutLets(InputObject inputObject, OutputObject outputObject) { + otherOutLetsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询其他出库单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOtherOutLetsTransById", value = "转仓库出库单时,根据id查询其他出库单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherOutLetsController/queryOtherOutLetsTransById") + public void queryOtherOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + otherOutLetsService.queryOtherOutLetsTransById(inputObject, outputObject); + } + + /** + * 其他出库单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertOtherOutLetsToTurnDepot", value = "其他出库单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherOutLetsController/insertOtherOutLetsToTurnDepot") + public void insertOtherOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + otherOutLetsService.insertOtherOutLetsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherWareHousController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherWareHousController.java new file mode 100644 index 0000000..f99d3c3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/OtherWareHousController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.other.entity.OtherWareHous; +import com.skyeye.other.service.OtherWareHousService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OtherWareHousController + * @Description: 其他入库单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "其他入库单", tags = "其他入库单", modelName = "其他订单模块") +public class OtherWareHousController { + + @Autowired + private OtherWareHousService otherWareHousService; + + /** + * 获取其他入库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "otherwarehous001", value = "获取其他入库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OtherWareHousController/queryOtherWareHousList") + public void queryOtherWareHousList(InputObject inputObject, OutputObject outputObject) { + otherWareHousService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑其他入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeOtherWareHous", value = "新增/编辑其他入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = OtherWareHous.class) + @RequestMapping("/post/OtherWareHousController/writeOtherOutLets") + public void writeOtherOutLets(InputObject inputObject, OutputObject outputObject) { + otherWareHousService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询其他入库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOtherWareHousTransById", value = "转仓库入库单时,根据id查询其他入库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherWareHousController/queryOtherWareHousTransById") + public void queryOtherWareHousTransById(InputObject inputObject, OutputObject outputObject) { + otherWareHousService.queryOtherWareHousTransById(inputObject, outputObject); + } + + /** + * 其他入库单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertOtherWareHousToTurnDepot", value = "其他入库单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherWareHousController/insertOtherWareHousToTurnDepot") + public void insertOtherWareHousToTurnDepot(InputObject inputObject, OutputObject outputObject) { + otherWareHousService.insertOtherWareHousToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/SplitListController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/SplitListController.java new file mode 100644 index 0000000..6096b31 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/controller/SplitListController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.SplitList; +import com.skyeye.other.service.SplitListService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SplitListController + * @Description: 拆分单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "拆分单", tags = "拆分单", modelName = "拆分单模块") +public class SplitListController { + + @Autowired + private SplitListService splitListService; + + /** + * 获取拆分单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "splitlist001", value = "获取拆分单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SplitListController/querySplitListList") + public void querySplitListList(InputObject inputObject, OutputObject outputObject) { + splitListService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑拆分单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSplitList", value = "新增/编辑拆分单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SplitList.class) + @RequestMapping("/post/SplitListController/writeSplitList") + public void writeSplitList(InputObject inputObject, OutputObject outputObject) { + splitListService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AllocationDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AllocationDao.java new file mode 100644 index 0000000..e1c7ce4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AllocationDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.other.entity.Allocation; + +/** + * @ClassName: AllocationDao + * @Description: 调拨单管理数据管理层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AllocationDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AssemblySheetDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AssemblySheetDao.java new file mode 100644 index 0000000..21b2e15 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/AssemblySheetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.other.entity.AssemblySheet; + +/** + * @ClassName: AssemblySheetDao + * @Description: 组装单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssemblySheetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherOutLetsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherOutLetsDao.java new file mode 100644 index 0000000..54a11d1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherOutLetsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.other.entity.OtherOutLets; + +/** + * @ClassName: OtherOutLetsDao + * @Description: 其他出库单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherOutLetsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherWareHousDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherWareHousDao.java new file mode 100644 index 0000000..3782c30 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/OtherWareHousDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.other.entity.OtherWareHous; + +/** + * @ClassName: OtherWareHousDao + * @Description: 其他入库单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherWareHousDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/SplitListDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/SplitListDao.java new file mode 100644 index 0000000..c1c9191 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/dao/SplitListDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.other.entity.SplitList; + +/** + * @ClassName: SplitListDao + * @Description: 拆分单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SplitListDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/Allocation.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/Allocation.java new file mode 100644 index 0000000..f36abfc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/Allocation.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderCommon; +import lombok.Data; + +/** + * @ClassName: Allocation + * @Description: 调拨单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:allocation", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("调拨单实体类") +public class Allocation extends ErpOrderCommon { + + @TableField("allocation_project_id") + @ApiModelProperty(value = "调拨时,对方项目Id") + private String allocationProjectId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/AssemblySheet.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/AssemblySheet.java new file mode 100644 index 0000000..fc98507 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/AssemblySheet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderCommon; +import lombok.Data; + +/** + * @ClassName: AssemblySheet + * @Description: 组装单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:assemblySheet", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("组装单实体类") +public class AssemblySheet extends ErpOrderCommon { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherOutLets.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherOutLets.java new file mode 100644 index 0000000..a73d723 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherOutLets.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: OtherOutLets + * @Description: 其他出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:otherOutLets", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("其他出库单实体类") +public class OtherOutLets extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherWareHous.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherWareHous.java new file mode 100644 index 0000000..ae0d797 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/OtherWareHous.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: OtherWareHous + * @Description: 其他入库单实体类 + * --otherState:这里表示【其他入库单入库状态】参考#DepotPutState + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:otherWareHous", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("其他入库单实体类") +public class OtherWareHous extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/SplitList.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/SplitList.java new file mode 100644 index 0000000..5d50523 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/entity/SplitList.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderCommon; +import lombok.Data; + +/** + * @ClassName: SplitList + * @Description: 拆分单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:splitList", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("拆分单实体类") +public class SplitList extends ErpOrderCommon { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AllocationService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AllocationService.java new file mode 100644 index 0000000..4191bca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AllocationService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.other.entity.Allocation; + +/** + * @ClassName: AllocationService + * @Description: 调拨单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AllocationService extends SkyeyeErpOrderService { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AssemblySheetService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AssemblySheetService.java new file mode 100644 index 0000000..bd1a330 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/AssemblySheetService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.other.entity.AssemblySheet; + +/** + * @ClassName: AssemblySheetService + * @Description: 组装单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AssemblySheetService extends SkyeyeErpOrderService { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherOutLetsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherOutLetsService.java new file mode 100644 index 0000000..19cdab3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherOutLetsService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.OtherOutLets; + +/** + * @ClassName: OtherOutLetsService + * @Description: 其他出库单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherOutLetsService extends SkyeyeErpOrderService { + + void queryOtherOutLetsTransById(InputObject inputObject, OutputObject outputObject); + + void insertOtherOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherWareHousService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherWareHousService.java new file mode 100644 index 0000000..2a7355b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/OtherWareHousService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.OtherWareHous; + +/** + * @ClassName: OtherWareHousService + * @Description: 其他入库单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherWareHousService extends SkyeyeErpOrderService { + + void queryOtherWareHousTransById(InputObject inputObject, OutputObject outputObject); + + void insertOtherWareHousToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/SplitListService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/SplitListService.java new file mode 100644 index 0000000..21f6e79 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/SplitListService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.other.entity.SplitList; + +/** + * @ClassName: SplitListService + * @Description: 拆分单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SplitListService extends SkyeyeErpOrderService { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AllocationServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AllocationServiceImpl.java new file mode 100644 index 0000000..9f50bb7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AllocationServiceImpl.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.other.dao.AllocationDao; +import com.skyeye.other.entity.Allocation; +import com.skyeye.other.service.AllocationService; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AllocationServiceImpl + * @Description: 调拨单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "调拨单", groupName = "调拨单模块", flowable = true) +public class AllocationServiceImpl extends SkyeyeErpOrderServiceImpl implements AllocationService { + + @Override + public void validatorEntity(Allocation entity) { + check(entity); + checkNormsCodeAndAllocation(entity, true); + } + + @Override + public void createPrepose(Allocation entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OTHER.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(Allocation entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public Allocation getDataFromDb(String id) { + Allocation allocation = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(allocation); + return allocation; + } + + private static void check(Allocation entity) { + entity.getErpOrderItemList().forEach(erpOrderItem -> { + if (StrUtil.isEmpty(erpOrderItem.getDepotId()) || StrUtil.isEmpty(erpOrderItem.getAnotherDepotId())) { + throw new CustomException("出入库仓库不能为空。"); + } + }); + } + + @Override + public void approvalEndIsSuccess(Allocation entity) { + entity = selectById(entity.getId()); + // 校验商品规格条形码明细并进行仓库修改 + checkNormsCodeAndAllocation(entity, false); + // 修改库存 + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + String depotId = erpOrderItem.getDepotId(); + String materialId = erpOrderItem.getMaterialId(); + String normsId = erpOrderItem.getNormsId(); + Integer operNumber = erpOrderItem.getOperNumber(); + // 调拨单 + String anotherDepotId = erpOrderItem.getAnotherDepotId(); + // 当前仓库出库 + erpCommonService.editMaterialNormsDepotStock(depotId, materialId, normsId, operNumber, DepotPutOutType.OUT.getKey()); + // 调入仓库入库 + erpCommonService.editMaterialNormsDepotStock(anotherDepotId, materialId, normsId, operNumber, DepotPutOutType.PUT.getKey()); + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 调拨单 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected void checkNormsCodeAndAllocation(Allocation entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行调拨的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或未入库/已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 判断条形码是否就在出库仓库里面 + Map materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + // 条形码对应的新的仓库信息 + Map allocationMap = new HashMap<>(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + MaterialNormsCode materialNormsCode = materialNormsCodeMap.get(normsCode); + if (!StrUtil.equals(materialNormsCode.getDepotId(), erpOrderItem.getDepotId())) { + throw new CustomException( + String.format(Locale.ROOT, "条形码【%s】不在指定出库仓库,请确认", normsCode)); + } + if (!StrUtil.equals(materialNormsCode.getNormsId(), erpOrderItem.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + if (!onlyCheck) { + allocationMap.put(normsCode, erpOrderItem.getAnotherDepotId()); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setDepotId(allocationMap.get(materialNormsCode.getCodeNum())); + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AssemblySheetServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AssemblySheetServiceImpl.java new file mode 100644 index 0000000..d599237 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/AssemblySheetServiceImpl.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.classenum.MaterialNormsCodeType; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.other.dao.AssemblySheetDao; +import com.skyeye.other.entity.AssemblySheet; +import com.skyeye.other.service.AssemblySheetService; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AssemblySheetServiceImpl + * @Description: 组装单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "组装单", groupName = "组装单模块", flowable = true) +public class AssemblySheetServiceImpl extends SkyeyeErpOrderServiceImpl implements AssemblySheetService { + + @Override + public void validatorEntity(AssemblySheet entity) { + check(entity); + checkNormsCodeAndAssemblySheet(entity, true); + } + + @Override + public void createPrepose(AssemblySheet entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OTHER.getKey()); + } + + @Override + public void writeChild(AssemblySheet entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public AssemblySheet getDataFromDb(String id) { + AssemblySheet assemblySheet = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(assemblySheet); + return assemblySheet; + } + + private static void check(AssemblySheet entity) { + // 组合件 + List assemblyList = entity.getErpOrderItemList().stream() + .filter(erpOrderItem -> MaterialInOrderType.ASSEMBLY.getKey() == erpOrderItem.getMType()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(assemblyList)) { + throw new CustomException("组合件不能为空"); + } + if (assemblyList.size() != 1) { + throw new CustomException("组装单有且只有一件组合件"); + } + + // 普通子件 + List generalSubassemblyList = entity.getErpOrderItemList().stream() + .filter(erpOrderItem -> MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey() == erpOrderItem.getMType()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(generalSubassemblyList)) { + throw new CustomException("普通子件不能为空"); + } + } + + @Override + public AssemblySheet selectById(String id) { + AssemblySheet assemblySheet = super.selectById(id); + assemblySheet.getErpOrderItemList().forEach(erpOrderItem -> { + String name = MaterialInOrderType.getName(erpOrderItem.getMType()); + Map mTypeMation = new HashMap<>(); + mTypeMation.put("name", name); + erpOrderItem.setMTypeMation(mTypeMation); + }); + return assemblySheet; + } + + @Override + public void approvalEndIsSuccess(AssemblySheet entity) { + entity = selectById(entity.getId()); + // 校验商品规格条形码明细并进行仓库修改 + checkNormsCodeAndAssemblySheet(entity, false); + + // 修改库存 + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + String depotId = erpOrderItem.getDepotId(); + String materialId = erpOrderItem.getMaterialId(); + String normsId = erpOrderItem.getNormsId(); + Integer operNumber = erpOrderItem.getOperNumber(); + Integer mType = erpOrderItem.getMType(); + if (MaterialInOrderType.ASSEMBLY.getKey().equals(mType)) { + erpCommonService.editMaterialNormsDepotStock(depotId, materialId, normsId, operNumber, DepotPutOutType.PUT.getKey()); + } else if (MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey().equals(mType)) { + erpCommonService.editMaterialNormsDepotStock(depotId, materialId, normsId, operNumber, DepotPutOutType.OUT.getKey()); + } + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 组装单 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected void checkNormsCodeAndAssemblySheet(AssemblySheet entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行组装的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询未入库和入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey(), MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + Map materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + // 设置条形码新的状态信息 + Map assemblyMap = new HashMap<>(); + Map assemblyDepotMap = new HashMap<>(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + Integer mType = erpOrderItem.getMType(); + MaterialNormsCode materialNormsCode = materialNormsCodeMap.get(normsCode); + if (MaterialInOrderType.ASSEMBLY.getKey().equals(mType)) { + if (materialNormsCode.getInDepot() != MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey()) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】已入库或已出库,无法作为组合件,请确认", normsCode)); + } + if (!onlyCheck) { + assemblyDepotMap.put(normsCode, erpOrderItem.getDepotId()); + assemblyMap.put(normsCode, MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + } + } else if (MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey().equals(mType)) { + if (materialNormsCode.getInDepot() != MaterialNormsCodeInDepot.WAREHOUSING.getKey()) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】未入库或已出库,无法作为普通子件,请确认", normsCode)); + } + if (!StrUtil.equals(materialNormsCode.getDepotId(), erpOrderItem.getDepotId())) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】所在仓库与实际仓库不符,请确认", normsCode)); + } + if (!onlyCheck) { + assemblyMap.put(normsCode, MaterialNormsCodeInDepot.OUTBOUND.getKey()); + } + } + if (!StrUtil.equals(materialNormsCode.getNormsId(), erpOrderItem.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + String currentTime = DateUtil.getTimeAndToString(); + String serviceClassName = getServiceClassName(); + materialNormsCodeList.forEach(materialNormsCode -> { + Integer inDepot = assemblyMap.get(materialNormsCode.getCodeNum()); + materialNormsCode.setInDepot(inDepot); + if (inDepot == MaterialNormsCodeInDepot.WAREHOUSING.getKey()) { + // 入库 + materialNormsCode.setDepotId(assemblyDepotMap.get(materialNormsCode.getCodeNum())); + materialNormsCode.setWarehousingTime(currentTime); + materialNormsCode.setFromObjectId(entity.getId()); + materialNormsCode.setFromObjectKey(serviceClassName); + materialNormsCode.setType(MaterialNormsCodeType.AUTHENTIC.getKey()); + } else if (inDepot == MaterialNormsCodeInDepot.OUTBOUND.getKey()) { + // 出库 + materialNormsCode.setOutboundTime(currentTime); + materialNormsCode.setToObjectId(entity.getId()); + materialNormsCode.setToObjectKey(serviceClassName); + } + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherOutLetsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherOutLetsServiceImpl.java new file mode 100644 index 0000000..f33279e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherOutLetsServiceImpl.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.other.dao.OtherOutLetsDao; +import com.skyeye.other.entity.OtherOutLets; +import com.skyeye.other.service.OtherOutLetsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OtherOutLetsServiceImpl + * @Description: 其他出库单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "其他出库单", groupName = "其他订单模块", flowable = true) +public class OtherOutLetsServiceImpl extends SkyeyeErpOrderServiceImpl implements OtherOutLetsService { + + @Autowired + private DepotOutService depotOutService; + + @Override + public void validatorEntity(OtherOutLets entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + } + + @Override + public void createPrepose(OtherOutLets entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void queryOtherOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + OtherOutLets otherOutLets = selectById(id); + // 该其他出库单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(otherOutLets.getId()); + // 设置未下达商品数量-----其他出库单数量 - 已出库数量 + super.setOrCheckOperNumber(otherOutLets.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + otherOutLets.setErpOrderItemList(otherOutLets.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(otherOutLets); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertOtherOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取其他出库单状态 + OtherOutLets otherOutLets = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(otherOutLets)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(otherOutLets.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.OTHER_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherWareHousServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherWareHousServiceImpl.java new file mode 100644 index 0000000..7a6d477 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/OtherWareHousServiceImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.other.dao.OtherWareHousDao; +import com.skyeye.other.entity.OtherWareHous; +import com.skyeye.other.service.OtherWareHousService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OtherWareHousServiceImpl + * @Description: 其他入库单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "其他入库单", groupName = "其他订单模块", flowable = true) +public class OtherWareHousServiceImpl extends SkyeyeErpOrderServiceImpl implements OtherWareHousService { + + @Autowired + private DepotPutService depotPutService; + + @Override + public void validatorEntity(OtherWareHous entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + } + + @Override + public void createPrepose(OtherWareHous entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void queryOtherWareHousTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + OtherWareHous otherWareHous = selectById(id); + // 该其他入库单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(otherWareHous.getId()); + // 设置未下达商品数量-----其他入库单数量 - 已入库数量 + super.setOrCheckOperNumber(otherWareHous.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + otherWareHous.setErpOrderItemList(otherWareHous.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(otherWareHous); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertOtherWareHousToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取其他入库单状态 + OtherWareHous otherWareHous = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(otherWareHous)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(otherWareHous.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.OTHER_WARE_HOUS.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/SplitListServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/SplitListServiceImpl.java new file mode 100644 index 0000000..f1bd44d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/other/service/impl/SplitListServiceImpl.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.other.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialItemCode; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.classenum.MaterialNormsCodeType; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.other.dao.SplitListDao; +import com.skyeye.other.entity.SplitList; +import com.skyeye.other.service.SplitListService; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SplitListServiceImpl + * @Description: 拆分单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "拆分单", groupName = "拆分单模块", flowable = true) +public class SplitListServiceImpl extends SkyeyeErpOrderServiceImpl implements SplitListService { + + @Override + public void validatorEntity(SplitList entity) { + check(entity); + checkNormsCodeAndSplitList(entity, true); + } + + @Override + public void createPrepose(SplitList entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OTHER.getKey()); + } + + @Override + public void writeChild(SplitList entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public SplitList getDataFromDb(String id) { + SplitList splitList = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(splitList); + return splitList; + } + + private static void check(SplitList entity) { + // 组合件 + List assemblyList = entity.getErpOrderItemList().stream() + .filter(erpOrderItem -> MaterialInOrderType.ASSEMBLY.getKey() == erpOrderItem.getMType()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(assemblyList)) { + throw new CustomException("组合件不能为空"); + } + if (assemblyList.size() != 1) { + throw new CustomException("拆分单有且只有一件组合件"); + } + + // 普通子件 + List generalSubassemblyList = entity.getErpOrderItemList().stream() + .filter(erpOrderItem -> MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey() == erpOrderItem.getMType()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(generalSubassemblyList)) { + throw new CustomException("普通子件不能为空"); + } + } + + @Override + public SplitList selectById(String id) { + SplitList split = super.selectById(id); + split.getErpOrderItemList().forEach(erpOrderItem -> { + String name = MaterialInOrderType.getName(erpOrderItem.getMType()); + Map mTypeMation = new HashMap<>(); + mTypeMation.put("name", name); + erpOrderItem.setMTypeMation(mTypeMation); + }); + return split; + } + + @Override + public void approvalEndIsSuccess(SplitList entity) { + entity = selectById(entity.getId()); + // 校验商品规格条形码明细并进行仓库修改 + checkNormsCodeAndSplitList(entity, false); + + // 修改库存 + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + String depotId = erpOrderItem.getDepotId(); + String materialId = erpOrderItem.getMaterialId(); + String normsId = erpOrderItem.getNormsId(); + Integer operNumber = erpOrderItem.getOperNumber(); + Integer mType = erpOrderItem.getMType(); + if (MaterialInOrderType.ASSEMBLY.getKey().equals(mType)) { + erpCommonService.editMaterialNormsDepotStock(depotId, materialId, normsId, operNumber, DepotPutOutType.OUT.getKey()); + } else if (MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey().equals(mType)) { + erpCommonService.editMaterialNormsDepotStock(depotId, materialId, normsId, operNumber, DepotPutOutType.PUT.getKey()); + } + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 拆分单 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected void checkNormsCodeAndSplitList(SplitList entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行拆分的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询未入库和入库状态的条形码信息 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey(), MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + Map materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(MaterialNormsCode::getCodeNum, bean -> bean)); + // 设置条形码新的状态信息 + Map assemblyMap = new HashMap<>(); + Map assemblyDepotMap = new HashMap<>(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + Material material = materialMap.get(erpOrderItem.getMaterialId()); + if (material.getItemCode() == MaterialItemCode.ONE_ITEM_CODE.getKey()) { + // 一物一码 + erpOrderItem.getNormsCodeList().forEach(normsCode -> { + Integer mType = erpOrderItem.getMType(); + MaterialNormsCode materialNormsCode = materialNormsCodeMap.get(normsCode); + if (MaterialInOrderType.ASSEMBLY.getKey().equals(mType)) { + if (materialNormsCode.getInDepot() != MaterialNormsCodeInDepot.WAREHOUSING.getKey()) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】未入库或已出库,无法作为组合件,请确认", normsCode)); + } + if (!StrUtil.equals(materialNormsCode.getDepotId(), erpOrderItem.getDepotId())) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】所在仓库与实际仓库不符,请确认", normsCode)); + } + if (!onlyCheck) { + assemblyMap.put(normsCode, MaterialNormsCodeInDepot.OUTBOUND.getKey()); + } + } else if (MaterialInOrderType.GENERAL_SUBASSEMBLY.getKey().equals(mType)) { + if (materialNormsCode.getInDepot() != MaterialNormsCodeInDepot.NOT_IN_STOCK.getKey()) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】已入库或已出库,无法作为普通子件,请确认", normsCode)); + } + if (!onlyCheck) { + assemblyDepotMap.put(normsCode, erpOrderItem.getDepotId()); + assemblyMap.put(normsCode, MaterialNormsCodeInDepot.WAREHOUSING.getKey()); + } + } + if (!StrUtil.equals(materialNormsCode.getNormsId(), erpOrderItem.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + String currentTime = DateUtil.getTimeAndToString(); + String serviceClassName = getServiceClassName(); + materialNormsCodeList.forEach(materialNormsCode -> { + Integer inDepot = assemblyMap.get(materialNormsCode.getCodeNum()); + materialNormsCode.setInDepot(inDepot); + if (inDepot == MaterialNormsCodeInDepot.WAREHOUSING.getKey()) { + // 入库 + materialNormsCode.setDepotId(assemblyDepotMap.get(materialNormsCode.getCodeNum())); + materialNormsCode.setWarehousingTime(currentTime); + materialNormsCode.setFromObjectId(entity.getId()); + materialNormsCode.setFromObjectKey(serviceClassName); + materialNormsCode.setType(MaterialNormsCodeType.AUTHENTIC.getKey()); + } else if (inDepot == MaterialNormsCodeInDepot.OUTBOUND.getKey()) { + // 出库 + materialNormsCode.setOutboundTime(currentTime); + materialNormsCode.setToObjectId(entity.getId()); + materialNormsCode.setToObjectKey(serviceClassName); + } + }); + materialNormsCodeService.updateEntity(materialNormsCodeList, StrUtil.EMPTY); + } + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/controller/OtherWiseOrderController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/controller/OtherWiseOrderController.java new file mode 100644 index 0000000..7f4f547 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/controller/OtherWiseOrderController.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.otherwise.entity.ErpOtherWiseOrder; +import com.skyeye.otherwise.service.OtherWiseOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OtherWiseOrderController + * @Description: 其他微服务订单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 11:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "其他微服务订单", tags = "其他微服务订单", modelName = "其他微服务订单") +public class OtherWiseOrderController { + + @Autowired + private OtherWiseOrderService otherWiseOrderService; + + /** + * 新增已经审批通过的单据 + * --给其他微服务使用,比如:售后服务等 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createApprovelSuccessOrder", value = "新增已经审批通过的单据", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ErpOtherWiseOrder.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "createId", name = "createId", value = "创建人id", required = "required"), + @ApiImplicitParam(id = "createTime", name = "createTime", value = "创建时间", required = "required"), + @ApiImplicitParam(id = "lastUpdateId", name = "lastUpdateId", value = "最后更新人id", required = "required"), + @ApiImplicitParam(id = "lastUpdateTime", name = "lastUpdateTime", value = "最后更新日期", required = "required")}) + @RequestMapping("/post/OtherWiseOrderController/createApprovelSuccessOrder") + public void createApprovelSuccessOrder(InputObject inputObject, OutputObject outputObject) { + otherWiseOrderService.createApprovelSuccessOrder(inputObject, outputObject); + } + + /** + * 其他微服务的单据转仓库出库单时,根据id查询其他微服务的单据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOtherWiseOrderTransById", value = "其他微服务的单据转仓库出库单时,根据id查询其他微服务的单据信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherWiseOrderController/queryOtherWiseOrderTransById") + public void queryOtherWiseOrderTransById(InputObject inputObject, OutputObject outputObject) { + otherWiseOrderService.queryOtherWiseOrderTransById(inputObject, outputObject); + } + + /** + * 其他微服务的单据转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertOtherWiseOrderToDepotOut", value = "其他微服务的单据转仓库出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OtherWiseOrderController/insertOtherWiseOrderToDepotOut") + public void insertOtherWiseOrderToDepotOut(InputObject inputObject, OutputObject outputObject) { + otherWiseOrderService.insertOtherWiseOrderToDepotOut(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/dao/OtherWiseOrderDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/dao/OtherWiseOrderDao.java new file mode 100644 index 0000000..aaf968a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/dao/OtherWiseOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.otherwise.entity.OtherWiseOrder; + +/** + * @ClassName: OtherWiseOrderDao + * @Description: 其他微服务订单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 11:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherWiseOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrder.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrder.java new file mode 100644 index 0000000..b07e859 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrder.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ErpOtherWiseOrder + * @Description: 其他微服务创建ERP单据的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/19 18:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("其他微服务创建ERP单据的实体类") +public class ErpOtherWiseOrder extends OperatorUserInfo { + + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑", required = "required") + private String id; + + @ApiModelProperty(value = "单据编号", required = "required") + private String oddNumber; + + @ApiModelProperty(value = "状态", required = "required") + private String state; + + @ApiModelProperty(value = "流程实例id") + private String processInstanceId; + + @ApiModelProperty(value = "出入库类型,参考#DepotPutOutType", required = "required") + private Integer type; + + @ApiModelProperty(value = "订单类型,每个服务类的serviceClassName", required = "required") + private String idKey; + + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "业务员id") + private String salesman; + + @ApiModelProperty(value = "来源单据类型") + private Integer fromTypeId; + + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @ApiModelProperty(value = "实际完成时间") + private String realComplateTime; + + @ApiModelProperty(value = "商品列表,json串", required = "required,json") + private List erpOrderItemList; + + @ApiModelProperty(value = "质检类型,参考#OrderQualityInspectionType") + private Integer qualityInspection; + + @ApiModelProperty(value = "是否需要出入库,参考#WhetherEnum") + private Integer needDepot; + + @ApiModelProperty("其他状态信息,根据单据类型不同,状态信息表达含义不同。") + private Integer otherState; + + @ApiModelProperty(value = "部门id") + private String departmentId; + + @ApiModelProperty(value = "车间id") + private String farmId; + + @ApiModelProperty(value = "关联项目id") + private String projectId; + + @ApiModelProperty(value = "优惠率,默认为0.00", required = "double") + private String discount; + + @ApiModelProperty(value = "优惠金额/折损扣费,默认为0.00", required = "double") + private String discountMoney; + + @ApiModelProperty(value = "是否需要统筹,参考#WhetherEnum") + private Integer needOverPlan; + + @ApiModelProperty(value = "计划完成时间") + private String planComplateTime; + + @ApiModelProperty(value = "付款类型,参考#PayTypeEnum", required = "num", defaultValue = "0") + private String payType; + + @ApiModelProperty(value = "关联的客户/供应商/会员id") + private String holderId; + + @ApiModelProperty(value = "关联的客户/供应商/会员的className") + private String holderKey; + + @ApiModelProperty(value = "合计总金额(减去优惠后的金额,加上其他金额)") + private String totalPrice; + + @ApiModelProperty(value = "账户id") + private String accountId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrderItem.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrderItem.java new file mode 100644 index 0000000..81e071c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/ErpOtherWiseOrderItem.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +/** + * @ClassName: ErpOtherWiseOrderItem + * @Description: 其他微服务创建ERP单据的子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/19 18:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("其他微服务创建ERP单据的子单据实体类") +public class ErpOtherWiseOrderItem extends SkyeyeLinkData { + + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @ApiModelProperty(value = "仓库id") + private String depotId; + + @ApiModelProperty(value = "调拨时,对方仓库Id") + private String anotherDepotId; + + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @ApiModelProperty(value = "商品在单据中的类型,参考#MaterialInOrderType", required = "num") + private Integer mType; + + @ApiModelProperty(value = "质检类型,参考#OrderItemQualityInspectionType", required = "num") + private Integer qualityInspection; + + @ApiModelProperty(value = "质检比例(%),质检类型为抽检时才生效") + private String qualityInspectionRatio; + + @ApiModelProperty(value = "交货日期") + private String deliveryTime; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/OtherWiseOrder.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/OtherWiseOrder.java new file mode 100644 index 0000000..1474fcd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/entity/OtherWiseOrder.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: OtherWiseOrder + * @Description: 其他微服务订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 11:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:otherWise", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("其他微服务订单实体类") +public class OtherWiseOrder extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/OtherWiseOrderService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/OtherWiseOrderService.java new file mode 100644 index 0000000..f0aaf0d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/OtherWiseOrderService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.otherwise.entity.OtherWiseOrder; + +/** + * @ClassName: OtherWiseOrderService + * @Description: 其他微服务订单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 11:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OtherWiseOrderService extends SkyeyeErpOrderService { + + void createApprovelSuccessOrder(InputObject inputObject, OutputObject outputObject); + + void queryOtherWiseOrderTransById(InputObject inputObject, OutputObject outputObject); + + void insertOtherWiseOrderToDepotOut(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/impl/OtherWiseOrderServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/impl/OtherWiseOrderServiceImpl.java new file mode 100644 index 0000000..893b54f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/otherwise/service/impl/OtherWiseOrderServiceImpl.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.otherwise.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.exception.CustomException; +import com.skyeye.otherwise.dao.OtherWiseOrderDao; +import com.skyeye.otherwise.entity.OtherWiseOrder; +import com.skyeye.otherwise.service.OtherWiseOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OtherWiseOrderServiceImpl + * @Description: 其他微服务订单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 11:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "其他微服务订单", groupName = "其他微服务订单", flowable = true) +public class OtherWiseOrderServiceImpl extends SkyeyeErpOrderServiceImpl implements OtherWiseOrderService { + + @Autowired + private DepotOutService depotOutService; + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void createApprovelSuccessOrder(InputObject inputObject, OutputObject outputObject) { + OtherWiseOrder otherWiseOrder = inputObject.getParams(OtherWiseOrder.class); + save(otherWiseOrder); + skyeyeErpOrderItemService.saveLinkList(otherWiseOrder.getId(), otherWiseOrder.getErpOrderItemList()); + } + + @Override + public void queryOtherWiseOrderTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + OtherWiseOrder otherWiseOrder = selectById(id); + // 该其他微服务订单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(otherWiseOrder.getId()); + // 设置未下达商品数量-----其他微服务订单数量 - 已出库数量 + super.setOrCheckOperNumber(otherWiseOrder.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + otherWiseOrder.setErpOrderItemList(otherWiseOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(otherWiseOrder); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertOtherWiseOrderToDepotOut(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取采购退货单状态 + OtherWiseOrder otherWiseOrder = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(otherWiseOrder)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(otherWiseOrder.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.getItemKey(otherWiseOrder.getIdKey())); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/OutLetState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/OutLetState.java new file mode 100644 index 0000000..097308d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/OutLetState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OutLetState + * @Description: 领料单/补料单出库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OutLetState implements SkyeyeEnumClass { + + NEED_OUTLET(1, "待出库", "blue", true, false), + PARTIAL_OUTLET(2, "部分出库", "orange", true, false), + COMPLATE_OUTLET(3, "全部出库", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PatchOutLetFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PatchOutLetFromType.java new file mode 100644 index 0000000..a81ff85 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PatchOutLetFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PatchOutLetFromType + * @Description: 补料出库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PatchOutLetFromType implements SkyeyeEnumClass { + + PATCH_OUT_LET(1, "补料单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickFromType.java new file mode 100644 index 0000000..fb49f1b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PickFromType + * @Description: 领料单/补料单/退料单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PickFromType implements SkyeyeEnumClass { + + MACHIN(1, "加工单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickNormsCodeUseState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickNormsCodeUseState.java new file mode 100644 index 0000000..45ca0ea --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PickNormsCodeUseState.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PickNormsCodeUseState + * @Description: 物料被加工时的状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PickNormsCodeUseState implements SkyeyeEnumClass { + + WAIT_USE(1, "待使用", "red", true, false), + USED(2, "已使用", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PutState.java new file mode 100644 index 0000000..8d4b9cb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/PutState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PutState + * @Description: 退料单入库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PutState implements SkyeyeEnumClass { + + NEED_PUT(1, "待入库", "blue", true, false), + PARTIAL_PUT(2, "部分入库", "orange", true, false), + COMPLATE_PUT(3, "全部入库", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/RequisitionOutLetFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/RequisitionOutLetFromType.java new file mode 100644 index 0000000..6daf5fd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/RequisitionOutLetFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: RequisitionOutLetFromType + * @Description: 领料出库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum RequisitionOutLetFromType implements SkyeyeEnumClass { + + REQUISITION_MATERIAL(1, "领料单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/ReturnPutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/ReturnPutFromType.java new file mode 100644 index 0000000..3b032f7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/classenum/ReturnPutFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ReturnPutFromType + * @Description: 退料入库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ReturnPutFromType implements SkyeyeEnumClass { + + RETURN_PUT(1, "退料单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/DepartmentStockController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/DepartmentStockController.java new file mode 100644 index 0000000..a31c39b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/DepartmentStockController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.service.DepartmentStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DepartmentStockController + * @Description: 物料单信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/20 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "部门/车间物料库存信息", tags = "部门/车间物料库存信息", modelName = "物料单") +public class DepartmentStockController { + + @Autowired + private DepartmentStockService departmentStockService; + + /** + * 获取登录人部门/车间物料库存信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpdepartstock001", value = "获取登录人部门/车间物料库存信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DepartmentStockController/queryDepartmentStockList") + public void queryDepartmentStockList(InputObject inputObject, OutputObject outputObject) { + departmentStockService.queryPageList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchMaterialController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchMaterialController.java new file mode 100644 index 0000000..e6d3813 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchMaterialController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.PatchMaterial; +import com.skyeye.pick.entity.PatchOutLet; +import com.skyeye.pick.service.PatchMaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PatchMaterialController + * @Description: 补料申请单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "补料单", tags = "补料单", modelName = "物料单") +public class PatchMaterialController { + + @Autowired + private PatchMaterialService patchMaterialService; + + /** + * 获取补料申请单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppick003", value = "获取补料申请单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PatchMaterialController/queryPatchMaterialOrderList") + public void queryPatchMaterialOrderList(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑补料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePatchMaterial", value = "新增/编辑补料申请单信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PatchMaterial.class) + @RequestMapping("/post/PatchMaterialController/writePatchMaterial") + public void writePatchMaterial(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除补料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePatchMaterialById", value = "删除补料申请单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PatchMaterialController/deletePatchMaterialById") + public void deletePatchMaterialById(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.deleteById(inputObject, outputObject); + } + + /** + * 补料申请单提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitPatchMaterial", value = "补料申请单提交审核", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/PatchMaterialController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销补料申请单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokePatchMaterial", value = "撤销补料申请单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/PatchMaterialController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.revoke(inputObject, outputObject); + } + + /** + * 转补料出库单时,根据id查询补料单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPatchMaterialTransById", value = "转补料出库单时,根据id查询补料单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PatchMaterialController/queryPatchMaterialTransById") + public void queryPatchMaterialTransById(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.queryPatchMaterialTransById(inputObject, outputObject); + } + + /** + * 补料单信息转补料出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPatchMaterialToTurnOut", value = "补料单信息转补料出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PatchOutLet.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PatchMaterialController/insertPatchMaterialToTurnOut") + public void insertPatchMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + patchMaterialService.insertPatchMaterialToTurnOut(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchOutLetController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchOutLetController.java new file mode 100644 index 0000000..031998f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/PatchOutLetController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.pick.entity.PatchOutLet; +import com.skyeye.pick.service.PatchOutLetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PatchOutLetController + * @Description: 补料出库单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "补料出库单", tags = "补料出库单", modelName = "物料单") +public class PatchOutLetController { + + @Autowired + private PatchOutLetService patchOutLetService; + + /** + * 获取补料出库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPatchOutLetList", value = "获取补料出库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PatchOutLetController/queryPatchOutLetList") + public void queryPatchOutLetList(InputObject inputObject, OutputObject outputObject) { + patchOutLetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑补料出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePatchOutLet", value = "新增/编辑补料出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PatchOutLet.class) + @RequestMapping("/post/PatchOutLetController/writePatchOutLet") + public void writePatchOutLet(InputObject inputObject, OutputObject outputObject) { + patchOutLetService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询补料出库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPatchOutLetTransById", value = "转仓库出库单时,根据id查询补料出库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PatchOutLetController/queryPatchOutLetTransById") + public void queryPatchOutLetTransById(InputObject inputObject, OutputObject outputObject) { + patchOutLetService.queryPatchOutLetTransById(inputObject, outputObject); + } + + /** + * 补料出库单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPatchOutLetToTurnDepot", value = "补料出库单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PatchOutLetController/insertPatchOutLetToTurnDepot") + public void insertPatchOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + patchOutLetService.insertPatchOutLetToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionMaterialController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionMaterialController.java new file mode 100644 index 0000000..ecd0cbc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionMaterialController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.RequisitionMaterial; +import com.skyeye.pick.entity.RequisitionOutLet; +import com.skyeye.pick.service.RequisitionMaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RequisitionMaterialController + * @Description: 领料申请单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "领料单", tags = "领料单", modelName = "物料单") +public class RequisitionMaterialController { + + @Autowired + private RequisitionMaterialService requisitionMaterialService; + + /** + * 获取领料申请单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppick001", value = "获取领料申请单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RequisitionMaterialController/queryRequisitionMaterialOrderList") + public void queryRequisitionMaterialOrderList(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑领料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRequisitionMaterial", value = "新增/编辑领料申请单信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RequisitionMaterial.class) + @RequestMapping("/post/RequisitionMaterialController/writeRequisitionMaterial") + public void writeRequisitionMaterial(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除领料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteRequisitionMaterialById", value = "删除领料申请单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RequisitionMaterialController/deleteRequisitionMaterialById") + public void deleteRequisitionMaterialById(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.deleteById(inputObject, outputObject); + } + + /** + * 领料申请单提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitRequisitionMaterial", value = "领料申请单提交审核", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/RequisitionMaterialController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销领料申请单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeRequisitionMaterial", value = "撤销领料申请单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/RequisitionMaterialController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.revoke(inputObject, outputObject); + } + + /** + * 转领料出库单时,根据id查询领料单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRequisitionMaterialTransById", value = "转领料出库单时,根据id查询领料单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RequisitionMaterialController/queryRequisitionMaterialTransById") + public void queryRequisitionMaterialTransById(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.queryRequisitionMaterialTransById(inputObject, outputObject); + } + + /** + * 领料单信息转领料出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertRequisitionMaterialToTurnOut", value = "领料单信息转领料出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RequisitionOutLet.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RequisitionMaterialController/insertRequisitionMaterialToTurnOut") + public void insertRequisitionMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + requisitionMaterialService.insertRequisitionMaterialToTurnOut(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionOutLetController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionOutLetController.java new file mode 100644 index 0000000..e894b2f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/RequisitionOutLetController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.pick.entity.RequisitionOutLet; +import com.skyeye.pick.service.RequisitionOutLetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RequisitionOutLetController + * @Description: 领料出库单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "领料出库单", tags = "领料出库单", modelName = "物料单") +public class RequisitionOutLetController { + + @Autowired + private RequisitionOutLetService requisitionOutLetService; + + /** + * 获取领料出库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRequisitionOutLetList", value = "获取领料出库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RequisitionOutLetController/queryRequisitionOutLetList") + public void queryRequisitionOutLetList(InputObject inputObject, OutputObject outputObject) { + requisitionOutLetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑领料出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRequisitionOutLet", value = "新增/编辑领料出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RequisitionOutLet.class) + @RequestMapping("/post/RequisitionOutLetController/writeRequisitionOutLet") + public void writeRequisitionOutLet(InputObject inputObject, OutputObject outputObject) { + requisitionOutLetService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询领料出库单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRequisitionOutLetsTransById", value = "转仓库出库单时,根据id查询领料出库单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RequisitionOutLetsController/queryRequisitionOutLetsTransById") + public void queryRequisitionOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + requisitionOutLetService.queryRequisitionOutLetsTransById(inputObject, outputObject); + } + + /** + * 领料出库单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertRequisitionOutLetsToTurnDepot", value = "领料出库单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RequisitionOutLetsController/insertRequisitionOutLetsToTurnDepot") + public void insertRequisitionOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + requisitionOutLetService.insertRequisitionOutLetsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnMaterialController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnMaterialController.java new file mode 100644 index 0000000..4c1ac22 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnMaterialController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.ReturnMaterial; +import com.skyeye.pick.entity.ReturnPut; +import com.skyeye.pick.service.ReturnMaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReturnMaterialController + * @Description: 退料申请单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/20 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "退料单", tags = "退料单", modelName = "物料单") +public class ReturnMaterialController { + + @Autowired + private ReturnMaterialService returnMaterialService; + + /** + * 获取退料申请单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erppick002", value = "获取退料申请单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReturnMaterialController/queryReturnMaterialOrderList") + public void queryReturnMaterialOrderList(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑退料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeReturnMaterial", value = "新增/编辑退料申请单信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReturnMaterial.class) + @RequestMapping("/post/ReturnMaterialController/writeReturnMaterial") + public void writeReturnMaterial(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除退料申请单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteReturnMaterialById", value = "删除退料申请单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReturnMaterialController/deleteReturnMaterialById") + public void deleteReturnMaterialById(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.deleteById(inputObject, outputObject); + } + + /** + * 退料申请单提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitReturnMaterial", value = "退料申请单提交审核", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ReturnMaterialController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销退料申请单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeReturnMaterial", value = "撤销退料申请单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ReturnMaterialController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.revoke(inputObject, outputObject); + } + + /** + * 转退料入库单时,根据id查询退料单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReturnMaterialTransById", value = "转退料入库单时,根据id查询退料单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReturnMaterialController/queryReturnMaterialTransById") + public void queryReturnMaterialTransById(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.queryReturnMaterialTransById(inputObject, outputObject); + } + + /** + * 退料单信息转退料入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertReturnMaterialToTurnOut", value = "退料单信息转退料入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReturnPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReturnMaterialController/insertReturnMaterialToTurnOut") + public void insertReturnMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + returnMaterialService.insertReturnMaterialToTurnOut(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnPutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnPutController.java new file mode 100644 index 0000000..317071f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/controller/ReturnPutController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.pick.entity.ReturnPut; +import com.skyeye.pick.service.ReturnPutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReturnPutController + * @Description: 退料入库单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 21:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "退料入库单", tags = "退料入库单", modelName = "物料单") +public class ReturnPutController { + + @Autowired + private ReturnPutService returnPutService; + + /** + * 获取退料入库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReturnPutList", value = "获取退料入库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReturnPutController/queryReturnPutList") + public void queryReturnPutList(InputObject inputObject, OutputObject outputObject) { + returnPutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑退料入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeReturnPut", value = "新增/编辑退料入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReturnPut.class) + @RequestMapping("/post/ReturnPutController/writeReturnPut") + public void writeReturnPut(InputObject inputObject, OutputObject outputObject) { + returnPutService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询退料入库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReturnPutTransById", value = "转仓库入库单时,根据id查询退料入库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReturnPutController/queryReturnPutTransById") + public void queryReturnPutTransById(InputObject inputObject, OutputObject outputObject) { + returnPutService.queryReturnPutTransById(inputObject, outputObject); + } + + /** + * 退料入库单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertReturnPutToTurnDepot", value = "退料入库单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReturnPutController/insertReturnPutToTurnDepot") + public void insertReturnPutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + returnPutService.insertReturnPutToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/DepartmentStockDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/DepartmentStockDao.java new file mode 100644 index 0000000..21d4c47 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/DepartmentStockDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.DepartmentStock; + +/** + * @ClassName: DepartmentStockDao + * @Description: 部门物料库存信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:56 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepartmentStockDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchMaterialDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchMaterialDao.java new file mode 100644 index 0000000..e1d1e67 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchMaterialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.PatchMaterial; + +/** + * @ClassName: PatchMaterialDao + * @Description: 补料申请单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 11:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PatchMaterialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchOutLetDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchOutLetDao.java new file mode 100644 index 0000000..c561832 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PatchOutLetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.PatchOutLet; + +/** + * @ClassName: PatchOutLetDao + * @Description: 补料出库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PatchOutLetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickChildDao.java new file mode 100644 index 0000000..7d6ef40 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickChildDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.PickChild; + +/** + * @ClassName: PickChildDao + * @Description: 物料单子单据数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:59 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PickChildDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickDao.java new file mode 100644 index 0000000..49bc27f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/PickDao.java @@ -0,0 +1,9 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +public interface PickDao { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionMaterialDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionMaterialDao.java new file mode 100644 index 0000000..2f12cfc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionMaterialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.RequisitionMaterial; + +/** + * @ClassName: RequisitionMaterialDao + * @Description: 领料申请单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 11:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RequisitionMaterialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionOutLetDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionOutLetDao.java new file mode 100644 index 0000000..d67e372 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/RequisitionOutLetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.RequisitionOutLet; + +/** + * @ClassName: RequisitionOutLetDao + * @Description: 领料出库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RequisitionOutLetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnMaterialDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnMaterialDao.java new file mode 100644 index 0000000..c500c87 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnMaterialDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.ReturnMaterial; + +/** + * @ClassName: ReturnMaterialDao + * @Description: 退料申请单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 11:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReturnMaterialDao extends SkyeyeBaseMapper { + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnPutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnPutDao.java new file mode 100644 index 0000000..c480d90 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/dao/ReturnPutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pick.entity.ReturnPut; + +/** + * @ClassName: ReturnPutDao + * @Description: 退料入库单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:49 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReturnPutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/DepartmentStock.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/DepartmentStock.java new file mode 100644 index 0000000..37efda9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/DepartmentStock.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.farm.entity.Farm; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: DepartmentStock + * @Description: 部门物料库存信息 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_department_stock") +@ApiModel("部门物料库存信息") +public class DepartmentStock extends CommonInfo { + + @TableField(value = "material_id") + @Property(value = "产品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "department_id") + @Property(value = "部门id") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间id") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField(value = "stock") + @Property(value = "数量") + private Integer stock; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchMaterial.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchMaterial.java new file mode 100644 index 0000000..0f684ce --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchMaterial.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.pick.entity.common.Pick; +import lombok.Data; + +/** + * @ClassName: PatchMaterial + * @Description: 补料单 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_PATCH_CACHE_KEY, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_pick_header", autoResultMap = true) +@ApiModel("补料单实体类") +public class PatchMaterial extends Pick { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchOutLet.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchOutLet.java new file mode 100644 index 0000000..bb563b7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PatchOutLet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: PatchOutLet + * @Description: 补料出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:patchOutLet", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("补料出库单实体类") +public class PatchOutLet extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PickChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PickChild.java new file mode 100644 index 0000000..59ddd1a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/PickChild.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.depot.entity.Depot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +/** + * @ClassName: PickChild + * @Description: 物料单子单据 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:52 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_pick_child", autoResultMap = true) +@ApiModel("物料单子单据") +public class PickChild extends CommonInfo { + + @TableId("id") + private String id; + + @TableField(value = "parent_id") + @Property(value = "物料单id") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Depot depotMation; + + @TableField(value = "need_num") + @ApiModelProperty(value = "领料/退料数量", required = "required,num") + private Integer needNum; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionMaterial.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionMaterial.java new file mode 100644 index 0000000..8bf2865 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionMaterial.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.pick.entity.common.Pick; +import lombok.Data; + +/** + * @ClassName: RequisitionMaterial + * @Description: 领料单 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_REQUISITION_CACHE_KEY, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_pick_header", autoResultMap = true) +@ApiModel("领料单实体类") +public class RequisitionMaterial extends Pick { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionOutLet.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionOutLet.java new file mode 100644 index 0000000..85952c8 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/RequisitionOutLet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: RequisitionOutLet + * @Description: 领料出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:requisitionOutLet", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("领料出库单实体类") +public class RequisitionOutLet extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnMaterial.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnMaterial.java new file mode 100644 index 0000000..e3f15ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnMaterial.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.pick.entity.common.Pick; +import lombok.Data; + +/** + * @ClassName: ReturnMaterial + * @Description: 退料单 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_RETURN_CACHE_KEY, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_pick_header", autoResultMap = true) +@ApiModel("退料单实体类") +public class ReturnMaterial extends Pick { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnPut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnPut.java new file mode 100644 index 0000000..1dc99cb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/ReturnPut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ReturnPut + * @Description: 退料入库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:returnPut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("退料入库单实体类") +public class ReturnPut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/common/Pick.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/common/Pick.java new file mode 100644 index 0000000..2f80c32 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/entity/common/Pick.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.entity.common; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.depot.entity.Depot; +import com.skyeye.farm.entity.Farm; +import com.skyeye.pick.entity.PickChild; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Pick + * @Description: 物料单父类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 8:49 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("加工单实体类") +public class Pick extends SkyeyeFlowable { + + /** + * 订单类型,每个服务类的serviceClassName + */ + @TableField(value = "id_key", updateStrategy = FieldStrategy.NEVER) + private String idKey; + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "department_id") + @ApiModelProperty(value = "部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "部门信息") + private Map departmentMation; + + @TableField(value = "farm_id") + @ApiModelProperty(value = "车间id") + private String farmId; + + @TableField(exist = false) + @Property(value = "车间信息") + private Farm farmMation; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#PickFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField(exist = false) + @ApiModelProperty(value = "子单据信息", required = "required,json") + private List pickChildList; + + @TableField("other_state") + @Property("其他状态信息,根据单据类型不同,状态信息表达含义不同。") + private Integer otherState; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/DepartmentStockService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/DepartmentStockService.java new file mode 100644 index 0000000..8edc549 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/DepartmentStockService.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.pick.entity.DepartmentStock; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DepartmentStockService + * @Description: 部门/车间物料库存信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DepartmentStockService extends SkyeyeBusinessService { + + /** + * 修改部门/车间库存存量信息 + * + * @param departmentId 部门id + * @param farmId 车间id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 出入库类型,参考#DepotPutOutType + */ + void updateDepartmentStock(String departmentId, String farmId, String materialId, String normsId, Integer operNumber, int type); + + DepartmentStock queryDepartmentStock(String departmentId, String farmId, String normsId); + + Map queryNormsDepartmentStock(String departmentId, String farmId, List normsIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ErpPickService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ErpPickService.java new file mode 100644 index 0000000..6d05e26 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ErpPickService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpPickService + * @Description: 物料单单据的service接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 20:22 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpPickService extends SkyeyeFlowableService { + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + + void editOtherState(String id, Integer otherState); + + Map calcMaterialNormsNumByFromId(String fromId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchMaterialService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchMaterialService.java new file mode 100644 index 0000000..54c0ae7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchMaterialService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.PatchMaterial; + +/** + * @ClassName: PatchMaterialService + * @Description: 补料申请单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PatchMaterialService extends ErpPickService { + + void queryPatchMaterialTransById(InputObject inputObject, OutputObject outputObject); + + void insertPatchMaterialToTurnOut(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchOutLetService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchOutLetService.java new file mode 100644 index 0000000..73e1b37 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PatchOutLetService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.PatchOutLet; + +/** + * @ClassName: PatchOutLetService + * @Description: 补料出库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PatchOutLetService extends SkyeyeErpOrderService { + + void queryPatchOutLetTransById(InputObject inputObject, OutputObject outputObject); + + void insertPatchOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PickChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PickChildService.java new file mode 100644 index 0000000..005cf37 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/PickChildService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.pick.entity.PickChild; + +import java.util.List; + +/** + * @ClassName: PickChildService + * @Description: 物料单子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 9:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PickChildService extends SkyeyeBusinessService { + + void deleteByParentId(String pickId); + + List selectByParentId(String pickId); + + void saveList(String pickId, List pickChildList, String userId); + + List queryPickChildListByParentIds(List ids); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionMaterialService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionMaterialService.java new file mode 100644 index 0000000..22be0c8 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionMaterialService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.RequisitionMaterial; + +/** + * @ClassName: RequisitionMaterialService + * @Description: 领料申请单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RequisitionMaterialService extends ErpPickService { + + void queryRequisitionMaterialTransById(InputObject inputObject, OutputObject outputObject); + + void insertRequisitionMaterialToTurnOut(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionOutLetService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionOutLetService.java new file mode 100644 index 0000000..bdb4fb9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/RequisitionOutLetService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.RequisitionOutLet; + +/** + * @ClassName: RequisitionOutLetService + * @Description: 领料出库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RequisitionOutLetService extends SkyeyeErpOrderService { + + void queryRequisitionOutLetsTransById(InputObject inputObject, OutputObject outputObject); + + void insertRequisitionOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnMaterialService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnMaterialService.java new file mode 100644 index 0000000..48bcef3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnMaterialService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.ReturnMaterial; + +/** + * @ClassName: ReturnMaterialService + * @Description: 退料申请单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/20 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReturnMaterialService extends ErpPickService { + + void queryReturnMaterialTransById(InputObject inputObject, OutputObject outputObject); + + void insertReturnMaterialToTurnOut(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnPutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnPutService.java new file mode 100644 index 0000000..b09e58f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/ReturnPutService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pick.entity.ReturnPut; + +/** + * @ClassName: ReturnPutService + * @Description: 退料入库单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 21:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReturnPutService extends SkyeyeErpOrderService { + + void queryReturnPutTransById(InputObject inputObject, OutputObject outputObject); + + void insertReturnPutToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/DepartmentStockServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/DepartmentStockServiceImpl.java new file mode 100644 index 0000000..d85572b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/DepartmentStockServiceImpl.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.dao.DepartmentStockDao; +import com.skyeye.pick.entity.DepartmentStock; +import com.skyeye.pick.service.DepartmentStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DepartmentStockServiceImpl + * @Description: 部门物料库存信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "部门/车间物料库存信息", groupName = "部门/车间物料库存", manageShow = false) +public class DepartmentStockServiceImpl extends SkyeyeBusinessServiceImpl implements DepartmentStockService { + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private FarmService farmService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "department")) { + // 我所在部门 + String departmentId = InputObject.getLogParamsStatic().get("departmentId").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getDepartmentId), departmentId); + } else if (StrUtil.equals(commonPageInfo.getType(), "farm")) { + // 指定车间 + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + commonPageInfo.setObjectId("-"); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getFarmId), commonPageInfo.getObjectId()); + } + return queryWrapper; + } + + @Override + protected List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + farmService.setMationForMap(beans, "farmId", "farmMation"); + return beans; + } + + @Override + public void updateDepartmentStock(String departmentId, String farmId, String materialId, String normsId, Integer operNumber, int type) { + DepartmentStock departmentStock = queryDepartmentStock(departmentId, farmId, normsId); + // 如果该规格在指定部门中已经有存储数据,则直接做修改 + if (ObjectUtil.isNotEmpty(departmentStock)) { + int stock = departmentStock.getStock(); + if (type == DepotPutOutType.PUT.getKey()) { + // 入库 + stock = stock + operNumber; + } else if (type == DepotPutOutType.OUT.getKey()) { + // 出库 + stock = stock - operNumber; + } + editDepartmentStock(departmentId, farmId, normsId, stock); + } else { + int stockNum = 0; + if (type == DepotPutOutType.PUT.getKey()) { + // 入库 + stockNum = operNumber; + } else if (type == DepotPutOutType.OUT.getKey()) { + // 出库 + stockNum = stockNum - operNumber; + } + if (stockNum < 0) { + throw new CustomException("部门库存存量不足."); + } + saveDepartmentStock(departmentId, farmId, materialId, normsId, stockNum); + } + } + + @Override + public DepartmentStock queryDepartmentStock(String departmentId, String farmId, String normsId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getDepartmentId), departmentId); + if (StrUtil.isNotEmpty(farmId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getFarmId), farmId); + } else { + String farmIdKey = MybatisPlusUtil.toColumns(DepartmentStock::getFarmId); + queryWrapper.and(Wrapper -> { + Wrapper.isNull(farmIdKey).or().eq(farmIdKey, StrUtil.EMPTY); + }); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getNormsId), normsId); + return getOne(queryWrapper); + } + + private void editDepartmentStock(String departmentId, String farmId, String normsId, int stock) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getDepartmentId), departmentId); + if (StrUtil.isNotEmpty(farmId)) { + updateWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getFarmId), farmId); + } else { + String farmIdKey = MybatisPlusUtil.toColumns(DepartmentStock::getFarmId); + updateWrapper.and(Wrapper -> { + Wrapper.isNull(farmIdKey).or().eq(farmIdKey, StrUtil.EMPTY); + }); + } + updateWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getNormsId), normsId); + updateWrapper.set(MybatisPlusUtil.toColumns(DepartmentStock::getStock), stock); + update(updateWrapper); + } + + private void saveDepartmentStock(String departmentId, String farmId, String materialId, String normsId, int stock) { + DepartmentStock departmentStock = new DepartmentStock(); + departmentStock.setDepartmentId(departmentId); + departmentStock.setFarmId(farmId); + departmentStock.setMaterialId(materialId); + departmentStock.setNormsId(normsId); + departmentStock.setStock(stock); + save(departmentStock); + } + + @Override + public Map queryNormsDepartmentStock(String departmentId, String farmId, List normsIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getDepartmentId), departmentId); + if (StrUtil.isNotEmpty(farmId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(DepartmentStock::getFarmId), farmId); + } else { + String farmIdKey = MybatisPlusUtil.toColumns(DepartmentStock::getFarmId); + queryWrapper.and(Wrapper -> { + Wrapper.isNull(farmIdKey).or().eq(farmIdKey, StrUtil.EMPTY); + }); + } + queryWrapper.in(MybatisPlusUtil.toColumns(DepartmentStock::getNormsId), normsIds); + List departmentStockList = list(queryWrapper); + + Map stockMap = departmentStockList.stream() + .collect(Collectors.toMap(DepartmentStock::getNormsId, DepartmentStock::getStock)); + normsIds.forEach(normsId -> { + if (!stockMap.containsKey(normsId)) { + stockMap.put(normsId, 0); + } + }); + return stockMap; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ErpPickServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ErpPickServiceImpl.java new file mode 100644 index 0000000..97f090e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ErpPickServiceImpl.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.farm.service.FarmService; +import com.skyeye.machin.service.MachinService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.entity.PickChild; +import com.skyeye.pick.entity.common.Pick; +import com.skyeye.pick.service.ErpPickService; +import com.skyeye.pick.service.PickChildService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ErpPickServiceImpl + * @Description: 领料申请单、补料申请单、退料申请单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class ErpPickServiceImpl, T extends Pick> extends SkyeyeFlowableServiceImpl implements ErpPickService { + + @Autowired + private MachinService machinService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private PickChildService pickChildService; + + @Autowired + private ErpDepotService erpDepotService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private MaterialService materialService; + + @Autowired + private FarmService farmService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getIdKey), getServiceClassName()); + if (StrUtil.equals(commonPageInfo.getType(), "department")) { + // 我所在部门 + String departmentId = InputObject.getLogParamsStatic().get("departmentId").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getDepartmentId), departmentId); + } else if (StrUtil.equals(commonPageInfo.getType(), "farm")) { + // 指定车间 + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getFarmId), commonPageInfo.getObjectId()); + } + return queryWrapper; + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + machinService.setMationForMap(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void createPrepose(T entity) { + super.createPrepose(entity); + entity.setIdKey(getServiceClassName()); + // 设置商品为使用中 + entity.getPickChildList().forEach(pickChild -> { + materialService.setUsed(pickChild.getMaterialId()); + }); + } + + @Override + public void writeChild(T entity, String userId) { + pickChildService.saveList(entity.getId(), entity.getPickChildList(), userId); + super.writeChild(entity, userId); + } + + @Override + public T getDataFromDb(String id) { + T pick = super.getDataFromDb(id); + List pickChildList = pickChildService.selectByParentId(id); + pick.setPickChildList(pickChildList); + return pick; + } + + @Override + public T selectById(String id) { + T pick = super.selectById(id); + // 仓库 + erpDepotService.setDataMation(pick.getPickChildList(), PickChild::getDepotId); + // 加工单 + machinService.setDataMation(pick, T::getFromId); + + // 获取产品/规格信息 + materialService.setDataMation(pick.getPickChildList(), PickChild::getMaterialId); + materialNormsService.setDataMation(pick.getPickChildList(), PickChild::getNormsId); + + // 部门 + iDepmentService.setDataMation(pick, T::getDepartmentId); + // 车间 + farmService.setDataMation(pick, T::getFarmId); + return pick; + } + + @Override + public void deletePostpose(String id) { + // 删除子单据信息 + pickChildService.deleteByParentId(id); + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List entityList = list(queryWrapper); + Map entityMap = entityList.stream().collect(Collectors.toMap(Pick::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + T entity = entityMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + @Override + public void editOtherState(String id, Integer otherState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Pick::getOtherState), otherState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getIdKey), getServiceClassName()); + // 只查询审批通过的单据 + queryWrapper.eq(MybatisPlusUtil.toColumns(Pick::getState), FlowableStateEnum.PASS.getKey()); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(Pick::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List pickChildList = pickChildService.queryPickChildListByParentIds(ids); + Map collect = pickChildList.stream() + .collect(Collectors.groupingBy(PickChild::getNormsId, Collectors.summingInt(PickChild::getNeedNum))); + return collect; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchMaterialServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchMaterialServiceImpl.java new file mode 100644 index 0000000..8c777a7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchMaterialServiceImpl.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.pick.classenum.OutLetState; +import com.skyeye.pick.classenum.PatchOutLetFromType; +import com.skyeye.pick.dao.PatchMaterialDao; +import com.skyeye.pick.entity.PatchMaterial; +import com.skyeye.pick.entity.PatchOutLet; +import com.skyeye.pick.service.PatchMaterialService; +import com.skyeye.pick.service.PatchOutLetService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PatchMaterialServiceImpl + * @Description: 补料申请单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "补料单", groupName = "物料单", flowable = true) +public class PatchMaterialServiceImpl extends ErpPickServiceImpl implements PatchMaterialService { + + @Autowired + private PatchOutLetService patchOutLetService; + + @Override + public void createPrepose(PatchMaterial entity) { + super.createPrepose(entity); + entity.setOtherState(OutLetState.NEED_OUTLET.getKey()); + } + + @Override + public void queryPatchMaterialTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PatchMaterial patchMaterial = selectById(id); + // 该补料单下的已经下达补料出库单(审核通过)的数量 + Map executeNum = patchOutLetService.calcMaterialNormsNumByFromId(patchMaterial.getId()); + // 设置未下达商品数量-----补料单数量 - 补料出库单数量 + patchMaterial.getPickChildList().forEach(pickChild -> { + // 补料单数量 - 已经下达补料出库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), executeNum); + pickChild.setNeedNum(surplusNum); + }); + // 过滤掉数量为0的商品信息 + patchMaterial.setPickChildList(patchMaterial.getPickChildList().stream() + .filter(erpOrderItem -> erpOrderItem.getNeedNum() > 0).collect(Collectors.toList())); + outputObject.setBean(patchMaterial); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertPatchMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + PatchOutLet patchOutLet = inputObject.getParams(PatchOutLet.class); + // 获取补料单状态 + PatchMaterial patchMaterial = selectById(patchOutLet.getId()); + if (ObjectUtil.isEmpty(patchMaterial)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到补料出库单 + if (FlowableStateEnum.PASS.getKey().equals(patchMaterial.getState()) && + (patchMaterial.getOtherState() == OutLetState.NEED_OUTLET.getKey() + || patchMaterial.getOtherState() == OutLetState.PARTIAL_OUTLET.getKey())) { + String userId = inputObject.getLogParams().get("id").toString(); + patchOutLet.setFromId(patchOutLet.getId()); + patchOutLet.setFromTypeId(PatchOutLetFromType.PATCH_OUT_LET.getKey()); + patchOutLet.setId(StrUtil.EMPTY); + patchOutLetService.createEntity(patchOutLet, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达补料出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchOutLetServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchOutLetServiceImpl.java new file mode 100644 index 0000000..3e309f0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PatchOutLetServiceImpl.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.OutLetState; +import com.skyeye.pick.classenum.PatchOutLetFromType; +import com.skyeye.pick.dao.PatchOutLetDao; +import com.skyeye.pick.entity.PatchMaterial; +import com.skyeye.pick.entity.PatchOutLet; +import com.skyeye.pick.entity.PickChild; +import com.skyeye.pick.service.PatchMaterialService; +import com.skyeye.pick.service.PatchOutLetService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PatchOutLetServiceImpl + * @Description: 补料出库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "补料出库单", groupName = "物料单", flowable = true) +public class PatchOutLetServiceImpl extends SkyeyeErpOrderServiceImpl implements PatchOutLetService { + + @Autowired + private PatchMaterialService patchMaterialService; + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private FarmService farmService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置补料需求单 + patchMaterialService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(PatchOutLet entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(PatchOutLet entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public PatchOutLet selectById(String id) { + PatchOutLet requisitionOutLet = super.selectById(id); + // 部门 + iDepmentService.setDataMation(requisitionOutLet, PatchOutLet::getDepartmentId); + // 车间 + farmService.setDataMation(requisitionOutLet, PatchOutLet::getFarmId); + + if (requisitionOutLet.getFromTypeId() == PatchOutLetFromType.PATCH_OUT_LET.getKey()) { + // 补料需求单 + patchMaterialService.setDataMation(requisitionOutLet, PatchOutLet::getFromId); + } + + return requisitionOutLet; + } + + private void checkMaterialNorms(PatchOutLet entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前补料出库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达补料出库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == PatchOutLetFromType.PATCH_OUT_LET.getKey()) { + // 补料需求单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(PatchOutLet entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + PatchMaterial patchMaterial = patchMaterialService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(patchMaterial.getPickChildList())) { + throw new CustomException("该补料单下未包含商品."); + } + List fromNormsIds = patchMaterial.getPickChildList().stream() + .map(PickChild::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + + patchMaterial.getPickChildList().forEach(pickChild -> { + // 补料需求单数量 - 当前单据数量 - 已经下达补料出库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), orderNormsNum, executeNum); + if (setData) { + pickChild.setNeedNum(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List pickChildList = patchMaterial.getPickChildList().stream() + .filter(pickChild -> pickChild.getNeedNum() > 0).collect(Collectors.toList()); + // 如果该补料需求单的商品已经全部生成了补料出库单,那说明已经完成 + if (CollectionUtil.isEmpty(pickChildList)) { + patchMaterialService.editOtherState(patchMaterial.getId(), OutLetState.COMPLATE_OUTLET.getKey()); + } else { + patchMaterialService.editOtherState(patchMaterial.getId(), OutLetState.PARTIAL_OUTLET.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(PatchOutLet entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void queryPatchOutLetTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PatchOutLet patchOutLet = selectById(id); + // 该补料出库单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(patchOutLet.getId()); + // 设置未下达商品数量-----补料出库单数量 - 已出库数量 + super.setOrCheckOperNumber(patchOutLet.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + patchOutLet.setErpOrderItemList(patchOutLet.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(patchOutLet); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPatchOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取补料出库单状态 + PatchOutLet patchOutLet = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(patchOutLet)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(patchOutLet.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.PATCH_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PickChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PickChildServiceImpl.java new file mode 100644 index 0000000..360f641 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/PickChildServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.pick.dao.PickChildDao; +import com.skyeye.pick.entity.PickChild; +import com.skyeye.pick.service.PickChildService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: PickChildServiceImpl + * @Description: 物料单子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/30 9:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "物料单子单据", groupName = "物料单子单据", manageShow = false) +public class PickChildServiceImpl extends SkyeyeBusinessServiceImpl implements PickChildService { + + @Override + public void deleteByParentId(String pickId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PickChild::getParentId), pickId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String pickId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PickChild::getParentId), pickId); + List pickChildList = list(queryWrapper); + return pickChildList; + } + + @Override + public void saveList(String pickId, List pickChildList, String userId) { + deleteByParentId(pickId); + if (CollectionUtil.isNotEmpty(pickChildList)) { + for (PickChild pickChild : pickChildList) { + pickChild.setParentId(pickId); + } + createEntity(pickChildList, userId); + } + } + + @Override + public List queryPickChildListByParentIds(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(PickChild::getParentId), ids); + return list(queryWrapper); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionMaterialServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionMaterialServiceImpl.java new file mode 100644 index 0000000..ad0ee1c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionMaterialServiceImpl.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.machin.classenum.MachinPickStateEnum; +import com.skyeye.machin.service.MachinService; +import com.skyeye.pick.classenum.OutLetState; +import com.skyeye.pick.classenum.RequisitionOutLetFromType; +import com.skyeye.pick.dao.RequisitionMaterialDao; +import com.skyeye.pick.entity.RequisitionMaterial; +import com.skyeye.pick.entity.RequisitionOutLet; +import com.skyeye.pick.service.RequisitionMaterialService; +import com.skyeye.pick.service.RequisitionOutLetService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: RequisitionMaterialServiceImpl + * @Description: 领料申请单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/27 12:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "领料单", groupName = "物料单", flowable = true) +public class RequisitionMaterialServiceImpl extends ErpPickServiceImpl implements RequisitionMaterialService { + + @Autowired + private MachinService machinService; + + @Autowired + private RequisitionOutLetService requisitionOutLetService; + + @Override + public void createPrepose(RequisitionMaterial entity) { + super.createPrepose(entity); + entity.setOtherState(OutLetState.NEED_OUTLET.getKey()); + } + + @Override + public void approvalEndIsSuccess(RequisitionMaterial entity) { + if (StrUtil.isNotEmpty(entity.getFromId())) { + machinService.editPickStateById(entity.getFromId(), MachinPickStateEnum.PICKED.getKey()); + } + } + + @Override + public void queryRequisitionMaterialTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + RequisitionMaterial requisitionMaterial = selectById(id); + // 该领料单下的已经下达领料出库单(审核通过)的数量 + Map executeNum = requisitionOutLetService.calcMaterialNormsNumByFromId(requisitionMaterial.getId()); + // 设置未下达商品数量-----领料单数量 - 领料出库单数量 + requisitionMaterial.getPickChildList().forEach(pickChild -> { + // 领料单数量 - 已经下达领料出库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), executeNum); + pickChild.setNeedNum(surplusNum); + }); + // 过滤掉数量为0的商品信息 + requisitionMaterial.setPickChildList(requisitionMaterial.getPickChildList().stream() + .filter(erpOrderItem -> erpOrderItem.getNeedNum() > 0).collect(Collectors.toList())); + outputObject.setBean(requisitionMaterial); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertRequisitionMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + RequisitionOutLet requisitionOutLet = inputObject.getParams(RequisitionOutLet.class); + // 获取领料单状态 + RequisitionMaterial requisitionMaterial = selectById(requisitionOutLet.getId()); + if (ObjectUtil.isEmpty(requisitionMaterial)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到领料出库单 + if (FlowableStateEnum.PASS.getKey().equals(requisitionMaterial.getState()) && + (requisitionMaterial.getOtherState() == OutLetState.NEED_OUTLET.getKey() + || requisitionMaterial.getOtherState() == OutLetState.PARTIAL_OUTLET.getKey())) { + String userId = inputObject.getLogParams().get("id").toString(); + requisitionOutLet.setFromId(requisitionOutLet.getId()); + requisitionOutLet.setFromTypeId(RequisitionOutLetFromType.REQUISITION_MATERIAL.getKey()); + requisitionOutLet.setId(StrUtil.EMPTY); + requisitionOutLetService.createEntity(requisitionOutLet, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达领料出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionOutLetServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionOutLetServiceImpl.java new file mode 100644 index 0000000..fa3c3aa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/RequisitionOutLetServiceImpl.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.OutLetState; +import com.skyeye.pick.classenum.RequisitionOutLetFromType; +import com.skyeye.pick.dao.RequisitionOutLetDao; +import com.skyeye.pick.entity.PickChild; +import com.skyeye.pick.entity.RequisitionMaterial; +import com.skyeye.pick.entity.RequisitionOutLet; +import com.skyeye.pick.service.RequisitionMaterialService; +import com.skyeye.pick.service.RequisitionOutLetService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: RequisitionOutLetServiceImpl + * @Description: 领料出库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "领料出库单", groupName = "物料单", flowable = true) +public class RequisitionOutLetServiceImpl extends SkyeyeErpOrderServiceImpl implements RequisitionOutLetService { + + @Autowired + private RequisitionMaterialService requisitionMaterialService; + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private FarmService farmService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置领料需求单 + requisitionMaterialService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(RequisitionOutLet entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(RequisitionOutLet entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public RequisitionOutLet selectById(String id) { + RequisitionOutLet requisitionOutLet = super.selectById(id); + // 部门 + iDepmentService.setDataMation(requisitionOutLet, RequisitionOutLet::getDepartmentId); + // 车间 + farmService.setDataMation(requisitionOutLet, RequisitionOutLet::getFarmId); + if (requisitionOutLet.getFromTypeId() == RequisitionOutLetFromType.REQUISITION_MATERIAL.getKey()) { + // 领料需求单 + requisitionMaterialService.setDataMation(requisitionOutLet, RequisitionOutLet::getFromId); + } + return requisitionOutLet; + } + + private void checkMaterialNorms(RequisitionOutLet entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前领料出库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达领料出库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == RequisitionOutLetFromType.REQUISITION_MATERIAL.getKey()) { + // 领料需求单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(RequisitionOutLet entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + RequisitionMaterial requisitionMaterial = requisitionMaterialService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(requisitionMaterial.getPickChildList())) { + throw new CustomException("该领料单下未包含商品."); + } + List fromNormsIds = requisitionMaterial.getPickChildList().stream() + .map(PickChild::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + + requisitionMaterial.getPickChildList().forEach(pickChild -> { + // 领料需求单数量 - 当前单据数量 - 已经下达领料出库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), orderNormsNum, executeNum); + if (setData) { + pickChild.setNeedNum(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List pickChildList = requisitionMaterial.getPickChildList().stream() + .filter(pickChild -> pickChild.getNeedNum() > 0).collect(Collectors.toList()); + // 如果该领料需求单的商品已经全部生成了领料出库单,那说明已经完成 + if (CollectionUtil.isEmpty(pickChildList)) { + requisitionMaterialService.editOtherState(requisitionMaterial.getId(), OutLetState.COMPLATE_OUTLET.getKey()); + } else { + requisitionMaterialService.editOtherState(requisitionMaterial.getId(), OutLetState.PARTIAL_OUTLET.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(RequisitionOutLet entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void queryRequisitionOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + RequisitionOutLet requisitionOutLet = selectById(id); + // 该领料出库单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(requisitionOutLet.getId()); + // 设置未下达商品数量-----领料出库单数量 - 已出库数量 + super.setOrCheckOperNumber(requisitionOutLet.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + requisitionOutLet.setErpOrderItemList(requisitionOutLet.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(requisitionOutLet); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertRequisitionOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取领料出库单状态 + RequisitionOutLet requisitionOutLet = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(requisitionOutLet)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(requisitionOutLet.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.REQUISITION_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnMaterialServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnMaterialServiceImpl.java new file mode 100644 index 0000000..06d0af3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnMaterialServiceImpl.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.pick.classenum.PutState; +import com.skyeye.pick.classenum.ReturnPutFromType; +import com.skyeye.pick.dao.ReturnMaterialDao; +import com.skyeye.pick.entity.ReturnMaterial; +import com.skyeye.pick.entity.ReturnPut; +import com.skyeye.pick.service.ReturnMaterialService; +import com.skyeye.pick.service.ReturnPutService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReturnMaterialServiceImpl + * @Description: 退料申请单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/20 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "退料单", groupName = "物料单", flowable = true) +public class ReturnMaterialServiceImpl extends ErpPickServiceImpl implements ReturnMaterialService { + + @Autowired + private ReturnPutService returnPutService; + + @Override + public void createPrepose(ReturnMaterial entity) { + super.createPrepose(entity); + entity.setOtherState(PutState.NEED_PUT.getKey()); + } + + @Override + public void queryReturnMaterialTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ReturnMaterial returnMaterial = selectById(id); + // 该退料单下的已经下达退料入库单(审核通过)的数量 + Map executeNum = returnPutService.calcMaterialNormsNumByFromId(returnMaterial.getId()); + // 设置未下达商品数量-----退料单数量 - 退料入库单数量 + returnMaterial.getPickChildList().forEach(pickChild -> { + // 退料单数量 - 已经下达退料入库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), executeNum); + pickChild.setNeedNum(surplusNum); + }); + // 过滤掉数量为0的商品信息 + returnMaterial.setPickChildList(returnMaterial.getPickChildList().stream() + .filter(erpOrderItem -> erpOrderItem.getNeedNum() > 0).collect(Collectors.toList())); + outputObject.setBean(returnMaterial); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertReturnMaterialToTurnOut(InputObject inputObject, OutputObject outputObject) { + ReturnPut returnPut = inputObject.getParams(ReturnPut.class); + // 获取退料单状态 + ReturnMaterial returnMaterial = selectById(returnPut.getId()); + if (ObjectUtil.isEmpty(returnMaterial)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到退料入库单 + if (FlowableStateEnum.PASS.getKey().equals(returnMaterial.getState()) && + (returnMaterial.getOtherState() == PutState.NEED_PUT.getKey() + || returnMaterial.getOtherState() == PutState.PARTIAL_PUT.getKey())) { + String userId = inputObject.getLogParams().get("id").toString(); + returnPut.setFromId(returnPut.getId()); + returnPut.setFromTypeId(ReturnPutFromType.RETURN_PUT.getKey()); + returnPut.setId(StrUtil.EMPTY); + returnPutService.createEntity(returnPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达退料入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnPutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnPutServiceImpl.java new file mode 100644 index 0000000..c3474ff --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pick/service/impl/ReturnPutServiceImpl.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pick.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.machinprocedure.classenum.MachinProcedureAcceptChildType; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.OutLetState; +import com.skyeye.pick.classenum.PickNormsCodeUseState; +import com.skyeye.pick.classenum.ReturnPutFromType; +import com.skyeye.pick.dao.ReturnPutDao; +import com.skyeye.pick.entity.PickChild; +import com.skyeye.pick.entity.ReturnMaterial; +import com.skyeye.pick.entity.ReturnPut; +import com.skyeye.pick.service.DepartmentStockService; +import com.skyeye.pick.service.ReturnMaterialService; +import com.skyeye.pick.service.ReturnPutService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReturnPutServiceImpl + * @Description: 退料入库单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/26 21:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "退料入库单", groupName = "物料单", flowable = true) +public class ReturnPutServiceImpl extends SkyeyeErpOrderServiceImpl implements ReturnPutService { + + @Autowired + private ReturnMaterialService returnMaterialService; + + @Autowired + private DepartmentStockService departmentStockService; + + @Autowired + private DepotPutService depotPutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private FarmService farmService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置退料需求单 + returnMaterialService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(ReturnPut entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + checkMaterialNorms(entity, false); + checkNormsCodeAndSave(entity, true); + } + + @Override + public void createPrepose(ReturnPut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ReturnPut entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ReturnPut getDataFromDb(String id) { + ReturnPut returnPut = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(returnPut); + return returnPut; + } + + @Override + public ReturnPut selectById(String id) { + ReturnPut returnPut = super.selectById(id); + // 部门 + iDepmentService.setDataMation(returnPut, ReturnPut::getDepartmentId); + // 车间 + farmService.setDataMation(returnPut, ReturnPut::getFarmId); + if (returnPut.getFromTypeId() == ReturnPutFromType.RETURN_PUT.getKey()) { + // 退料需求单 + returnMaterialService.setDataMation(returnPut, ReturnPut::getFromId); + } + return returnPut; + } + + private void checkMaterialNorms(ReturnPut entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前退料入库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达退料入库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ReturnPutFromType.RETURN_PUT.getKey()) { + // 退料需求单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(ReturnPut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + ReturnMaterial returnMaterial = returnMaterialService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(returnMaterial.getPickChildList())) { + throw new CustomException("该退料单下未包含商品."); + } + List fromNormsIds = returnMaterial.getPickChildList().stream() + .map(PickChild::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + + returnMaterial.getPickChildList().forEach(pickChild -> { + // 退料需求单数量 - 当前单据数量 - 已经下达退料入库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(pickChild.getNeedNum(), pickChild.getNormsId(), orderNormsNum, executeNum); + if (setData) { + pickChild.setNeedNum(surplusNum); + } + }); + // 和当前部门/车间的库存做对比 + checkDepartStockWhetherOutstrip(entity.getDepartmentId(), entity.getFarmId(), entity.getErpOrderItemList()); + if (setData) { + // 过滤掉剩余数量为0的商品 + List pickChildList = returnMaterial.getPickChildList().stream() + .filter(pickChild -> pickChild.getNeedNum() > 0).collect(Collectors.toList()); + // 如果该退料需求单的商品已经全部生成了退料入库单,那说明已经完成 + if (CollectionUtil.isEmpty(pickChildList)) { + returnMaterialService.editOtherState(returnMaterial.getId(), OutLetState.COMPLATE_OUTLET.getKey()); + } else { + returnMaterialService.editOtherState(returnMaterial.getId(), OutLetState.PARTIAL_OUTLET.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(ReturnPut entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, false); + } + + private void checkDepartStockWhetherOutstrip(String departmentId, String farmId, List erpOrderItemList) { + List normsIds = erpOrderItemList.stream().map(ErpOrderItem::getNormsId).collect(Collectors.toList()); + Map normsDepartmentStock = departmentStockService.queryNormsDepartmentStock(departmentId, farmId, normsIds); + for (ErpOrderItem bean : erpOrderItemList) { + // 部门库存存量 + int departMentTock = normsDepartmentStock.get(bean.getNormsId()); + // 单据数量 小于 仓储数量 + if (departMentTock - bean.getOperNumber() < 0) { + throw new CustomException("单据储量小于仓储数量,请确认"); + } + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 从部门/车间的库存入库到仓库的库存 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndSave(ReturnPut entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和数据库中条形码的状态做对比 + // 1.1 从数据库查询出库状态的条形码信息, + // 1.2 只有部门信息不为空的说明没有退料,才可以进行退料。部门信息为空,说明该条形码还未进行领料 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getDepartmentId()) && StrUtil.equals(entity.getDepartmentId(), bean.getDepartmentId())) + .collect(Collectors.toList()); + // 1.3 如果车间不为空,则需要获取过滤出当前车间的库存 + if (StrUtil.isNotEmpty(entity.getFarmId())) { + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getFarmId()) && StrUtil.equals(entity.getFarmId(), bean.getFarmId())) + .collect(Collectors.toList()); + } + // 1.4 只有未使用/不是正常使用(入报废等)的可以退料 + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> bean.getPickUseState() == PickNormsCodeUseState.WAIT_USE.getKey() || + MachinProcedureAcceptChildType.NORMAL.getKey() != bean.getPickState()) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或不存在【部门/车间】仓库中或已被使用,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setDepartmentId(StrUtil.EMPTY); + materialNormsCode.setFarmId(StrUtil.EMPTY); + materialNormsCode.setPickUseState(null); + }); + materialNormsCodeService.updateEntityPick(materialNormsCodeList); + } + } + if (!onlyCheck) { + // 修改部门/车间的库存 + entity.getErpOrderItemList().forEach(erpOrderItem -> { + departmentStockService.updateDepartmentStock(entity.getDepartmentId(), entity.getFarmId(), erpOrderItem.getMaterialId(), + erpOrderItem.getNormsId(), erpOrderItem.getOperNumber(), DepotPutOutType.OUT.getKey()); + }); + } + return allNormsCodeList; + } + + @Override + public void queryReturnPutTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ReturnPut returnPut = selectById(id); + // 该退料入库单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(returnPut.getId()); + // 设置未下达商品数量-----退料入库单数量 - 已入库数量 + super.setOrCheckOperNumber(returnPut.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + returnPut.setErpOrderItemList(returnPut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(returnPut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertReturnPutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取退料入库单状态 + ReturnPut returnPut = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(returnPut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(returnPut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.RETURN_PUT.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/classenum/ConfirmFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/classenum/ConfirmFromType.java new file mode 100644 index 0000000..9353aa3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/classenum/ConfirmFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ConfirmFromType + * @Description: 物料接收单/物料退货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ConfirmFromType implements SkyeyeEnumClass { + + DEPOT_OUT(1, "仓库出库单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmPutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmPutController.java new file mode 100644 index 0000000..e817343 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmPutController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pickconfirm.entity.ConfirmPut; +import com.skyeye.pickconfirm.service.ConfirmPutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ConfirmPutController + * @Description: 物料接收单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "物料接收单", tags = "物料接收单", modelName = "物料确认") +public class ConfirmPutController { + + @Autowired + private ConfirmPutService confirmPutService; + + /** + * 获取物料接收单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryConfirmPutList", value = "获取物料接收单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ConfirmPutController/queryConfirmPutList") + public void queryConfirmPutList(InputObject inputObject, OutputObject outputObject) { + confirmPutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑物料接收单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeConfirmPut", value = "新增/编辑物料接收单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConfirmPut.class) + @RequestMapping("/post/ConfirmPutController/writeConfirmPut") + public void writeConfirmPut(InputObject inputObject, OutputObject outputObject) { + confirmPutService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmReturnController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmReturnController.java new file mode 100644 index 0000000..bfe18cc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/controller/ConfirmReturnController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.pickconfirm.entity.ConfirmReturn; +import com.skyeye.pickconfirm.service.ConfirmReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ConfirmReturnController + * @Description: 物料退货单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "物料退货单", tags = "物料退货单", modelName = "物料确认") +public class ConfirmReturnController { + + @Autowired + private ConfirmReturnService confirmReturnService; + + /** + * 获取物料退货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryConfirmReturnList", value = "获取物料退货单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ConfirmReturnController/queryConfirmReturnList") + public void queryConfirmReturnList(InputObject inputObject, OutputObject outputObject) { + confirmReturnService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑物料退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeConfirmReturn", value = "新增/编辑物料退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ConfirmReturn.class) + @RequestMapping("/post/ConfirmReturnController/writeConfirmReturn") + public void writeConfirmReturn(InputObject inputObject, OutputObject outputObject) { + confirmReturnService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询物料退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryConfirmReturnTransById", value = "转仓库入库单时,根据id查询物料退货信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConfirmReturnController/queryConfirmReturnTransById") + public void queryConfirmReturnTransById(InputObject inputObject, OutputObject outputObject) { + confirmReturnService.queryConfirmReturnTransById(inputObject, outputObject); + } + + /** + * 物料退货单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertConfirmReturnToTurnDepot", value = "物料退货单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ConfirmReturnController/insertConfirmReturnToTurnDepot") + public void insertConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject) { + confirmReturnService.insertConfirmReturnToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmPutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmPutDao.java new file mode 100644 index 0000000..e879abc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmPutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pickconfirm.entity.ConfirmPut; + +/** + * @ClassName: ConfirmPutDao + * @Description: 物料接收单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConfirmPutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmReturnDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmReturnDao.java new file mode 100644 index 0000000..c51ae5c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/dao/ConfirmReturnDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pickconfirm.entity.ConfirmReturn; + +/** + * @ClassName: ConfirmReturnDao + * @Description: 物料退货单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConfirmReturnDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmPut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmPut.java new file mode 100644 index 0000000..f368316 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmPut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ConfirmPut + * @Description: 物料接收单 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:confirmPut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("物料接收单实体类") +public class ConfirmPut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmReturn.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmReturn.java new file mode 100644 index 0000000..a10683a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/entity/ConfirmReturn.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ConfirmReturn + * @Description: 物料退货单 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:confirmReturn", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("物料退货单实体类") +public class ConfirmReturn extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmPutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmPutService.java new file mode 100644 index 0000000..3cd294b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmPutService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.pickconfirm.entity.ConfirmPut; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ConfirmPutService + * @Description: 物料接收单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConfirmPutService extends SkyeyeErpOrderService { + + Map> calcMaterialNormsCodeByFromId(String fromId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmReturnService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmReturnService.java new file mode 100644 index 0000000..8d76516 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/ConfirmReturnService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pickconfirm.entity.ConfirmReturn; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ConfirmReturnService + * @Description: 物料退货单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ConfirmReturnService extends SkyeyeErpOrderService { + + void queryConfirmReturnTransById(InputObject inputObject, OutputObject outputObject); + + void insertConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject); + + Map> calcMaterialNormsCodeByFromId(String fromId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmPutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmPutServiceImpl.java new file mode 100644 index 0000000..dece146 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmPutServiceImpl.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutOtherState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.ErpOrderItemCode; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pick.classenum.PickNormsCodeUseState; +import com.skyeye.pick.service.DepartmentStockService; +import com.skyeye.pickconfirm.classenum.ConfirmFromType; +import com.skyeye.pickconfirm.dao.ConfirmPutDao; +import com.skyeye.pickconfirm.entity.ConfirmPut; +import com.skyeye.pickconfirm.service.ConfirmPutService; +import com.skyeye.pickconfirm.service.ConfirmReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ConfirmPutServiceImpl + * @Description: 物料接收单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "物料接收单", groupName = "物料确认", flowable = true) +public class ConfirmPutServiceImpl extends SkyeyeErpOrderServiceImpl implements ConfirmPutService { + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private ConfirmReturnService confirmReturnService; + + @Autowired + private DepartmentStockService departmentStockService; + + @Autowired + private FarmService farmService; + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置仓库出库单 + depotOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 车间 + farmService.setMationForMap(beans, "farmId", "farmMation"); + // 部门 + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + return beans; + } + + @Override + public void validatorEntity(ConfirmPut entity) { + if (StrUtil.isNotEmpty(entity.getId())) { + ConfirmPut confirmPut = selectById(entity.getId()); + entity.setFromId(confirmPut.getFromId()); + entity.setFromTypeId(confirmPut.getFromTypeId()); + entity.setFarmId(confirmPut.getFarmId()); + entity.setDepartmentId(confirmPut.getDepartmentId()); + entity.setSalesman(confirmPut.getSalesman()); + } + checkMaterialNorms(entity, false); + checkNormsCodeAndSave(entity, true); + } + + @Override + public void createPrepose(ConfirmPut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ConfirmPut entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ConfirmPut getDataFromDb(String id) { + ConfirmPut confirmPut = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(confirmPut); + return confirmPut; + } + + @Override + public ConfirmPut selectById(String id) { + ConfirmPut confirmPut = super.selectById(id); + if (confirmPut.getFromTypeId() == ConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + depotOutService.setDataMation(confirmPut, ConfirmPut::getFromId); + } + // 车间 + farmService.setDataMation(confirmPut, ConfirmPut::getFarmId); + // 部门 + iDepmentService.setDataMation(confirmPut, ConfirmPut::getDepartmentId); + return confirmPut; + } + + private void checkMaterialNorms(ConfirmPut entity, boolean setData) { + // 当前物料接收单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达物料接收单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(ConfirmPut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(depotOut.getErpOrderItemList())) { + throw new CustomException("该仓库出库单下未包含商品."); + } + super.checkFromOrderMaterialNorms(depotOut.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达物料退货单的商品信息 + Map returnExecuteNum = confirmReturnService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 仓库出库单数量 - 当前单据数量 - 已经下达物料接收单的数量 - 已经下达物料退货单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), setData, orderNormsNum, executeNum, returnExecuteNum); + + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } else { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(ConfirmPut entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, false); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 接收需要入库到对应的车间/部门的仓库下 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndSave(ConfirmPut entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和来源单据的条形码作对比 + // 获取来源单据中的条形码的信息 + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + List inFromOrderNormsCodeList = depotOut.getErpOrderItemList().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(norms -> norms.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在来源单据中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inFromOrderNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在来源出库单中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和数据库中条形码的状态做对比 + // 2.1 从数据库查询出库状态的条形码信息, + // 2.2 只有部门信息为空的说明没有领料,才可以进行物料接收。部门信息不为空,说明该条形码已经在部门/车间的库存里 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream().filter(bean -> StrUtil.isEmpty(bean.getDepartmentId())) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/已经存在其他仓库中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setDepartmentId(entity.getDepartmentId()); + materialNormsCode.setFarmId(entity.getFarmId()); + materialNormsCode.setPickUseState(PickNormsCodeUseState.WAIT_USE.getKey()); + materialNormsCode.setPickState(null); + }); + materialNormsCodeService.updateEntityPick(materialNormsCodeList); + } + } + if (!onlyCheck) { + // 修改部门/车间的库存 + entity.getErpOrderItemList().forEach(erpOrderItem -> { + departmentStockService.updateDepartmentStock(entity.getDepartmentId(), entity.getFarmId(), erpOrderItem.getMaterialId(), + erpOrderItem.getNormsId(), erpOrderItem.getOperNumber(), DepotPutOutType.PUT.getKey()); + }); + } + return allNormsCodeList; + } + + @Override + public Map> calcMaterialNormsCodeByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConfirmPut::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConfirmPut::getIdKey), getServiceClassName()); + // 只查询审批通过,部分出入库,已完成的单据 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ConfirmPut::getState), stateList); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(ConfirmPut::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + // 查询单据子表关联的条形码编号信息 + List erpOrderItemCodeList = erpOrderItemCodeService.selectByParentId(ids.toArray(new String[]{})); + Map> listMap = erpOrderItemCodeList.stream().collect(Collectors.groupingBy(ErpOrderItemCode::getNormsId)); + erpOrderItemList.forEach(erpOrderItem -> { + List erpOrderItemCodes = listMap.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isNotEmpty(erpOrderItemCodes)) { + List normsCodeList = erpOrderItemCodes.stream().map(ErpOrderItemCode::getNormsCode).collect(Collectors.toList()); + erpOrderItem.setNormsCodeList(normsCodeList); + erpOrderItem.setNormsCode(Joiner.on("\n").join(normsCodeList)); + } + }); + Map> collect = erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.mapping(ErpOrderItem::getNormsCodeList, + Collectors.reducing( + new ArrayList<>(), + Function.identity(), + (l1, l2) -> { + if (CollectionUtil.isNotEmpty(l2)) { + l1.addAll(l2); + } + return l1; + } + )))); + return collect; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmReturnServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmReturnServiceImpl.java new file mode 100644 index 0000000..ce6111f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/pickconfirm/service/impl/ConfirmReturnServiceImpl.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pickconfirm.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutOtherState; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.ErpOrderItemCode; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.pickconfirm.classenum.ConfirmFromType; +import com.skyeye.pickconfirm.dao.ConfirmReturnDao; +import com.skyeye.pickconfirm.entity.ConfirmReturn; +import com.skyeye.pickconfirm.service.ConfirmPutService; +import com.skyeye.pickconfirm.service.ConfirmReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ConfirmReturnServiceImpl + * @Description: 物料退货单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "物料退货单", groupName = "物料确认", flowable = true) +public class ConfirmReturnServiceImpl extends SkyeyeErpOrderServiceImpl implements ConfirmReturnService { + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private ConfirmPutService confirmPutService; + + @Autowired + private DepotPutService depotPutService; + + @Autowired + private FarmService farmService; + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置仓库出库单 + depotOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 车间 + farmService.setMationForMap(beans, "farmId", "farmMation"); + // 部门 + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + return beans; + } + + @Override + public void validatorEntity(ConfirmReturn entity) { + if (StrUtil.isNotEmpty(entity.getId())) { + ConfirmReturn confirmReturn = selectById(entity.getId()); + entity.setFromId(confirmReturn.getFromId()); + entity.setFromTypeId(confirmReturn.getFromTypeId()); + entity.setFarmId(confirmReturn.getFarmId()); + entity.setDepartmentId(confirmReturn.getDepartmentId()); + entity.setSalesman(confirmReturn.getSalesman()); + } + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + checkMaterialNorms(entity, false); + checkNormsCodeAndSave(entity); + } + + @Override + public void createPrepose(ConfirmReturn entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ConfirmReturn entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ConfirmReturn getDataFromDb(String id) { + ConfirmReturn confirmReturn = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(confirmReturn); + return confirmReturn; + } + + @Override + public ConfirmReturn selectById(String id) { + ConfirmReturn confirmReturn = super.selectById(id); + if (confirmReturn.getFromTypeId() == ConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + depotOutService.setDataMation(confirmReturn, ConfirmReturn::getFromId); + } + // 车间 + farmService.setDataMation(confirmReturn, ConfirmReturn::getFarmId); + // 部门 + iDepmentService.setDataMation(confirmReturn, ConfirmReturn::getDepartmentId); + return confirmReturn; + } + + private void checkMaterialNorms(ConfirmReturn entity, boolean setData) { + // 当前物料退货单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达物料退货单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(ConfirmReturn entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(depotOut.getErpOrderItemList())) { + throw new CustomException("该仓库出库单下未包含商品."); + } + super.checkFromOrderMaterialNorms(depotOut.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达物料接收单的商品信息 + Map putExecuteNum = confirmPutService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 仓库出库单数量 - 当前单据数量 - 已经下达物料退货单的数量 - 已经下达物料接收单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), setData, orderNormsNum, executeNum, putExecuteNum); + + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } else { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(ConfirmReturn entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * + * @param entity + */ + protected List checkNormsCodeAndSave(ConfirmReturn entity) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和来源单据的条形码作对比 + // 获取来源单据中的条形码的信息 + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + List inFromOrderNormsCodeList = depotOut.getErpOrderItemList().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(norms -> norms.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在来源单据中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inFromOrderNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在来源出库单中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和数据库中条形码的状态做对比 + // 2.1 从数据库查询出库状态的条形码信息, + // 2.2 只有部门信息为空的说明没有领料,才可以进行退货。部门信息不为空,说明该条形码已经在部门/车间的库存里 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream().filter(bean -> StrUtil.isEmpty(bean.getDepartmentId())) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/已经存在其他仓库中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + } + return allNormsCodeList; + } + + @Override + public void queryConfirmReturnTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ConfirmReturn confirmReturn = selectById(id); + // 该物料退货单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(confirmReturn.getId()); + // 设置未下达商品数量-----物料退货单数量 - 已入库数量 + super.setOrCheckOperNumber(confirmReturn.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + confirmReturn.setErpOrderItemList(confirmReturn.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(confirmReturn); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取物料退货单状态 + ConfirmReturn confirmReturn = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(confirmReturn)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(confirmReturn.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.CONFIRM_RETURN.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } + + @Override + public Map> calcMaterialNormsCodeByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConfirmReturn::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ConfirmReturn::getIdKey), getServiceClassName()); + // 只查询审批通过,部分出入库,已完成的单据 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ConfirmReturn::getState), stateList); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(ConfirmReturn::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + // 查询单据子表关联的条形码编号信息 + List erpOrderItemCodeList = erpOrderItemCodeService.selectByParentId(ids.toArray(new String[]{})); + Map> listMap = erpOrderItemCodeList.stream().collect(Collectors.groupingBy(ErpOrderItemCode::getNormsId)); + erpOrderItemList.forEach(erpOrderItem -> { + List erpOrderItemCodes = listMap.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isNotEmpty(erpOrderItemCodes)) { + List normsCodeList = erpOrderItemCodes.stream().map(ErpOrderItemCode::getNormsCode).collect(Collectors.toList()); + erpOrderItem.setNormsCodeList(normsCodeList); + erpOrderItem.setNormsCode(Joiner.on("\n").join(normsCodeList)); + } + }); + Map> collect = erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.mapping(ErpOrderItem::getNormsCodeList, + Collectors.reducing( + new ArrayList<>(), + Function.identity(), + (l1, l2) -> { + if (CollectionUtil.isNotEmpty(l2)) { + l1.addAll(l2); + } + return l1; + } + )))); + return collect; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/classenum/ProcedureCapacitySubject.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/classenum/ProcedureCapacitySubject.java new file mode 100644 index 0000000..0d79f4c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/classenum/ProcedureCapacitySubject.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ProcedureCapacitySubject + * @Description: 工序产能主体枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/17 22:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProcedureCapacitySubject implements SkyeyeEnumClass { + + EQUIPMENT(1, "设备", true, true), + PERSONNEL(2, "人员", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer state) { + for (ProcedureCapacitySubject bean : ProcedureCapacitySubject.values()) { + if (state == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WayProcedureController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WayProcedureController.java new file mode 100644 index 0000000..2ccd25b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WayProcedureController.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.procedure.entity.WayProcedure; +import com.skyeye.procedure.service.WayProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WayProcedureController + * @Description: 工艺路线管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/24 22:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工艺路线管理", tags = "工艺路线管理", modelName = "工艺路线管理") +public class WayProcedureController { + + @Autowired + private WayProcedureService wayProcedureService; + + /** + * 查询工艺列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpwayprocedure001", value = "查询工艺列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WayProcedureController/queryWayProcedureList") + public void queryWayProcedureList(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑工艺信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWayProcedure", value = "新增/编辑工艺信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WayProcedure.class) + @RequestMapping("/post/WayProcedureController/writeWayProcedure") + public void writeWayProcedure(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除工艺 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWayProcedureById", value = "删除工艺", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WayProcedureController/deleteWayProcedureById") + public void deleteWayProcedureById(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.deleteById(inputObject, outputObject); + } + + /** + * 获取工艺下的工序列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProcedureListByWayId", value = "获取工艺下的工序列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "工艺id", required = "required")}) + @RequestMapping("/post/WayProcedureController/queryProcedureListByWayId") + public void queryProcedureListByWayId(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.queryProcedureListByWayId(inputObject, outputObject); + } + + /** + * 根据id发布工艺路线 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "publishProcedureVersionById", value = "根据id发布工艺路线", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "工艺路线id", required = "required")}) + @RequestMapping("/post/WayProcedureController/publishProcedureVersionById") + public void publishProcedureVersionById(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.publishVersionById(inputObject, outputObject); + } + + /** + * 获取所有工艺列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllPublishProcedureList", value = "获取所有工艺列表", method = "GET", allUse = "2") + @RequestMapping("/post/WayProcedureController/queryAllPublishProcedureList") + public void queryAllPublishProcedureList(InputObject inputObject, OutputObject outputObject) { + wayProcedureService.queryAllPublishProcedureList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WorkProcedureController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WorkProcedureController.java new file mode 100644 index 0000000..bfa5743 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/controller/WorkProcedureController.java @@ -0,0 +1,101 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.procedure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.procedure.entity.WorkProcedure; +import com.skyeye.procedure.service.WorkProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WorkProcedureController + * @Description: 工序管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/23 21:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工序管理", tags = "工序管理", modelName = "工序管理") +public class WorkProcedureController { + + @Autowired + private WorkProcedureService workProcedureService; + + /** + * 查询工序列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpworkprocedure001", value = "查询工序列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WorkProcedureController/queryWorkProcedureList") + public void queryWorkProcedureList(InputObject inputObject, OutputObject outputObject) { + workProcedureService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑工序信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWorkProcedure", value = "新增/编辑工序信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WorkProcedure.class) + @RequestMapping("/post/WorkProcedureController/writeWorkProcedure") + public void writeWorkProcedure(InputObject inputObject, OutputObject outputObject) { + workProcedureService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除工序信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWorkProcedureById", value = "删除工作流配置", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WorkProcedureController/deleteWorkProcedureById") + public void deleteWorkProcedureById(InputObject inputObject, OutputObject outputObject) { + workProcedureService.deleteById(inputObject, outputObject); + } + + /** + * 查询所有工序列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpworkprocedure009", value = "查询所有工序列表信息", method = "GET", allUse = "2") + @RequestMapping("/post/WorkProcedureController/queryAllWorkProcedureList") + public void queryAllWorkProcedureList(InputObject inputObject, OutputObject outputObject) { + workProcedureService.queryAllWorkProcedureList(inputObject, outputObject); + } + + /** + * 根据工序id查询可以执行该工序的车间 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryExecuteFarmByWorkProcedureId", value = "根据工序id查询可以执行该工序的车间", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "workProcedureId", name = "workProcedureId", value = "工序id", required = "required")}) + @RequestMapping("/post/WorkProcedureController/queryExecuteFarmByWorkProcedureId") + public void queryExecuteFarmByWorkProcedureId(InputObject inputObject, OutputObject outputObject) { + workProcedureService.queryExecuteFarmByWorkProcedureId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureChildDao.java new file mode 100644 index 0000000..7bdbc0b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureChildDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.procedure.entity.WayProcedureChild; + +/** + * @ClassName: WayProcedureChildDao + * @Description: 工艺路线关联的工序数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/26 20:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WayProcedureChildDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureDao.java new file mode 100644 index 0000000..44141e2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WayProcedureDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.procedure.entity.WayProcedure; + +/** + * @ClassName: ErpWayProcedureDao + * @Description: 工艺路线管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WayProcedureDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureDao.java new file mode 100644 index 0000000..78d9ca1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureDao.java @@ -0,0 +1,20 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.procedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.procedure.entity.WorkProcedure; + +/** + * @ClassName: WorkProcedureDao + * @Description: 工序管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WorkProcedureDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureEquipmentDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureEquipmentDao.java new file mode 100644 index 0000000..4cfd3ec --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/dao/WorkProcedureEquipmentDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.procedure.entity.WorkProcedureEquipment; + +/** + * @ClassName: WorkProcedureEquipmentDao + * @Description: 工序下的设备清单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/18 8:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WorkProcedureEquipmentDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedure.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedure.java new file mode 100644 index 0000000..8450c45 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedure.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.Version; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: WayProcedure + * @Description: 工艺路线实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/24 13:05 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_WAY_PROCEDURE_CACHE_KEY) +@TableName(value = "erp_way_procedure") +@ApiModel("工艺路线信息实体类") +public class WayProcedure extends Version { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + + @TableField(value = "number") + @ApiModelProperty(value = "工艺编号", required = "required", fuzzyLike = true) + private String number; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "all_price") + @Property(value = "工艺总价") + private String allPrice; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @ApiModelProperty(value = "关联的工序信息", required = "required,json") + private List workProcedureList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedureChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedureChild.java new file mode 100644 index 0000000..bb6b8f4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WayProcedureChild.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.machinprocedure.entity.MachinProcedure; +import lombok.Data; + +/** + * @ClassName: WayProcedureChild + * @Description: 工艺路线关联的工序实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/24 13:05 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_WAY_PROCEDURE_CACHE_KEY) +@TableName(value = "erp_way_procedure_child") +@ApiModel("工艺路线关联的工序实体类") +public class WayProcedureChild extends CommonInfo { + + @TableId("id") + private String id; + + @TableField(exist = false) + @Property(value = "新的id") + private String newId; + + @TableField(value = "way_id") + @Property(value = "工艺id") + private String wayId; + + @TableField(value = "procedure_id") + @ApiModelProperty(value = "工序id", required = "required") + private String procedureId; + + @TableField(exist = false) + @Property(value = "工序信息") + private WorkProcedure procedureMation; + + @TableField(value = "order_by") + @ApiModelProperty(value = "工序排序 值越大越往后", required = "required,num") + private Integer orderBy; + + @TableField(value = "price") + @ApiModelProperty(value = "单价", required = "required,double", defaultValue = "0") + private String price; + + @TableField(value = "quota_capacity") + @ApiModelProperty(value = "定额能力", required = "required,num") + private Integer quotaCapacity; + + @TableField(value = "homework_ability") + @ApiModelProperty(value = "作业人数", required = "required,num") + private Integer homeworkAbility; + + @TableField(exist = false) + @Property(value = "加工单子单据关联的工序信息----加工单特有") + private MachinProcedure machinProcedureMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedure.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedure.java new file mode 100644 index 0000000..2fb5363 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedure.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WorkProcedure + * @Description: 工序信息 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/23 21:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_PROCEDURE_CACHE_KEY) +@TableName(value = "erp_work_procedure", autoResultMap = true) +@ApiModel("工序信息实体类") +public class WorkProcedure extends BaseGeneralInfo { + + @TableField(value = "number") + @ApiModelProperty(value = "工序编号", required = "required") + private String number; + + @TableField(value = "content") + @ApiModelProperty(value = "工序内容") + private String content; + + @TableField(value = "type_id") + @ApiModelProperty(value = "工序类别id,数据字典", required = "required") + private String typeId; + + @TableField(value = "charge_id") + @ApiModelProperty(value = "负责人id") + private String chargeId; + + @TableField(exist = false) + @Property(value = "负责人信息") + private Map chargeMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(value = "capacity_subject") + @ApiModelProperty(value = "产能主体,参考#ProcedureCapacitySubject", required = "required,num") + private Integer capacitySubject; + + @TableField(exist = false) + @ApiModelProperty(value = "设备清单信息", required = "required,json") + private List workProcedureEquipmentList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedureEquipment.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedureEquipment.java new file mode 100644 index 0000000..a3839ad --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/entity/WorkProcedureEquipment.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.equipment.entity.Equipment; +import lombok.Data; + +/** + * @ClassName: WorkProcedureEquipment + * @Description: 工序下的设备清单管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/23 21:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_work_procedure_equipment") +@ApiModel("工序下的设备清单管理实体类") +public class WorkProcedureEquipment extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "work_procedure_id") + @Property(value = "工序id") + private String workProcedureId; + + @TableField(value = "equipment_id") + @ApiModelProperty(value = "设备id", required = "required") + private String equipmentId; + + @TableField(exist = false) + @Property(value = "设备信息") + private Equipment equipmentMation; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureChildService.java new file mode 100644 index 0000000..e6f826d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureChildService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.procedure.entity.WayProcedureChild; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WayProcedureChildService + * @Description: 工艺路线关联的工序服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/26 20:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WayProcedureChildService extends SkyeyeBusinessService { + + void deleteWayProcedureByWayId(String wayId); + + void saveWayProcedure(String wayId, List wayProcedureList, String userId); + + List queryWayProcedureByWayId(String wayId); + + String calcOrderAllTotalPrice(List wayProcedureChildList); + + Map> queryWayProcedureByWayId(List wayIds); + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureService.java new file mode 100644 index 0000000..e6003e6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WayProcedureService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.procedure.entity.WayProcedure; + +/** + * @ClassName: WayProcedureService + * @Description: 工艺路线管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/24 17:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WayProcedureService extends SkyeyeBusinessService { + + void queryProcedureListByWayId(InputObject inputObject, OutputObject outputObject); + + void queryAllPublishProcedureList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureEquipmentService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureEquipmentService.java new file mode 100644 index 0000000..6a56393 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureEquipmentService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.procedure.entity.WorkProcedureEquipment; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WorkProcedureEquipmentService + * @Description: 工序下的设备清单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/18 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WorkProcedureEquipmentService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + Map> selectByParentId(List parentIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureService.java new file mode 100644 index 0000000..8fc90c6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/WorkProcedureService.java @@ -0,0 +1,30 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.procedure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.farm.entity.Farm; +import com.skyeye.procedure.entity.WorkProcedure; + +import java.util.List; + +/** + * @ClassName: WorkProcedureService + * @Description: 工序管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/23 21:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WorkProcedureService extends SkyeyeBusinessService { + + void queryAllWorkProcedureList(InputObject inputObject, OutputObject outputObject); + + void queryExecuteFarmByWorkProcedureId(InputObject inputObject, OutputObject outputObject); + + List queryExecuteFarmByWorkProcedureId(String workProcedureId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureChildServiceImpl.java new file mode 100644 index 0000000..1e16e19 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureChildServiceImpl.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.procedure.dao.WayProcedureChildDao; +import com.skyeye.procedure.entity.WayProcedureChild; +import com.skyeye.procedure.service.WayProcedureChildService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WayProcedureChildServiceImpl + * @Description: 工艺路线关联的工序服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/26 20:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工艺路线关联的工序", groupName = "工艺路线管理", manageShow = false) +public class WayProcedureChildServiceImpl extends SkyeyeBusinessServiceImpl implements WayProcedureChildService { + + @Override + public void deleteWayProcedureByWayId(String wayId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedureChild::getWayId), wayId); + remove(queryWrapper); + } + + @Override + public void saveWayProcedure(String wayId, List wayProcedureList, String userId) { + deleteWayProcedureByWayId(wayId); + if (CollectionUtil.isNotEmpty(wayProcedureList)) { + for (WayProcedureChild wayProcedureChild : wayProcedureList) { + wayProcedureChild.setWayId(wayId); + } + createEntity(wayProcedureList, userId); + } + } + + @Override + public List queryWayProcedureByWayId(String wayId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedureChild::getWayId), wayId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(WayProcedureChild::getOrderBy)); + List wayProcedureList = list(queryWrapper); + return wayProcedureList; + } + + @Override + public String calcOrderAllTotalPrice(List wayProcedureChildList) { + String totalPrice = "0"; + for (WayProcedureChild wayProcedureChild : wayProcedureChildList) { + // 计算子单据总价:单价相加 + totalPrice = CalculationUtil.add(totalPrice, wayProcedureChild.getPrice()); + } + return totalPrice; + } + + @Override + public Map> queryWayProcedureByWayId(List wayIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(WayProcedureChild::getWayId), wayIds); + List wayProcedureChildList = list(queryWrapper); + Map> listMap = wayProcedureChildList.stream().collect(Collectors.groupingBy(WayProcedureChild::getWayId)); + return listMap; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureServiceImpl.java new file mode 100644 index 0000000..ace9643 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WayProcedureServiceImpl.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.procedure.dao.WayProcedureDao; +import com.skyeye.procedure.entity.WayProcedure; +import com.skyeye.procedure.entity.WayProcedureChild; +import com.skyeye.procedure.entity.WorkProcedure; +import com.skyeye.procedure.service.WayProcedureChildService; +import com.skyeye.procedure.service.WayProcedureService; +import com.skyeye.procedure.service.WorkProcedureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ErpWayProcedureServiceImpl + * @Description: 工艺路线管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/5 21:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工艺路线管理", groupName = "工艺路线管理") +public class WayProcedureServiceImpl extends SkyeyeBusinessServiceImpl implements WayProcedureService { + + @Autowired + private WayProcedureChildService wayProcedureChildService; + + @Autowired + private WorkProcedureService workProcedureService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedure::getWhetherLast), WhetherEnum.ENABLE_USING.getKey()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + return beans; + } + + @Override + public String createEntity(WayProcedure entity, String userId) { + entity.setStartSmallVersion(false); + return super.createEntity(entity, userId); + } + + @Override + public String updateEntity(WayProcedure entity, String userId) { + entity.setStartSmallVersion(false); + return super.updateEntity(entity, userId); + } + + @Override + public void validatorEntity(WayProcedure entity) { + entity.setAllPrice(wayProcedureChildService.calcOrderAllTotalPrice(entity.getWorkProcedureList())); + } + + @Override + public void writePostpose(WayProcedure entity, String userId) { + super.writePostpose(entity, userId); + wayProcedureChildService.saveWayProcedure(entity.getId(), entity.getWorkProcedureList(), userId); + } + + @Override + public WayProcedure getDataFromDb(String id) { + WayProcedure wayProcedure = super.getDataFromDb(id); + // 查询工序信息 + wayProcedure.setWorkProcedureList(wayProcedureChildService.queryWayProcedureByWayId(wayProcedure.getId())); + return wayProcedure; + } + + @Override + public List getDataFromDb(List idList) { + List wayProcedureList = super.getDataFromDb(idList); + // 查询工序信息 + List ids = wayProcedureList.stream().map(WayProcedure::getId).collect(Collectors.toList()); + Map> wayProcedureMap = wayProcedureChildService.queryWayProcedureByWayId(ids); + wayProcedureList.forEach(bom -> { + String id = bom.getId(); + bom.setWorkProcedureList(wayProcedureMap.get(id)); + }); + return wayProcedureList; + } + + @Override + public WayProcedure selectById(String id) { + WayProcedure wayProcedure = super.selectById(id); + // 设置工序信息 + workProcedureService.setDataMation(wayProcedure.getWorkProcedureList(), WayProcedureChild::getProcedureId); + return wayProcedure; + } + + @Override + public List selectByIds(String... ids) { + List wayProcedureList = super.selectByIds(ids); + // 设置工序信息 + wayProcedureList.forEach(wayProcedure -> { + workProcedureService.setDataMation(wayProcedure.getWorkProcedureList(), WayProcedureChild::getProcedureId); + }); + return wayProcedureList; + } + + @Override + public void deletePostpose(String id) { + wayProcedureChildService.deleteWayProcedureByWayId(id); + } + + /** + * 获取工艺下的工序列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryProcedureListByWayId(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + WayProcedure wayProcedure = selectById(id); + List workProcedureList = wayProcedure.getWorkProcedureList().stream() + .map(wayProcedureChild -> wayProcedureChild.getProcedureMation()) + .collect(Collectors.toList()); + outputObject.setBeans(workProcedureList); + outputObject.settotal(workProcedureList.size()); + } + + @Override + public void queryAllPublishProcedureList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedure::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedure::getWhetherLast), WhetherEnum.ENABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(WayProcedure::getWhetherPublish), WhetherEnum.ENABLE_USING.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(WayProcedure::getCreateTime)); + List wayProcedureList = list(queryWrapper); + outputObject.setBeans(wayProcedureList); + outputObject.settotal(wayProcedureList.size()); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureEquipmentServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureEquipmentServiceImpl.java new file mode 100644 index 0000000..9c93be6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureEquipmentServiceImpl.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.procedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.procedure.dao.WorkProcedureEquipmentDao; +import com.skyeye.procedure.entity.WorkProcedureEquipment; +import com.skyeye.procedure.service.WorkProcedureEquipmentService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WorkProcedureEquipmentServiceImpl + * @Description: 工序下的设备清单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/18 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工序下的设备清单管理", groupName = "工序管理", manageShow = false) +public class WorkProcedureEquipmentServiceImpl extends SkyeyeBusinessServiceImpl implements WorkProcedureEquipmentService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (WorkProcedureEquipment procedureEquipment : beans) { + procedureEquipment.setWorkProcedureId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WorkProcedureEquipment::getWorkProcedureId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WorkProcedureEquipment::getWorkProcedureId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public Map> selectByParentId(List parentIds) { + if (CollectionUtil.isEmpty(parentIds)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(WorkProcedureEquipment::getWorkProcedureId), parentIds); + List list = list(queryWrapper); + return list.stream().collect(Collectors.groupingBy(WorkProcedureEquipment::getWorkProcedureId)); + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureServiceImpl.java new file mode 100644 index 0000000..9c840bc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/procedure/service/impl/WorkProcedureServiceImpl.java @@ -0,0 +1,189 @@ +/** + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + */ + +package com.skyeye.procedure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.equipment.entity.Equipment; +import com.skyeye.equipment.service.EquipmentService; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.entity.Farm; +import com.skyeye.farm.service.FarmService; +import com.skyeye.procedure.dao.WorkProcedureDao; +import com.skyeye.procedure.entity.WorkProcedure; +import com.skyeye.procedure.entity.WorkProcedureEquipment; +import com.skyeye.procedure.service.WorkProcedureEquipmentService; +import com.skyeye.procedure.service.WorkProcedureService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WorkProcedureServiceImpl + * @Description: 工序信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工序管理", groupName = "工序管理") +public class WorkProcedureServiceImpl extends SkyeyeBusinessServiceImpl implements WorkProcedureService { + + @Autowired + private WorkProcedureEquipmentService workProcedureEquipmentService; + + @Autowired + private EquipmentService equipmentService; + + @Autowired + private FarmService farmService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setMationForMap(beans, "chargeId", "chargeMation"); + return beans; + } + + @Override + protected void validatorEntity(WorkProcedure entity) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(WorkProcedure::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(WorkProcedure::getNumber), entity.getNumber())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + WorkProcedure checkWorkProcedure = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkWorkProcedure)) { + throw new CustomException("this 【name/number】 is exist."); + } + // 校验设备的重复性 + List equipmentIdList = entity.getWorkProcedureEquipmentList().stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getEquipmentId())) + .map(WorkProcedureEquipment::getEquipmentId).distinct().collect(Collectors.toList()); + if (equipmentIdList.size() != entity.getWorkProcedureEquipmentList().size()) { + throw new CustomException("存在相同的设备信息,请确认."); + } + } + + @Override + public void writePostpose(WorkProcedure entity, String userId) { + super.writePostpose(entity, userId); + // 保存设备清单信息 + workProcedureEquipmentService.saveList(entity.getId(), entity.getWorkProcedureEquipmentList()); + } + + @Override + public WorkProcedure getDataFromDb(String id) { + WorkProcedure workProcedure = super.getDataFromDb(id); + // 查询设备清单信息 + workProcedure.setWorkProcedureEquipmentList(workProcedureEquipmentService.selectByParentId(id)); + return workProcedure; + } + + @Override + public List getDataFromDb(List idList) { + List workProcedureList = super.getDataFromDb(idList); + // 查询工序信息 + List ids = workProcedureList.stream().map(WorkProcedure::getId).collect(Collectors.toList()); + Map> workProcedureEquipmentMap = workProcedureEquipmentService.selectByParentId(ids); + workProcedureList.forEach(workProcedure -> { + String id = workProcedure.getId(); + workProcedure.setWorkProcedureEquipmentList(workProcedureEquipmentMap.get(id)); + }); + return workProcedureList; + } + + @Override + public WorkProcedure selectById(String id) { + WorkProcedure workProcedure = super.selectById(id); + iAuthUserService.setDataMation(workProcedure, WorkProcedure::getChargeId); + // 设置设备信息 + equipmentService.setDataMation(workProcedure.getWorkProcedureEquipmentList(), WorkProcedureEquipment::getEquipmentId); + return workProcedure; + } + + @Override + public List selectByIds(String... ids) { + List workProcedures = super.selectByIds(ids); + iAuthUserService.setDataMation(workProcedures, WorkProcedure::getChargeId); + // 设置设备信息 + List equipmentIds = workProcedures.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getWorkProcedureEquipmentList())) + .flatMap(norms -> norms.getWorkProcedureEquipmentList().stream()).map(WorkProcedureEquipment::getEquipmentId).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(equipmentIds)) { + Map equipmentMap = equipmentService.selectMapByIds(equipmentIds); + workProcedures.forEach(workProcedure -> { + if (CollectionUtil.isEmpty(workProcedure.getWorkProcedureEquipmentList())) { + return; + } + workProcedure.getWorkProcedureEquipmentList().forEach(workProcedureEquipment -> { + workProcedureEquipment.setEquipmentMation(equipmentMap.get(workProcedureEquipment.getEquipmentId())); + }); + }); + } + return workProcedures; + } + + /** + * 查询所有工序列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllWorkProcedureList(InputObject inputObject, OutputObject outputObject) { + List beans = queryAllData(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void queryExecuteFarmByWorkProcedureId(InputObject inputObject, OutputObject outputObject) { + String workProcedureId = inputObject.getParams().get("workProcedureId").toString(); + // 查询设备信息,然后根据设备信息查询车间信息,如果设备信息为空/车间信息为空,则返回所有车间列表 + List farmList = queryExecuteFarmByWorkProcedureId(workProcedureId); + if (CollectionUtil.isEmpty(farmList)) { + farmList = farmService.queryEnabledFarmList(); + } + outputObject.setBeans(farmList); + outputObject.settotal(farmList.size()); + } + + @Override + public List queryExecuteFarmByWorkProcedureId(String workProcedureId) { + // 查询设备信息 + List workProcedureEquipmentList = workProcedureEquipmentService.selectByParentId(workProcedureId); + if (CollectionUtil.isEmpty(workProcedureEquipmentList)) { + return CollectionUtil.newArrayList(); + } + List equipmentIdList = workProcedureEquipmentList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getEquipmentId())) + .map(WorkProcedureEquipment::getEquipmentId).distinct().collect(Collectors.toList()); + List equipment = equipmentService.selectByIds(equipmentIdList.toArray(new String[]{})); + // 查询车间信息 + List farmIdList = equipment.stream().map(Equipment::getFarmId).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(farmIdList)) { + return CollectionUtil.newArrayList(); + } + List farmList = farmService.selectByIds(farmIdList.toArray(new String[]{})); + return farmList; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionChildType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionChildType.java new file mode 100644 index 0000000..3a1a420 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionChildType.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import cn.hutool.core.map.MapUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: ProductionChildType + * @Description: 生产计划单子单据生产类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 11:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionChildType implements SkyeyeEnumClass { + + SELF_CONTROL(1, "自制", true, false), + OUTSOURCING(2, "委外", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static Map getMation(Integer type) { + for (ProductionChildType bean : ProductionChildType.values()) { + if (type == bean.getKey()) { + Map result = new HashMap<>(); + result.put("id", bean.getKey()); + result.put("name", bean.getValue()); + return result; + } + } + return MapUtil.newHashMap(); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionFromType.java new file mode 100644 index 0000000..31bd7f2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionFromType + * @Description: 生产计划单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionFromType implements SkyeyeEnumClass { + + DELIVERY_PLAN(1, "出货计划", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionMachinOrderState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionMachinOrderState.java new file mode 100644 index 0000000..93ad0ed --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionMachinOrderState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionMachinOrderState + * @Description: 生产计划单下达加工单的状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionMachinOrderState implements SkyeyeEnumClass { + + NOT_NEED_ISSUE(1, "无需下达", "purple", true, true), + NEED_ISSUE(2, "待下达", "blue", true, false), + PARTIAL_ISSUE(3, "部分下达", "orange", true, false), + COMPLATE_ISSUE(4, "全部下达", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionOutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionOutState.java new file mode 100644 index 0000000..5d7cf52 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionOutState.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionOutState + * @Description: 生产计划单委外状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionOutState implements SkyeyeEnumClass { + + NOT_NEED_OUT(1, "无需委外", "purple", true, true), + NEED_OUT(2, "待委外", "blue", true, false), + PARTIAL_OUT(3, "部分委外", "orange", true, false), + COMPLATE_OUT(4, "全部委外", "green", true, false); + + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanFromType.java new file mode 100644 index 0000000..a49734d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionPlanFromType + * @Description: 出货计划单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionPlanFromType implements SkyeyeEnumClass { + + SEAL_ORDER(1, "销售订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanProduceState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanProduceState.java new file mode 100644 index 0000000..d7d9b26 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanProduceState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionPlanProduceState + * @Description: 出货计划单生产状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionPlanProduceState implements SkyeyeEnumClass { + + NOT_NEED(1, "无需生产", "purple", true, true), + NEED(2, "待生产", "blue", true, false), + PARTIAL(3, "部分生产", "orange", true, false), + COMPLATE(4, "全部生产", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanPurchaseState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanPurchaseState.java new file mode 100644 index 0000000..38387bd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/classenum/ProductionPlanPurchaseState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductionPlanPurchaseState + * @Description: 出货计划单采购状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductionPlanPurchaseState implements SkyeyeEnumClass { + + NOT_NEED(1, "无需采购", "purple", true, true), + NEED(2, "待采购", "blue", true, false), + PARTIAL(3, "部分采购", "orange", true, false), + COMPLATE(4, "全部采购", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionController.java new file mode 100644 index 0000000..a620639 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionController.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.machin.entity.Machin; +import com.skyeye.production.entity.Production; +import com.skyeye.production.service.ProductionService; +import com.skyeye.whole.entity.WholeOrderOut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ProductionController + * @Description: 生产计划单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/9 10:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "生产计划单", tags = "生产计划单", modelName = "生产计划单") +public class ProductionController { + + @Autowired + private ProductionService productionService; + + /** + * 查询生产计划单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionList", value = "查询生产计划单列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ProductionController/queryProductionList") + public void queryProductionList(InputObject inputObject, OutputObject outputObject) { + productionService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑生产计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeProduction", value = "新增/编辑生产计划单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Production.class) + @RequestMapping("/post/ProductionController/writeProduction") + public void writeProduction(InputObject inputObject, OutputObject outputObject) { + productionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询生产计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionById", value = "根据id查询生产计划单", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "生产计划单id", required = "required")}) + @RequestMapping("/post/ProductionController/queryProductionById") + public void queryProductionById(InputObject inputObject, OutputObject outputObject) { + productionService.selectById(inputObject, outputObject); + } + + /** + * 删除生产计划单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteProductionById", value = "删除生产计划单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionController/deleteProductionById") + public void deleteProductionById(InputObject inputObject, OutputObject outputObject) { + productionService.deleteById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "erpproduction007", value = "提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ProductionController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + productionService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销生产计划单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeProduction", value = "撤销生产计划单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ProductionController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + productionService.revoke(inputObject, outputObject); + } + + /** + * 转加工单时,根据id查询生产计划单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionTransById", value = "转加工单时,根据id查询生产计划单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionController/queryProductionTransById") + public void queryProductionTransById(InputObject inputObject, OutputObject outputObject) { + productionService.queryProductionTransById(inputObject, outputObject); + } + + /** + * 生产计划单转加工单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertProductionToMachin", value = "生产计划单转加工单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Machin.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionController/insertProductionToMachin") + public void insertProductionToMachin(InputObject inputObject, OutputObject outputObject) { + productionService.insertProductionToMachin(inputObject, outputObject); + } + + /** + * 转整单委外单时,根据id查询生产计划单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionTransWholeById", value = "转整单委外单时,根据id查询生产计划单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionController/queryProductionTransWholeById") + public void queryProductionTransWholeById(InputObject inputObject, OutputObject outputObject) { + productionService.queryProductionTransWholeById(inputObject, outputObject); + } + + /** + * 生产计划单转整单委外单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertProductionToWhole", value = "生产计划单转整单委外单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WholeOrderOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionController/insertProductionToWhole") + public void insertProductionToWhole(InputObject inputObject, OutputObject outputObject) { + productionService.insertProductionToWhole(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionPlanController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionPlanController.java new file mode 100644 index 0000000..c624df6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/controller/ProductionPlanController.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.production.entity.Production; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.production.service.ProductionPlanService; +import com.skyeye.purchase.entity.PurchaseOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ProductionPlanController + * @Description: 出货计划单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "出货计划单", tags = "出货计划单", modelName = "出货计划单") +public class ProductionPlanController { + + @Autowired + private ProductionPlanService productionPlanService; + + /** + * 获取出货计划单信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionPlanList", value = "获取出货计划单信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ProductionPlanController/queryProductionPlanList") + public void queryProductionPlanList(InputObject inputObject, OutputObject outputObject) { + productionPlanService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑出货计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeProductionPlan", value = "新增/编辑出货计划单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ProductionPlan.class) + @RequestMapping("/post/ProductionPlanController/writeProductionPlan") + public void writeProductionPlan(InputObject inputObject, OutputObject outputObject) { + productionPlanService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitProductionPlanToApproval", value = "提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ProductionPlanController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + productionPlanService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除出货计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteProductionPlan", value = "删除出货计划单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/deleteProductionPlan") + public void invalid(InputObject inputObject, OutputObject outputObject) { + productionPlanService.deleteById(inputObject, outputObject); + } + + /** + * 撤销出货计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeProductionPlan", value = "撤销出货计划单", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + productionPlanService.revoke(inputObject, outputObject); + } + + /** + * 转生产计划单时,根据id查询出货计划单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionPlanTransById", value = "转生产计划单时,根据id查询出货计划单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/queryProductionPlanTransById") + public void queryProductionPlanTransById(InputObject inputObject, OutputObject outputObject) { + productionPlanService.queryProductionPlanTransById(inputObject, outputObject); + } + + /** + * 出货计划单转生产计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertProductionPlanToProduction", value = "出货计划单转生产计划单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Production.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/insertProductionPlanToProduction") + public void insertProductionPlanToProduction(InputObject inputObject, OutputObject outputObject) { + productionPlanService.insertProductionPlanToProduction(inputObject, outputObject); + } + + /** + * 转采购订单时,根据id查询出货计划单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProductionPlanTransPurchaseOrderById", value = "转采购订单时,根据id查询出货计划单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/queryProductionPlanTransPurchaseOrderById") + public void queryProductionPlanTransPurchaseOrderById(InputObject inputObject, OutputObject outputObject) { + productionPlanService.queryProductionPlanTransPurchaseOrderById(inputObject, outputObject); + } + + /** + * 出货计划单转采购订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertProductionPlanToPurchaseOrder", value = "出货计划单转采购订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseOrder.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProductionPlanController/insertProductionPlanToPurchaseOrder") + public void insertProductionPlanToPurchaseOrder(InputObject inputObject, OutputObject outputObject) { + productionPlanService.insertProductionPlanToPurchaseOrder(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionChildDao.java new file mode 100644 index 0000000..a379289 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.production.entity.ProductionChild; + +/** + * @ClassName: ProductionChildDao + * @Description: 生产计划单子单据数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/28 21:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionDao.java new file mode 100644 index 0000000..7660eb1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.production.entity.Production; + +/** + * @ClassName: ErpProductionDao + * @Description: 生产计划单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/25 21:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanChildDao.java new file mode 100644 index 0000000..c2e6c62 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.production.entity.ProductionPlanChild; + +/** + * @ClassName: ProductionPlanChildDao + * @Description: 出货计划单子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionPlanChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanDao.java new file mode 100644 index 0000000..8844f57 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/dao/ProductionPlanDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.production.entity.ProductionPlan; + +/** + * @ClassName: ProductionPlanDao + * @Description: 出货计划单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionPlanDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/Production.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/Production.java new file mode 100644 index 0000000..a0292b5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/Production.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Production + * @Description: 生产计划单 + * 1. 状态(state)只有工作流(FlowableStateEnum)的状态 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 10:53 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_PRODUCTION_CACHE_KEY, cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "erp_production_head", autoResultMap = true) +@ApiModel("生产计划单实体类") +public class Production extends SkyeyeFlowable { + + @TableField(exist = false) + @Property(value = "树的名称(订单编号)") + private String name; + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#ProductionFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("out_state") + @Property(value = "委外状态,参考#ProductionOutState") + private Integer outState; + + @TableField("machin_order_state") + @Property(value = "加工单的下达状态,参考#ProductionMachinOrderState") + private Integer machinOrderState; + + @TableField(exist = false) + @ApiModelProperty(value = "子单据信息", required = "required,json") + private List productionChildList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionChild.java new file mode 100644 index 0000000..7d32ca5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionChild.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.bom.entity.Bom; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ProductionChild + * @Description: 生产计划单子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/28 21:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_production_child", autoResultMap = true) +@ApiModel("生产计划单子单据实体类") +public class ProductionChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "parent_id") + @Property(value = "生产计划单id") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField(value = "plan_start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String planStartTime; + + @TableField(value = "plan_end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String planEndTime; + + @TableField("delivery_time") + @ApiModelProperty(value = "交货日期", required = "required") + private String deliveryTime; + + @TableField(value = "bom_id") + @ApiModelProperty(value = "bom方案id") + private String bomId; + + @TableField(exist = false) + @Property(value = "bom方案信息") + private Bom bomMation; + + @TableField(exist = false) + @Property(value = "该规格对应的所有bom方案信息列表") + private List bomList; + + @TableField(value = "production_type") + @ApiModelProperty(value = "生产类型,参考#ProductionChildType", required = "required,num") + private Integer productionType; + + @TableField(exist = false) + @Property(value = "生产类型信息") + private Map productionTypeMation; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlan.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlan.java new file mode 100644 index 0000000..e7423d7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlan.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ProductionPlan + * @Description: 出货计划单 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 10:53 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.MES_PRODUCTION_PLAN_CACHE_KEY, cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "erp_production_plan_head", autoResultMap = true) +@ApiModel("出货计划单实体类") +public class ProductionPlan extends SkyeyeFlowable { + + @TableField(value = "from_type_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据类型,参考#ProductionPlanFromType") + private Integer fromTypeId; + + @TableField(value = "from_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField(exist = false) + @Property(value = "来源单据信息") + private Map fromMation; + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("purchase_state") + @Property("采购状态,参考#ProductionPlanPurchaseState") + private Integer purchaseState; + + @TableField("produce_state") + @Property("生产状态,参考#ProductionPlanProduceState") + private Integer produceState; + + @TableField(exist = false) + @ApiModelProperty(value = "子单据信息", required = "required,json") + private List productionPlanChildList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlanChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlanChild.java new file mode 100644 index 0000000..7204654 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/entity/ProductionPlanChild.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.bom.entity.Bom; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ProductionPlanChild + * @Description: 出货计划单子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/28 21:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_production_plan_child", autoResultMap = true) +@ApiModel("出货计划单子单据实体类") +public class ProductionPlanChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "parent_id") + @Property(value = "单据id") + private String parentId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(exist = false) + @Property(value = "该规格对应的所有bom方案信息列表") + private List bomList; + + @TableField(value = "oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField("delivery_time") + @ApiModelProperty(value = "交货日期", required = "required") + private String deliveryTime; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionChildService.java new file mode 100644 index 0000000..ffb95e3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionChildService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.production.entity.ProductionChild; + +import java.util.List; + +/** + * @ClassName: ProductionChildService + * @Description: 生产计划单子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/28 21:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionChildService extends SkyeyeBusinessService { + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + List selectByParentId(List parentIds); + + void saveList(String parentId, List productionChildList); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanChildService.java new file mode 100644 index 0000000..d7b0914 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanChildService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.production.entity.ProductionPlanChild; + +import java.util.List; + +/** + * @ClassName: ProductionPlanChildService + * @Description: 出货计划单子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionPlanChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + List selectByParentId(List parentIds); + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanService.java new file mode 100644 index 0000000..713c54b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionPlanService.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.production.entity.ProductionPlan; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ProductionPlanService + * @Description: 出货计划单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionPlanService extends SkyeyeFlowableService { + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + + Map calcMaterialNormsNumByFromId(String fromId); + + /** + * 修改采购状态 + * + * @param id 出货计划单id + * @param purchaseState 采购状态 {@link com.skyeye.production.classenum.ProductionPlanPurchaseState} + */ + void editPurchaseState(String id, Integer purchaseState); + + /** + * 修改生产状态 + * + * @param id 出货计划单id + * @param produceState 生产状态 {@link com.skyeye.production.classenum.ProductionPlanProduceState} + */ + void editProduceState(String id, Integer produceState); + + void queryProductionPlanTransById(InputObject inputObject, OutputObject outputObject); + + void insertProductionPlanToProduction(InputObject inputObject, OutputObject outputObject); + + void queryProductionPlanTransPurchaseOrderById(InputObject inputObject, OutputObject outputObject); + + void insertProductionPlanToPurchaseOrder(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionService.java new file mode 100644 index 0000000..cf44db4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/ProductionService.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.production.entity.Production; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ProductionService + * @Description: 生产计划单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/29 11:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProductionService extends SkyeyeFlowableService { + + void setOrderMationByFromId(List> beans, String idKey, String mationKey); + + void editOutState(String id, Integer outState); + + void editMachinOrderState(String id, Integer machinOrderState); + + Map calcMaterialNormsNumByFromId(String fromId); + + void queryProductionTransById(InputObject inputObject, OutputObject outputObject); + + void insertProductionToMachin(InputObject inputObject, OutputObject outputObject); + + void queryProductionTransWholeById(InputObject inputObject, OutputObject outputObject); + + void insertProductionToWhole(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionChildServiceImpl.java new file mode 100644 index 0000000..c4fbbec --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionChildServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.production.dao.ProductionChildDao; +import com.skyeye.production.entity.ProductionChild; +import com.skyeye.production.service.ProductionChildService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ProductionChildServiceImpl + * @Description: 生产计划单子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/28 21:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "生产计划单子单据", groupName = "生产计划单管理", manageShow = false) +public class ProductionChildServiceImpl extends SkyeyeBusinessServiceImpl implements ProductionChildService { + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ProductionChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ProductionChild::getParentId), parentId); + List productionChildList = list(queryWrapper); + return productionChildList; + } + + @Override + public List selectByParentId(List parentIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ProductionChild::getParentId), parentIds); + List productionChildList = list(queryWrapper); + return productionChildList; + } + + @Override + public void saveList(String parentId, List productionChildList) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(productionChildList)) { + for (ProductionChild productionChild : productionChildList) { + productionChild.setParentId(parentId); + } + createEntity(productionChildList, StrUtil.EMPTY); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanChildServiceImpl.java new file mode 100644 index 0000000..aaca104 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanChildServiceImpl.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.production.dao.ProductionPlanChildDao; +import com.skyeye.production.entity.ProductionPlanChild; +import com.skyeye.production.service.ProductionPlanChildService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ProductionPlanChildServiceImpl + * @Description: 出货计划单子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "出货计划单子单据", groupName = "出货计划单子单据", manageShow = false) +public class ProductionPlanChildServiceImpl extends SkyeyeBusinessServiceImpl implements ProductionPlanChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ProductionPlanChild productionPlanChild : beans) { + productionPlanChild.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ProductionPlanChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ProductionPlanChild::getParentId), parentId); + List productionPlanChildList = list(queryWrapper); + return productionPlanChildList; + } + + @Override + public List selectByParentId(List parentIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ProductionPlanChild::getParentId), parentIds); + List productionPlanChildList = list(queryWrapper); + return productionPlanChildList; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanServiceImpl.java new file mode 100644 index 0000000..504495a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionPlanServiceImpl.java @@ -0,0 +1,390 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialFromType; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.production.classenum.ProductionFromType; +import com.skyeye.production.classenum.ProductionPlanFromType; +import com.skyeye.production.classenum.ProductionPlanProduceState; +import com.skyeye.production.classenum.ProductionPlanPurchaseState; +import com.skyeye.production.dao.ProductionPlanDao; +import com.skyeye.production.entity.Production; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.production.entity.ProductionPlanChild; +import com.skyeye.production.service.ProductionPlanChildService; +import com.skyeye.production.service.ProductionPlanService; +import com.skyeye.production.service.ProductionService; +import com.skyeye.purchase.classenum.PurchaseOrderFromType; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.seal.entity.SalesOrder; +import com.skyeye.seal.service.SalesOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ProductionPlanServiceImpl + * @Description: 出货计划单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/21 20:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "出货计划单", groupName = "出货计划单", flowable = true) +public class ProductionPlanServiceImpl extends SkyeyeFlowableServiceImpl implements ProductionPlanService { + + @Autowired + private ProductionPlanChildService productionPlanChildService; + + @Autowired + private ProductionService productionService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private SalesOrderService salesOrderService; + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private BomService bomService; + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + salesOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(ProductionPlan entity) { + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(ProductionPlan entity) { + super.createPrepose(entity); + setOtherMation(entity); + } + + @Override + public void updatePrepose(ProductionPlan entity) { + super.updatePrepose(entity); + setOtherMation(entity); + } + + @Override + public void writeChild(ProductionPlan entity, String userId) { + // 保存子单据信息 + productionPlanChildService.saveList(entity.getId(), entity.getProductionPlanChildList()); + super.writeChild(entity, userId); + } + + private void setOtherMation(ProductionPlan entity) { + // 设置采购状态 + Integer purchaseState = ProductionPlanPurchaseState.NOT_NEED.getKey(); + Integer produceState = ProductionPlanProduceState.NOT_NEED.getKey(); + List materialIds = entity.getProductionPlanChildList().stream() + .map(ProductionPlanChild::getMaterialId).distinct().collect(Collectors.toList()); + List materials = materialService.selectByIds(materialIds.toArray(new String[]{})); + for (Material material : materials) { + if (material.getFromType() == MaterialFromType.OUTSOURCING.getKey()) { + // 外购件 + purchaseState = ProductionPlanPurchaseState.NEED.getKey(); + break; + } + if (material.getFromType() == MaterialFromType.SELF_PRODUCED.getKey()) { + // 自产件 + produceState = ProductionPlanProduceState.NEED.getKey(); + } + } + entity.setPurchaseState(purchaseState); + entity.setProduceState(produceState); + } + + @Override + public ProductionPlan getDataFromDb(String id) { + ProductionPlan productionPlan = super.getDataFromDb(id); + // 查询子单据信息 + productionPlan.setProductionPlanChildList(productionPlanChildService.selectByParentId(productionPlan.getId())); + return productionPlan; + } + + @Override + public ProductionPlan selectById(String id) { + ProductionPlan productionPlan = super.selectById(id); + // 查询子单据产品信息 + materialService.setDataMation(productionPlan.getProductionPlanChildList(), ProductionPlanChild::getMaterialId); + materialNormsService.setDataMation(productionPlan.getProductionPlanChildList(), ProductionPlanChild::getNormsId); + if (productionPlan.getFromTypeId() == ProductionPlanFromType.SEAL_ORDER.getKey()) { + // 销售订单 + salesOrderService.setDataMation(productionPlan, ProductionPlan::getFromId); + } + return productionPlan; + } + + @Override + public void deletePreExecution(String id) { + ProductionPlan productionPlan = selectById(id); + if (!FlowableStateEnum.DRAFT.getKey().equals(productionPlan.getState()) + && !FlowableStateEnum.REJECT.getKey().equals(productionPlan.getState()) + && !FlowableStateEnum.REVOKE.getKey().equals(productionPlan.getState())) { + throw new CustomException("只有草稿、驳回、撤销状态的可删除."); + } + } + + @Override + public void deletePostpose(String id) { + // 删除子单据信息 + productionPlanChildService.deleteByParentId(id); + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List productionPlanList = list(queryWrapper); + Map productionPlanMap = productionPlanList.stream() + .collect(Collectors.toMap(ProductionPlan::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + ProductionPlan entity = productionPlanMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + private void checkMaterialNorms(ProductionPlan entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前出货计划单的商品数量 + Map orderNormsNum = entity.getProductionPlanChildList().stream() + .collect(Collectors.toMap(ProductionPlanChild::getNormsId, ProductionPlanChild::getOperNumber)); + // 获取同一个来源单据下已经审批通过的出货计划单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ProductionPlanFromType.SEAL_ORDER.getKey()) { + // 销售订单 + SalesOrder salesOrder = salesOrderService.selectById(entity.getFromId()); + List fromNormsIds = salesOrder.getErpOrderItemList().stream() + .map(ErpOrderItem::getNormsId).collect(Collectors.toList()); + // 求差集(销售订单不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该销售订单下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + salesOrder.getErpOrderItemList().forEach(erpOrderItem -> { + // 销售订单数量 - 当前出货计划单数量 - 已经审批通过的出货计划单数量 + Integer surplusNum = erpOrderItem.getOperNumber() + - (orderNormsNum.containsKey(erpOrderItem.getNormsId()) ? orderNormsNum.get(erpOrderItem.getNormsId()) : 0) + - (executeNum.containsKey(erpOrderItem.getNormsId()) ? executeNum.get(erpOrderItem.getNormsId()) : 0); + if (surplusNum < 0) { + throw new CustomException("超出销售订单的商品数量."); + } + if (setData) { + erpOrderItem.setOperNumber(surplusNum); + } + }); + if (setData) { + // TODO 该销售订单的商品是否已经全部下达了出货计划单-----目前先不做任何操作 + } + } + } + + @Override + public void approvalEndIsSuccess(ProductionPlan entity) { + entity = selectById(entity.getId()); + // 修改来源单据的状态信息 + checkMaterialNorms(entity, true); + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ProductionPlan::getFromId), fromId); + // 只查询审批通过的 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ProductionPlan::getState), stateList); + List productionList = list(queryWrapper); + List ids = productionList.stream().map(ProductionPlan::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List productionPlanChildList = productionPlanChildService.selectByParentId(ids); + Map collect = productionPlanChildList.stream() + .collect(Collectors.groupingBy(ProductionPlanChild::getNormsId, Collectors.summingInt(ProductionPlanChild::getOperNumber))); + return collect; + } + + @Override + public void editPurchaseState(String id, Integer purchaseState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ProductionPlan::getPurchaseState), purchaseState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void editProduceState(String id, Integer produceState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ProductionPlan::getProduceState), produceState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void queryProductionPlanTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ProductionPlan productionPlan = selectById(id); + // 只查询自产商品 + List productionPlanChildList = productionPlan.getProductionPlanChildList().stream() + .filter(productionPlanChild -> productionPlanChild.getMaterialMation().getFromType() == MaterialFromType.SELF_PRODUCED.getKey()) + .collect(Collectors.toList()); + // 获取已经下达生产计划单的数量 + Map normsNum = productionService.calcMaterialNormsNumByFromId(id); + productionPlanChildList.forEach(productionPlanChild -> { + // 订单数量 - 已经下达生产计划单的数量 + Integer surplusNum = productionPlanChild.getOperNumber() + - (normsNum.containsKey(productionPlanChild.getNormsId()) ? normsNum.get(productionPlanChild.getNormsId()) : 0); + // 设置未下达生产计划单的商品数量 + productionPlanChild.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成生产计划单 + productionPlanChildList = productionPlanChildList.stream() + .filter(productionPlanChild -> productionPlanChild.getOperNumber() > 0).collect(Collectors.toList()); + // 获取规格对应的所有bom信息 + List normsId = productionPlanChildList.stream() + .map(ProductionPlanChild::getNormsId).distinct().collect(Collectors.toList()); + Map> listMap = bomService.getBomListByNormsId(normsId.toArray(new String[]{})); + // 设置生产类型信息 + productionPlanChildList.forEach(productionPlanChild -> { + productionPlanChild.setBomList(listMap.get(productionPlanChild.getNormsId())); + }); + productionPlan.setProductionPlanChildList(productionPlanChildList); + outputObject.setBean(productionPlan); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertProductionPlanToProduction(InputObject inputObject, OutputObject outputObject) { + Production production = inputObject.getParams(Production.class); + // 获取出货计划单状态 + ProductionPlan order = selectById(production.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过 && 生产状态为待生产/部分生产 的可以转生产计划单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) && + (ProductionPlanProduceState.NEED.getKey().equals(order.getProduceState()) + || ProductionPlanProduceState.PARTIAL.getKey().equals(order.getProduceState()))) { + String userId = inputObject.getLogParams().get("id").toString(); + production.setFromId(production.getId()); + production.setFromTypeId(ProductionFromType.DELIVERY_PLAN.getKey()); + production.setId(StrUtil.EMPTY); + productionService.createEntity(production, userId); + } else { + outputObject.setreturnMessage("状态错误,无法生成生产计划单."); + } + } + + @Override + public void queryProductionPlanTransPurchaseOrderById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ProductionPlan productionPlan = selectById(id); + // 只查询外购商品 + List productionPlanChildList = productionPlan.getProductionPlanChildList().stream() + .filter(productionPlanChild -> productionPlanChild.getMaterialMation().getFromType() == MaterialFromType.OUTSOURCING.getKey()) + .collect(Collectors.toList()); + // 获取已经下达采购订单的数量 + Map normsNum = purchaseOrderService.calcMaterialNormsNumByFromId(id); + productionPlanChildList.forEach(productionPlanChild -> { + // 订单数量 - 已经下达采购订单的数量 + Integer surplusNum = productionPlanChild.getOperNumber() + - (normsNum.containsKey(productionPlanChild.getNormsId()) ? normsNum.get(productionPlanChild.getNormsId()) : 0); + // 设置未下达采购订单的商品数量 + productionPlanChild.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成采购订单 + productionPlan.setProductionPlanChildList(productionPlanChildList.stream() + .filter(productionPlanChild -> productionPlanChild.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(productionPlan); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertProductionPlanToPurchaseOrder(InputObject inputObject, OutputObject outputObject) { + PurchaseOrder purchaseOrder = inputObject.getParams(PurchaseOrder.class); + // 获取出货计划单状态 + ProductionPlan order = selectById(purchaseOrder.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过 && 采购状态为待生产/部分生产 的可以转生产计划单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) && + (ProductionPlanPurchaseState.NEED.getKey().equals(order.getPurchaseState()) + || ProductionPlanPurchaseState.PARTIAL.getKey().equals(order.getPurchaseState()))) { + String userId = inputObject.getLogParams().get("id").toString(); + purchaseOrder.setFromId(purchaseOrder.getId()); + purchaseOrder.setFromTypeId(PurchaseOrderFromType.DELIVERY_PLAN.getKey()); + purchaseOrder.setId(StrUtil.EMPTY); + purchaseOrderService.createEntity(purchaseOrder, userId); + } else { + outputObject.setreturnMessage("状态错误,无法生成采购订单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionServiceImpl.java new file mode 100644 index 0000000..8c8cb16 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/production/service/impl/ProductionServiceImpl.java @@ -0,0 +1,381 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.production.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.bom.entity.Bom; +import com.skyeye.bom.service.BomService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.machin.classenum.MachinFromType; +import com.skyeye.machin.entity.Machin; +import com.skyeye.machin.service.MachinService; +import com.skyeye.material.classenum.MaterialFromType; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.production.classenum.*; +import com.skyeye.production.dao.ProductionDao; +import com.skyeye.production.entity.Production; +import com.skyeye.production.entity.ProductionChild; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.production.entity.ProductionPlanChild; +import com.skyeye.production.service.ProductionChildService; +import com.skyeye.production.service.ProductionPlanService; +import com.skyeye.production.service.ProductionService; +import com.skyeye.util.ErpOrderUtil; +import com.skyeye.whole.classenum.WholeOrderOutFromType; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ProductionServiceImpl + * @Description: 生产计划单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "生产计划单管理", groupName = "生产计划单管理", flowable = true) +public class ProductionServiceImpl extends SkyeyeFlowableServiceImpl implements ProductionService { + + @Autowired + private ProductionChildService productionChildService; + + @Autowired + private BomService bomService; + + @Autowired + private MaterialService materialService; + + @Autowired + private MachinService machinService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private ProductionPlanService productionPlanService; + + @Autowired + private WholeOrderOutService wholeOrderOutService; + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + productionPlanService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(Production entity) { + checkOrderItem(entity); + checkMaterialNorms(entity, false); + } + + private void checkOrderItem(Production entity) { + Integer outState = ProductionOutState.NOT_NEED_OUT.getKey(); + Integer machinOrderState = ProductionMachinOrderState.NOT_NEED_ISSUE.getKey(); + + for (ProductionChild productionChild : entity.getProductionChildList()) { + // 自制 + if (productionChild.getProductionType() == ProductionChildType.SELF_CONTROL.getKey()) { + machinOrderState = ProductionMachinOrderState.NEED_ISSUE.getKey(); + } + // 委外 + if (productionChild.getProductionType() == ProductionChildType.OUTSOURCING.getKey()) { + outState = ProductionOutState.NEED_OUT.getKey(); + } + } + entity.setOutState(outState); + entity.setMachinOrderState(machinOrderState); + } + + @Override + public void writeChild(Production entity, String userId) { + // 保存子单据信息 + productionChildService.saveList(entity.getId(), entity.getProductionChildList()); + super.writeChild(entity, userId); + } + + @Override + public Production getDataFromDb(String id) { + Production production = super.getDataFromDb(id); + // 查询子单据信息 + production.setProductionChildList(productionChildService.selectByParentId(production.getId())); + return production; + } + + @Override + public Production selectById(String id) { + Production production = super.selectById(id); + // 查询方案信息 + bomService.setDataMation(production.getProductionChildList(), ProductionChild::getBomId); + // 查询子单据产品信息 + materialService.setDataMation(production.getProductionChildList(), ProductionChild::getMaterialId); + materialNormsService.setDataMation(production.getProductionChildList(), ProductionChild::getNormsId); + if (production.getFromTypeId() == ProductionFromType.DELIVERY_PLAN.getKey()) { + // 出货计划单 + productionPlanService.setDataMation(production, Production::getFromId); + } + // 获取规格对应的所有bom信息 + List normsId = production.getProductionChildList().stream() + .map(ProductionChild::getNormsId).distinct().collect(Collectors.toList()); + Map> listMap = bomService.getBomListByNormsId(normsId.toArray(new String[]{})); + // 设置生产类型信息 + production.getProductionChildList().forEach(productionChild -> { + productionChild.setProductionTypeMation(ProductionChildType.getMation(productionChild.getProductionType())); + productionChild.setBomList(listMap.get(productionChild.getNormsId())); + }); + + return production; + } + + @Override + public void deletePreExecution(String id) { + Production production = selectById(id); + if (!FlowableStateEnum.DRAFT.getKey().equals(production.getState()) + && !FlowableStateEnum.REJECT.getKey().equals(production.getState()) + && !FlowableStateEnum.REVOKE.getKey().equals(production.getState())) { + throw new CustomException("只有草稿、驳回、撤销状态的可删除."); + } + } + + @Override + public void deletePostpose(String id) { + // 删除子单据信息 + productionChildService.deleteByParentId(id); + } + + @Override + public void approvalEndIsSuccess(Production entity) { + entity = selectById(entity.getId()); + // 修改来源单据的状态信息 + checkMaterialNorms(entity, true); + } + + @Override + public void setOrderMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List productionList = list(queryWrapper); + Map productionMap = productionList.stream() + .collect(Collectors.toMap(Production::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + Production entity = productionMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } + + private void checkMaterialNorms(Production entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前生产计划单的商品数量 + Map orderNormsNum = entity.getProductionChildList().stream() + .collect(Collectors.toMap(ProductionChild::getNormsId, ProductionChild::getOperNumber)); + // 获取同一个来源单据下已经审批通过的生产计划单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ProductionFromType.DELIVERY_PLAN.getKey()) { + // 出货计划单 + ProductionPlan productionPlan = productionPlanService.selectById(entity.getFromId()); + // 只查询自产商品 + List productionPlanChildList = productionPlan.getProductionPlanChildList().stream() + .filter(productionPlanChild -> productionPlanChild.getMaterialMation().getFromType() == MaterialFromType.SELF_PRODUCED.getKey()) + .collect(Collectors.toList()); + List fromNormsIds = productionPlanChildList.stream() + .map(ProductionPlanChild::getNormsId).collect(Collectors.toList()); + // 求差集(出货计划单不包含的商品) + List diffList = inSqlNormsId.stream() + .filter(num -> !fromNormsIds.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + List materialNormsList = materialNormsService.selectByIds(diffList.toArray(new String[]{})); + List normsNames = materialNormsList.stream().map(MaterialNorms::getName).collect(Collectors.toList()); + throw new CustomException(String.format(Locale.ROOT, "该出货计划单下未包含如下商品规格:【%s】.", + Joiner.on(CommonCharConstants.COMMA_MARK).join(normsNames))); + } + productionPlanChildList.forEach(productionPlanChild -> { + // 出货计划单数量 - 当前生产计划单数量 - 已经审批通过的生产计划单数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(productionPlanChild.getOperNumber(), productionPlanChild.getNormsId(), + orderNormsNum, executeNum); + if (setData) { + productionPlanChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List list = productionPlanChildList.stream() + .filter(productionPlanChild -> productionPlanChild.getOperNumber() > 0).collect(Collectors.toList()); + // 该出货计划单的商品已经全部下达了生产计划单 + if (CollectionUtil.isEmpty(list)) { + productionPlanService.editProduceState(productionPlan.getId(), ProductionPlanProduceState.COMPLATE.getKey()); + } else { + productionPlanService.editProduceState(productionPlan.getId(), ProductionPlanProduceState.PARTIAL.getKey()); + } + } + } + } + + @Override + public void editOutState(String id, Integer outState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Production::getOutState), outState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void editMachinOrderState(String id, Integer machinOrderState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Production::getMachinOrderState), machinOrderState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(Production::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Production::getState), FlowableStateEnum.PASS.getKey()); + List productionList = list(queryWrapper); + List ids = productionList.stream().map(Production::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List productionChildList = productionChildService.selectByParentId(ids); + Map collect = productionChildList.stream() + .collect(Collectors.groupingBy(ProductionChild::getNormsId, Collectors.summingInt(ProductionChild::getOperNumber))); + return collect; + } + + @Override + public void queryProductionTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Production production = selectById(id); + // 获取已经下达加工单的数量 + Map normsNum = machinService.calcMaterialNormsNumByFromId(id); + production.getProductionChildList().forEach(productionChild -> { + // 生产计划单数量 - 已经下达加工单的数量 + Integer surplusNum = productionChild.getOperNumber() + - (normsNum.containsKey(productionChild.getNormsId()) ? normsNum.get(productionChild.getNormsId()) : 0); + // 设置未下达加工单的商品数量 + productionChild.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成加工单 + production.setProductionChildList(production.getProductionChildList().stream() + .filter(productionChild -> productionChild.getOperNumber() > 0 + && productionChild.getProductionType() == ProductionChildType.SELF_CONTROL.getKey()).collect(Collectors.toList())); + // 获取规格对应的所有bom信息 + List normsId = production.getProductionChildList().stream() + .map(ProductionChild::getNormsId).distinct().collect(Collectors.toList()); + Map> listMap = bomService.getBomListByNormsId(normsId.toArray(new String[]{})); + // 设置生产类型信息 + production.getProductionChildList().forEach(productionChild -> { + productionChild.setBomList(listMap.get(productionChild.getNormsId())); + }); + outputObject.setBean(production); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertProductionToMachin(InputObject inputObject, OutputObject outputObject) { + Machin machin = inputObject.getParams(Machin.class); + // 获取生产计划单状态 + Production order = selectById(machin.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转加工单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + machin.setFromId(machin.getId()); + machin.setFromTypeId(MachinFromType.PRODUCTION.getKey()); + machin.setId(StrUtil.EMPTY); + machinService.createEntity(machin, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转加工单."); + } + } + + @Override + public void queryProductionTransWholeById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Production production = selectById(id); + // 获取已经下达整单委外单的数量 + Map normsNum = wholeOrderOutService.calcMaterialNormsNumByFromId(id); + production.getProductionChildList().forEach(productionChild -> { + // 生产计划单数量 - 已经下达整单委外单的数量 + Integer surplusNum = productionChild.getOperNumber() + - (normsNum.containsKey(productionChild.getNormsId()) ? normsNum.get(productionChild.getNormsId()) : 0); + // 设置未下达整单委外单的商品数量 + productionChild.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成整单委外单 + production.setProductionChildList(production.getProductionChildList().stream() + .filter(productionChild -> productionChild.getOperNumber() > 0 + && productionChild.getProductionType() == ProductionChildType.OUTSOURCING.getKey()).collect(Collectors.toList())); + outputObject.setBean(production); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertProductionToWhole(InputObject inputObject, OutputObject outputObject) { + WholeOrderOut wholeOrderOut = inputObject.getParams(WholeOrderOut.class); + // 获取生产计划单状态 + Production order = selectById(wholeOrderOut.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转整单委外单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + wholeOrderOut.setFromId(wholeOrderOut.getId()); + wholeOrderOut.setFromTypeId(WholeOrderOutFromType.PRODUCTION.getKey()); + wholeOrderOut.setId(StrUtil.EMPTY); + wholeOrderOutService.createEntity(wholeOrderOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转整单委外单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/DeliveryPutState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/DeliveryPutState.java new file mode 100644 index 0000000..569c0a6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/DeliveryPutState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DeliveryPutState + * @Description: 采购到货单免检商品入库状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DeliveryPutState implements SkyeyeEnumClass { + + NOT_NEED_PUT(1, "无需入库", "purple", true, true), + NEED_PUT(2, "待入库", "blue", true, false), + PARTIAL_PUT(3, "部分入库", "orange", true, false), + COMPLATE_PUT(4, "全部入库", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/OrderArrivalState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/OrderArrivalState.java new file mode 100644 index 0000000..7481f13 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/OrderArrivalState.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OrderArrivalState + * @Description: 采购订单/整单委外单到货状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OrderArrivalState implements SkyeyeEnumClass { + + NOT_NEED_ARRIVAL(1, "无需到货", "purple", true, true), + NEED_ARRIVAL(2, "待到货", "blue", true, false), + PARTIAL_ARRIVAL(3, "部分到货", "orange", true, false), + COMPLATE_ARRIVAL(4, "全部到货", "green", true, false); + + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseDeliveryFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseDeliveryFromType.java new file mode 100644 index 0000000..c91ac5b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseDeliveryFromType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseDeliveryFromType + * @Description: 到货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseDeliveryFromType implements SkyeyeEnumClass { + + PURCHASE_ORDER(1, "采购订单", true, false), + WHOLE_ORDER_OUT(2, "整单委外单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseOrderFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseOrderFromType.java new file mode 100644 index 0000000..0fabba7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseOrderFromType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseOrderFromType + * @Description: 采购订单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseOrderFromType implements SkyeyeEnumClass { + + SUPPLIER_CONTRACT(1, "采购合同", true, false), + DELIVERY_PLAN(2, "出货计划", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchasePutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchasePutFromType.java new file mode 100644 index 0000000..d17af34 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchasePutFromType.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchasePutFromType + * @Description: 采购入库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchasePutFromType implements SkyeyeEnumClass { + + PURCHASE_ORDER(1, "采购订单", true, false), + QUALITY_INSPECTION(2, "质检单", true, false), + PURCHASE_DELIVERY(3, "到货单", true, false), + WHOLE_ORDER_OUT(4, "整单委外单", true, false); + + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseReturnsFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseReturnsFromType.java new file mode 100644 index 0000000..5df84aa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/classenum/PurchaseReturnsFromType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseReturnsFromType + * @Description: 采购退货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseReturnsFromType implements SkyeyeEnumClass { + + PURCHASE_ORDER(1, "采购订单", true, false), + QUALITY_INSPECTION(2, "质检单", true, false), + WHOLE_ORDER_OUT(3, "整单委外单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseDeliveryController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseDeliveryController.java new file mode 100644 index 0000000..765cb03 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseDeliveryController.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PurchaseDeliveryController + * @Description: 到货单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 22:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "到货单", tags = "到货单", modelName = "采购模块") +public class PurchaseDeliveryController { + + @Autowired + private PurchaseDeliveryService purchaseDeliveryService; + + /** + * 获取到货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseDeliveryList", value = "获取到货单列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PurchaseDeliveryController/queryPurchaseDeliveryList") + public void queryPurchaseDeliveryList(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑到货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePurchaseDelivery", value = "新增/编辑到货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseDelivery.class) + @RequestMapping("/post/PurchaseDeliveryController/writePurchaseDelivery") + public void writePurchaseDelivery(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转质检单时,根据id查询到货单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseDeliveryTransById", value = "转质检单时,根据id查询到货单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/queryPurchaseDeliveryTransById") + public void queryPurchaseDeliveryTransById(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.queryPurchaseDeliveryTransById(inputObject, outputObject); + } + + /** + * 到货单转质检单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deliveryToQualityInspection", value = "到货单转质检单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = QualityInspection.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/deliveryToQualityInspection") + public void deliveryToQualityInspection(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.deliveryToQualityInspection(inputObject, outputObject); + } + + /** + * 转采购入库单时,根据id查询到货单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseDeliveryTransPurchasePutById", value = "转采购入库单时,根据id查询到货单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/queryPurchaseDeliveryTransPurchasePutById") + public void queryPurchaseDeliveryTransPurchasePutById(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.queryPurchaseDeliveryTransPurchasePutById(inputObject, outputObject); + } + + /** + * 到货单转采购入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deliveryToPurchasePut", value = "到货单转采购入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchasePut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/deliveryToPurchasePut") + public void deliveryToPurchasePut(InputObject inputObject, OutputObject outputObject) { + purchaseDeliveryService.deliveryToPurchasePut(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseOrderController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseOrderController.java new file mode 100644 index 0000000..cd82604 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseOrderController.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PurchaseOrderController + * @Description: 采购订单管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/14 10:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "采购订单", tags = "采购订单", modelName = "采购模块") +public class PurchaseOrderController { + + @Autowired + private PurchaseOrderService purchaseOrderService; + + /** + * 获取采购订单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "purchaseorder001", value = "获取采购订单列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PurchaseOrderController/queryPurchaseOrderList") + public void queryPurchaseOrderToList(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑采购订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePurchaseOrder", value = "新增/编辑采购订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseOrder.class) + @RequestMapping("/post/PurchaseOrderController/writePurchaseOrder") + public void writePurchaseOrder(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转采购入库单/到货单/采购退货单时,根据id查询采购订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseOrderTransById", value = "转采购入库单/到货单/采购退货单时,根据id查询采购订单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseOrderController/queryPurchaseOrderTransById") + public void queryPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.queryPurchaseOrderTransById(inputObject, outputObject); + } + + /** + * 采购单信息转采购入库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "purchaseorder009", value = "采购单信息转采购入库", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchasePut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseOrderController/insertPurchaseOrderToTurnPut") + public void insertPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.insertPurchaseOrderToTurnPut(inputObject, outputObject); + } + + /** + * 采购订单信息转到货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPurchaseOrderToTurnDelivery", value = "采购订单信息转到货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseDelivery.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/insertPurchaseOrderToTurnDelivery") + public void insertPurchaseOrderToTurnDelivery(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.insertPurchaseOrderToTurnDelivery(inputObject, outputObject); + } + + /** + * 采购单信息转采购退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPurchaseOrderToReturns", value = "采购单信息转采购退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseOrderController/insertPurchaseOrderToReturns") + public void insertPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject) { + purchaseOrderService.insertPurchaseOrderToReturns(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchasePutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchasePutController.java new file mode 100644 index 0000000..1061298 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchasePutController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.service.PurchasePutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PurchasePutController + * @Description: 采购入库单控制类 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "采购入库单", tags = "采购入库单", modelName = "采购模块") +public class PurchasePutController { + + @Autowired + private PurchasePutService purchasePutService; + + /** + * 获取采购入库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "purchaseput001", value = "获取采购入库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PurchasePutController/queryPurchasePutList") + public void queryPurchasePutList(InputObject inputObject, OutputObject outputObject) { + purchasePutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑采购入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePurchasePut", value = "新增/编辑采购入库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchasePut.class) + @RequestMapping("/post/PurchasePutController/writePurchasePut") + public void writePurchasePut(InputObject inputObject, OutputObject outputObject) { + purchasePutService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询采购入库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchasePutTransById", value = "转仓库入库单时,根据id查询采购入库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchasePutController/queryPurchasePutTransById") + public void queryPurchasePutTransById(InputObject inputObject, OutputObject outputObject) { + purchasePutService.queryPurchasePutTransById(inputObject, outputObject); + } + + /** + * 采购入库单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPurchasePutToTurnDepot", value = "采购入库单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchasePutController/insertPurchasePutToTurnDepot") + public void insertPurchasePutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + purchasePutService.insertPurchasePutToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseReturnsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseReturnsController.java new file mode 100644 index 0000000..b5e811d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/controller/PurchaseReturnsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PurchaseReturnsController + * @Description: 采购退货单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "采购退货单", tags = "采购退货单", modelName = "采购模块") +public class PurchaseReturnsController { + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + /** + * 获取采购退货列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "purchasereturns001", value = "获取采购退货列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PurchaseReturnsController/queryPurchaseReturnsToList") + public void queryPurchaseReturnsToList(InputObject inputObject, OutputObject outputObject) { + purchaseReturnsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑采购退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePurchaseReturn", value = "新增/编辑采购退货信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseReturn.class) + @RequestMapping("/post/PurchaseReturnsController/writePurchaseReturn") + public void writePurchaseReturn(InputObject inputObject, OutputObject outputObject) { + purchaseReturnsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询采购退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseReturnsTransById", value = "转仓库出库单时,根据id查询采购退货信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseReturnsController/queryPurchaseReturnsTransById") + public void queryPurchaseReturnsTransById(InputObject inputObject, OutputObject outputObject) { + purchaseReturnsService.queryPurchaseReturnsTransById(inputObject, outputObject); + } + + /** + * 采购退货单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPurchaseReturnsToTurnDepot", value = "采购退货单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseReturnsController/insertPurchaseReturnsToTurnDepot") + public void insertPurchaseReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + purchaseReturnsService.insertPurchaseReturnsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseDeliveryDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseDeliveryDao.java new file mode 100644 index 0000000..6f5217d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseDeliveryDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.purchase.entity.PurchaseDelivery; + +/** + * @ClassName: PurchaseDeliveryDao + * @Description: 到货单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 20:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseDeliveryDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseOrderDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseOrderDao.java new file mode 100644 index 0000000..13188a0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.purchase.entity.PurchaseOrder; + +/** + * @ClassName: PurchaseOrderDao + * @Description: 采购订单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchasePutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchasePutDao.java new file mode 100644 index 0000000..3b95e80 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchasePutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.purchase.entity.PurchasePut; + +/** + * @ClassName: PurchasePutDao + * @Description: 采购入库单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchasePutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseReturnsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseReturnsDao.java new file mode 100644 index 0000000..c152142 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/dao/PurchaseReturnsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.purchase.entity.PurchaseReturn; + +/** + * @ClassName: PurchaseReturnsDao + * @Description: 采购退货单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseReturnsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseDelivery.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseDelivery.java new file mode 100644 index 0000000..7aa8305 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseDelivery.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: PurchaseDelivery + * @Description: 到货单实体类 + * --otherState:这里表示【采购到货单免检商品入库状态】参考#DeliveryPutState + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 20:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:delivery", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("到货单实体类") +public class PurchaseDelivery extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseOrder.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseOrder.java new file mode 100644 index 0000000..96fdef4 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseOrder.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: PurchaseOrder + * @Description: 采购订单实体类 + * --otherState:这里表示【采购订单到货状态】参考#OrderArrivalState + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:purchase", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("采购订单实体类") +public class PurchaseOrder extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchasePut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchasePut.java new file mode 100644 index 0000000..a2d4bcc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchasePut.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: PurchasePut + * @Description: 采购入库单实体类 + * --otherState:这里表示【采购入库单入库状态】参考#DepotPutState + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:purchasePut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("采购入库单实体类") +public class PurchasePut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseReturn.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseReturn.java new file mode 100644 index 0000000..25a2bb6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/entity/PurchaseReturn.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: PurchaseReturn + * @Description: 采购退货单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:purchaseReturn", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("采购退货单实体类") +public class PurchaseReturn extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseDeliveryService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseDeliveryService.java new file mode 100644 index 0000000..7d61db5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseDeliveryService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchaseDelivery; + +/** + * @ClassName: PurchaseDeliveryService + * @Description: 到货单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 20:49 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseDeliveryService extends SkyeyeErpOrderService { + + /** + * 修改质检状态 + * + * @param id 到货单id + * @param qualityInspection 质检状态 + */ + void editQualityInspection(String id, Integer qualityInspection); + + void deliveryToQualityInspection(InputObject inputObject, OutputObject outputObject); + + void queryPurchaseDeliveryTransById(InputObject inputObject, OutputObject outputObject); + + void deliveryToPurchasePut(InputObject inputObject, OutputObject outputObject); + + void queryPurchaseDeliveryTransPurchasePutById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseOrderService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseOrderService.java new file mode 100644 index 0000000..a3daac6 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseOrderService.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchaseOrder; + +import java.util.Map; + +/** + * @ClassName: PurchaseOrderService + * @Description: 采购订单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseOrderService extends SkyeyeErpOrderService { + + /** + * 采购单信息转采购入库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void insertPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject); + + /** + * 采购订单信息转到货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void insertPurchaseOrderToTurnDelivery(InputObject inputObject, OutputObject outputObject); + + /** + * 修改质检状态 + * + * @param id 采购订单id + * @param qualityInspection 质检状态 + */ + void editQualityInspection(String id, Integer qualityInspection); + + Map calcMaterialNormsNumByFromId(String fromId); + + void queryPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject); + + void insertPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchasePutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchasePutService.java new file mode 100644 index 0000000..d02d02c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchasePutService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchasePut; + +/** + * @ClassName: PurchasePutService + * @Description: 采购入库单管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchasePutService extends SkyeyeErpOrderService { + + void queryPurchasePutTransById(InputObject inputObject, OutputObject outputObject); + + void insertPurchasePutToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseReturnsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseReturnsService.java new file mode 100644 index 0000000..94fc3cc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/PurchaseReturnsService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchaseReturn; + +/** + * @ClassName: PurchaseReturnsService + * @Description: 采购退货单管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseReturnsService extends SkyeyeErpOrderService { + + void queryPurchaseReturnsTransById(InputObject inputObject, OutputObject outputObject); + + void insertPurchaseReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseDeliveryServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseDeliveryServiceImpl.java new file mode 100644 index 0000000..517891f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseDeliveryServiceImpl.java @@ -0,0 +1,391 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.classenum.OrderQualityInspectionType; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.inspection.classenum.QualityInspectionFromType; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.inspection.service.QualityInspectionService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.purchase.classenum.DeliveryPutState; +import com.skyeye.purchase.classenum.OrderArrivalState; +import com.skyeye.purchase.classenum.PurchaseDeliveryFromType; +import com.skyeye.purchase.classenum.PurchasePutFromType; +import com.skyeye.purchase.dao.PurchaseDeliveryDao; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PurchaseDeliveryServiceImpl + * @Description: 到货单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 22:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "到货单", groupName = "采购模块", flowable = true) +public class PurchaseDeliveryServiceImpl extends SkyeyeErpOrderServiceImpl implements PurchaseDeliveryService { + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private QualityInspectionService qualityInspectionService; + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private WholeOrderOutService wholeOrderOutService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseDelivery::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseDelivery::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置采购订单 + purchaseOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 设置整单委外单 + wholeOrderOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(PurchaseDelivery entity) { + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(PurchaseDelivery entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + setOtherMation(entity); + } + + @Override + public void updatePrepose(PurchaseDelivery entity) { + super.updatePrepose(entity); + setOtherMation(entity); + } + + @Override + public PurchaseDelivery selectById(String id) { + PurchaseDelivery purchaseDelivery = super.selectById(id); + if (purchaseDelivery.getFromTypeId() == PurchaseDeliveryFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + purchaseOrderService.setDataMation(purchaseDelivery, PurchaseDelivery::getFromId); + } else if (purchaseDelivery.getFromTypeId() == PurchaseDeliveryFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + wholeOrderOutService.setDataMation(purchaseDelivery, PurchaseDelivery::getFromId); + } + purchaseDelivery.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setQualityInspectionMation(OrderItemQualityInspectionType.getMation(erpOrderItem.getQualityInspection())); + }); + return purchaseDelivery; + } + + private static void setOtherMation(PurchaseDelivery entity) { + // 设置质检类型 + Integer qualityInspection = OrderQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + qualityInspection = setQualityInspection(erpOrderItem, qualityInspection); + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + } + entity.setQualityInspection(qualityInspection); + // 获取所有免检的商品 + List erpOrderItemList = entity.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() == OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + entity.setOtherState(DeliveryPutState.NOT_NEED_PUT.getKey()); + } else { + entity.setOtherState(DeliveryPutState.NEED_PUT.getKey()); + } + + } + + private void checkMaterialNorms(PurchaseDelivery entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前到货单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达到货单(审批通过)的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == PurchaseDeliveryFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + checkAndUpdatePurchaseOrderState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchaseDeliveryFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + checkAndUpdateWholeOrderOutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateWholeOrderOutState(PurchaseDelivery entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + WholeOrderOut wholeOrderOut = wholeOrderOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(wholeOrderOut.getErpOrderItemList())) { + throw new CustomException("该整单委外单下未包含商品."); + } + super.checkFromOrderMaterialNorms(wholeOrderOut.getErpOrderItemList(), inSqlNormsId); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经到货的商品数量 + super.setOrCheckOperNumber(wholeOrderOut.getErpOrderItemList(), setData, orderNormsNum, executeNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = wholeOrderOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该整单委外单的商品已经全部下达了到货单,那说明已经完成了订单的【到货内容】 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + wholeOrderOutService.editArrivalState(wholeOrderOut.getId(), OrderArrivalState.COMPLATE_ARRIVAL.getKey()); + } else { + wholeOrderOutService.editArrivalState(wholeOrderOut.getId(), OrderArrivalState.PARTIAL_ARRIVAL.getKey()); + } + } + } + + private void checkAndUpdatePurchaseOrderState(PurchaseDelivery entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + PurchaseOrder purchaseOrder = purchaseOrderService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(purchaseOrder.getErpOrderItemList())) { + throw new CustomException("该采购订单下未包含商品."); + } + super.checkFromOrderMaterialNorms(purchaseOrder.getErpOrderItemList(), inSqlNormsId); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经到货的商品数量 + super.setOrCheckOperNumber(purchaseOrder.getErpOrderItemList(), setData, orderNormsNum, executeNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = purchaseOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该订单的商品已经全部下达了到货单,那说明已经完成了订单的【到货内容】 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseOrderService.editOtherState(purchaseOrder.getId(), OrderArrivalState.COMPLATE_ARRIVAL.getKey()); + } else { + purchaseOrderService.editOtherState(purchaseOrder.getId(), OrderArrivalState.PARTIAL_ARRIVAL.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(PurchaseDelivery entity) { + entity = selectById(entity.getId()); + checkMaterialNorms(entity, true); + } + + @Override + public void editQualityInspection(String id, Integer qualityInspection) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(PurchaseDelivery::getQualityInspection), qualityInspection); + update(updateWrapper); + refreshCache(id); + // 设置父节点质检状态 + PurchaseDelivery purchaseDelivery = selectById(id); + if (StrUtil.isEmpty(purchaseDelivery.getFromId())) { + return; + } + // 获取同一个单据下的所有已经质检的商品数量 + Map qualityInspectionNumMap = queryDeliveryQualityNumByParentId(purchaseDelivery.getFromId()); + if (purchaseDelivery.getFromTypeId() == PurchaseDeliveryFromType.PURCHASE_ORDER.getKey()) { + // 来源-采购订单 + PurchaseOrder purchaseOrder = purchaseOrderService.selectById(purchaseDelivery.getFromId()); + // 过滤掉【采购订单】中免检的商品 + List erpOrderItemList = purchaseOrder.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() != OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = erpOrderItem.getOperNumber() + - (qualityInspectionNumMap.containsKey(erpOrderItem.getNormsId()) ? qualityInspectionNumMap.get(erpOrderItem.getNormsId()) : 0); + erpOrderItem.setOperNumber(surplusNum); + }); + // 过滤掉剩余数量为0的商品 + erpOrderItemList = erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 该采购订单的商品已经全部进行了质检 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseOrderService.editQualityInspection(purchaseDelivery.getFromId(), OrderQualityInspectionType.COMPLATE_QUALITY_INSPECTION.getKey()); + } else { + purchaseOrderService.editQualityInspection(purchaseDelivery.getFromId(), OrderQualityInspectionType.PARTIAL_QUALITY_INSPECTION.getKey()); + } + } else if (purchaseDelivery.getFromTypeId() == PurchaseDeliveryFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + WholeOrderOut wholeOrderOut = wholeOrderOutService.selectById(purchaseDelivery.getFromId()); + // 过滤掉【整单委外单】中免检的商品 + List erpOrderItemList = wholeOrderOut.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() != OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = erpOrderItem.getOperNumber() + - (qualityInspectionNumMap.containsKey(erpOrderItem.getNormsId()) ? qualityInspectionNumMap.get(erpOrderItem.getNormsId()) : 0); + erpOrderItem.setOperNumber(surplusNum); + }); + // 过滤掉剩余数量为0的商品 + erpOrderItemList = erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 该整单委外单的商品已经全部进行了质检 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + wholeOrderOutService.editQualityInspection(purchaseDelivery.getFromId(), OrderQualityInspectionType.COMPLATE_QUALITY_INSPECTION.getKey()); + } else { + wholeOrderOutService.editQualityInspection(purchaseDelivery.getFromId(), OrderQualityInspectionType.PARTIAL_QUALITY_INSPECTION.getKey()); + } + } + } + + /** + * 获取采购订单下所有已经质检的商品 + * + * @param parentId 采购订单id + * @return + */ + private Map queryDeliveryQualityNumByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseDelivery::getFromId), parentId); + // 只查询审批通过 && 已经质检(部分质检/质检完成) 的到货单 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(PurchaseDelivery::getState), stateList); + List qualityInspectionList = Arrays.asList(new Integer[]{OrderQualityInspectionType.PARTIAL_QUALITY_INSPECTION.getKey(), + OrderQualityInspectionType.COMPLATE_QUALITY_INSPECTION.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(PurchaseDelivery::getQualityInspection), qualityInspectionList); + List purchaseOrderList = list(queryWrapper); + // 获取所有到货单id + List purchaseDeliveryIdList = purchaseOrderList.stream().map(PurchaseDelivery::getId).collect(Collectors.toList()); + // 获取到货单下所有已经质检的商品数量 + return qualityInspectionService.calcMaterialNormsNumByFromId(purchaseDeliveryIdList.toArray(new String[]{})); + } + + @Override + public void queryPurchaseDeliveryTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PurchaseDelivery purchaseDelivery = selectById(id); + Map normsNum = qualityInspectionService.calcMaterialNormsNumByFromId(id); + // 过滤掉【采购到货单】中免检的商品 + List erpOrderItemList = purchaseDelivery.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() != OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = erpOrderItem.getOperNumber() + - (normsNum.containsKey(erpOrderItem.getNormsId()) ? normsNum.get(erpOrderItem.getNormsId()) : 0); + // 设置未下达质检单的商品数量 + erpOrderItem.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成质检单 + purchaseDelivery.setErpOrderItemList(erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(purchaseDelivery); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void deliveryToQualityInspection(InputObject inputObject, OutputObject outputObject) { + QualityInspection qualityInspection = inputObject.getParams(QualityInspection.class); + // 获取到货单状态 + PurchaseDelivery purchaseDelivery = selectById(qualityInspection.getId()); + if (ObjectUtil.isEmpty(purchaseDelivery)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的并且需要质检的可以进行质检单 + if (FlowableStateEnum.PASS.getKey().equals(purchaseDelivery.getState()) && + (purchaseDelivery.getQualityInspection() == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey() + || purchaseDelivery.getQualityInspection() == OrderQualityInspectionType.PARTIAL_QUALITY_INSPECTION.getKey())) { + String userId = inputObject.getLogParams().get("id").toString(); + qualityInspection.setFromId(qualityInspection.getId()); + qualityInspection.setFromTypeId(QualityInspectionFromType.PURCHASE_DELIVERY.getKey()); + qualityInspection.setId(StrUtil.EMPTY); + qualityInspectionService.createEntity(qualityInspection, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达质检单."); + } + } + + @Override + public void queryPurchaseDeliveryTransPurchasePutById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PurchaseDelivery purchaseDelivery = selectById(id); + Map normsNum = purchasePutService.calcMaterialNormsNumByFromId(id); + // 获取【采购到货单】中免检的商品 + List erpOrderItemList = purchaseDelivery.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() == OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + erpOrderItemList.forEach(erpOrderItem -> { + Integer surplusNum = erpOrderItem.getOperNumber() + - (normsNum.containsKey(erpOrderItem.getNormsId()) ? normsNum.get(erpOrderItem.getNormsId()) : 0); + // 设置未下达采购入库单的商品数量 + erpOrderItem.setOperNumber(surplusNum); + }); + // 过滤掉数量为0的进行生成采购入库单 + purchaseDelivery.setErpOrderItemList(erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(purchaseDelivery); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void deliveryToPurchasePut(InputObject inputObject, OutputObject outputObject) { + PurchasePut purchasePut = inputObject.getParams(PurchasePut.class); + // 获取到货单状态 + PurchaseDelivery purchaseDelivery = selectById(purchasePut.getId()); + if (ObjectUtil.isEmpty(purchaseDelivery)) { + throw new CustomException("该数据不存在."); + } + // 【审核通过】的并且【免检商品入库状态为待入库,部分入库】的可以进行采购入库 + if (FlowableStateEnum.PASS.getKey().equals(purchaseDelivery.getState()) && + (purchaseDelivery.getOtherState() == DeliveryPutState.NEED_PUT.getKey() + || purchaseDelivery.getOtherState() == DeliveryPutState.PARTIAL_PUT.getKey())) { + String userId = inputObject.getLogParams().get("id").toString(); + purchasePut.setFromId(purchasePut.getId()); + purchasePut.setFromTypeId(PurchasePutFromType.PURCHASE_DELIVERY.getKey()); + purchasePut.setId(StrUtil.EMPTY); + purchasePutService.createEntity(purchasePut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法转采购入库单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseOrderServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseOrderServiceImpl.java new file mode 100644 index 0000000..df5c88b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseOrderServiceImpl.java @@ -0,0 +1,369 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.classenum.OrderQualityInspectionType; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.classenum.SupplierContractChildStateEnum; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.contract.entity.SupplierContractChild; +import com.skyeye.contract.service.SupplierContractService; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialFromType; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.production.classenum.ProductionPlanPurchaseState; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.production.entity.ProductionPlanChild; +import com.skyeye.production.service.ProductionPlanService; +import com.skyeye.purchase.classenum.*; +import com.skyeye.purchase.dao.PurchaseOrderDao; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: PurchaseOrderServiceImpl + * @Description: 采购订单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购订单", groupName = "采购模块", flowable = true) +public class PurchaseOrderServiceImpl extends SkyeyeErpOrderServiceImpl implements PurchaseOrderService { + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private PurchaseDeliveryService purchaseDeliveryService; + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + @Autowired + private SupplierContractService supplierContractService; + + @Autowired + private ProductionPlanService productionPlanService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseOrder::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseOrder::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public void validatorEntity(PurchaseOrder entity) { + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(PurchaseOrder entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + setOtherMation(entity); + } + + @Override + public void updatePrepose(PurchaseOrder entity) { + super.updatePrepose(entity); + setOtherMation(entity); + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + supplierContractService.setContractMationByFromId(beans, "fromId", "fromMation"); + productionPlanService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + private static void setOtherMation(PurchaseOrder entity) { + // 设置质检类型 + Integer qualityInspection = OrderQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + qualityInspection = setQualityInspection(erpOrderItem, qualityInspection); + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + } + entity.setQualityInspection(qualityInspection); + // 设置到货状态 + if (qualityInspection == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + // 如果需要质检,则需要先下【到货单】 + entity.setOtherState(OrderArrivalState.NEED_ARRIVAL.getKey()); + } else { + entity.setOtherState(OrderArrivalState.NOT_NEED_ARRIVAL.getKey()); + } + } + + private void checkMaterialNorms(PurchaseOrder entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前采购订单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达采购订单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == PurchaseOrderFromType.SUPPLIER_CONTRACT.getKey()) { + // 采购合同 + checkAndUpdateSupplierContractState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchaseOrderFromType.DELIVERY_PLAN.getKey()) { + // 到货计划 + checkAndUpdateDeliveryPlanState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateSupplierContractState(PurchaseOrder entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + SupplierContract supplierContract = supplierContractService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(supplierContract.getSupplierContractChildList())) { + throw new CustomException("该采购合同下未包含商品."); + } + List fromNormsIds = supplierContract.getSupplierContractChildList().stream() + .map(SupplierContractChild::getNormsId).collect(Collectors.toList()); + + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + supplierContract.getSupplierContractChildList().forEach(supplierContractChild -> { + // 合同数量 - 当前采购订单的数量 - 已经下达采购订单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(supplierContractChild.getOperNumber(), supplierContractChild.getNormsId(), + orderNormsNum, executeNum); + if (setData) { + supplierContractChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List supplierContractChildList = supplierContract.getSupplierContractChildList().stream() + .filter(supplierContractChild -> supplierContractChild.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该合同的商品已经全部下达订单,那说明已经完成了合同的内容 + if (CollectionUtil.isEmpty(supplierContractChildList)) { + supplierContractService.editChildState(supplierContract.getId(), SupplierContractChildStateEnum.ALL_ISSUED.getKey()); + } else { + supplierContractService.editChildState(supplierContract.getId(), SupplierContractChildStateEnum.PARTIAL_RELEASE.getKey()); + } + } + } + + private void checkAndUpdateDeliveryPlanState(PurchaseOrder entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + ProductionPlan productionPlan = productionPlanService.selectById(entity.getFromId()); + // 只查询外购商品 + List productionPlanChildList = productionPlan.getProductionPlanChildList().stream() + .filter(productionPlanChild -> productionPlanChild.getMaterialMation().getFromType() == MaterialFromType.OUTSOURCING.getKey()) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(productionPlanChildList)) { + throw new CustomException("该到货计划单下未包含外购商品."); + } + List fromNormsIds = productionPlanChildList.stream() + .map(ProductionPlanChild::getNormsId).collect(Collectors.toList()); + + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + productionPlanChildList.forEach(productionPlanChild -> { + // 到货计划单的数量 - 当前采购订单的数量 - 已经下达采购订单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(productionPlanChild.getOperNumber(), productionPlanChild.getNormsId(), + orderNormsNum, executeNum); + if (setData) { + productionPlanChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + productionPlanChildList = productionPlanChildList.stream() + .filter(productionPlanChild -> productionPlanChild.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该合同的商品已经全部下达订单,那说明已经完成了合同的内容 + if (CollectionUtil.isEmpty(productionPlanChildList)) { + productionPlanService.editPurchaseState(productionPlan.getId(), ProductionPlanPurchaseState.COMPLATE.getKey()); + } else { + productionPlanService.editPurchaseState(productionPlan.getId(), ProductionPlanPurchaseState.PARTIAL.getKey()); + } + } + } + + @Override + public Map calcMaterialNormsNumByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseOrder::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseOrder::getIdKey), getServiceClassName()); + // 只查询审批通过,部分入库,已完成的采购订单 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(PurchaseOrder::getState), stateList); + List purchaseOrderList = list(queryWrapper); + List ids = purchaseOrderList.stream().map(PurchaseOrder::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + // 获取所有的商品信息 + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + if (CollectionUtil.isNotEmpty(erpOrderItemList)) { + // 分组计算已经下达订单的数量 + return erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.summingInt(ErpOrderItem::getOperNumber))); + } + return MapUtil.newHashMap(); + } + + @Override + public PurchaseOrder selectById(String id) { + PurchaseOrder purchaseOrder = super.selectById(id); + if (purchaseOrder.getFromTypeId() == PurchaseOrderFromType.SUPPLIER_CONTRACT.getKey()) { + // 采购合同 + supplierContractService.setDataMation(purchaseOrder, PurchaseOrder::getFromId); + } else if (purchaseOrder.getFromTypeId() == PurchaseOrderFromType.DELIVERY_PLAN.getKey()) { + // 到货计划 + productionPlanService.setDataMation(purchaseOrder, PurchaseOrder::getFromId); + } + purchaseOrder.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setQualityInspectionMation(OrderItemQualityInspectionType.getMation(erpOrderItem.getQualityInspection())); + }); + return purchaseOrder; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPurchaseOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + PurchasePut purchasePut = inputObject.getParams(PurchasePut.class); + // 获取采购单状态 + PurchaseOrder order = selectById(purchasePut.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以进行入库 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + if (order.getQualityInspection() == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + throw new CustomException("该订单需要进行质检,无法直接转采购入库,请先转【到货单】."); + } + String userId = inputObject.getLogParams().get("id").toString(); + purchasePut.setFromId(purchasePut.getId()); + purchasePut.setFromTypeId(PurchasePutFromType.PURCHASE_ORDER.getKey()); + purchasePut.setId(StrUtil.EMPTY); + purchasePutService.createEntity(purchasePut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购入库单."); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPurchaseOrderToTurnDelivery(InputObject inputObject, OutputObject outputObject) { + PurchaseDelivery purchaseDelivery = inputObject.getParams(PurchaseDelivery.class); + // 获取采购单状态 + PurchaseOrder order = selectById(purchaseDelivery.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到货单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + if (order.getQualityInspection() == OrderQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) { + throw new CustomException("该订单无需进行质检,请直接转采购入库."); + } + String userId = inputObject.getLogParams().get("id").toString(); + purchaseDelivery.setFromId(purchaseDelivery.getId()); + purchaseDelivery.setFromTypeId(PurchaseDeliveryFromType.PURCHASE_ORDER.getKey()); + purchaseDelivery.setId(StrUtil.EMPTY); + purchaseDeliveryService.createEntity(purchaseDelivery, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达到货单."); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPurchaseOrderToReturns(InputObject inputObject, OutputObject outputObject) { + PurchaseReturn purchaseReturn = inputObject.getParams(PurchaseReturn.class); + // 获取采购单状态 + PurchaseOrder order = selectById(purchaseReturn.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到采购退货单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + purchaseReturn.setFromId(purchaseReturn.getId()); + purchaseReturn.setFromTypeId(PurchaseReturnsFromType.PURCHASE_ORDER.getKey()); + purchaseReturn.setId(StrUtil.EMPTY); + purchaseReturnsService.createEntity(purchaseReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购退货单."); + } + } + + @Override + public void approvalEndIsSuccess(PurchaseOrder entity) { + entity = selectById(entity.getId()); + checkMaterialNorms(entity, true); + } + + @Override + public void queryPurchaseOrderTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PurchaseOrder purchaseOrder = selectById(id); + // 该采购订单下的已经下达采购退货单(审核通过)的数量 + Map normsReturnMap = purchaseReturnsService.calcMaterialNormsNumByFromId(purchaseOrder.getId()); + if (purchaseOrder.getQualityInspection() == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + // 需要质检,计算未到货数量 + Map normsNum = purchaseDeliveryService.calcMaterialNormsNumByFromId(id); + // 设置未下达到货单的商品数量-----采购订单数量 - 已到货数量 - 已退货数量 + super.setOrCheckOperNumber(purchaseOrder.getErpOrderItemList(), true, normsNum, normsReturnMap); + } else { + // 免检,计算未入库的数量 + Map normsNum = purchasePutService.calcMaterialNormsNumByFromId(id); + // 设置未下达采购入库单的商品数量-----采购订单数量 - 已入库数量 - 已退货数量 + super.setOrCheckOperNumber(purchaseOrder.getErpOrderItemList(), true, normsNum, normsReturnMap); + } + // 过滤掉数量为0的进行生成采购入库单/到货单/退货单 + purchaseOrder.setErpOrderItemList(purchaseOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(purchaseOrder); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void editQualityInspection(String id, Integer qualityInspection) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(PurchaseOrder::getQualityInspection), qualityInspection); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchasePutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchasePutServiceImpl.java new file mode 100644 index 0000000..63eab7d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchasePutServiceImpl.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.inspection.classenum.QualityInspectionPutState; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.inspection.entity.QualityInspectionItem; +import com.skyeye.inspection.service.QualityInspectionService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.purchase.classenum.DeliveryPutState; +import com.skyeye.purchase.classenum.PurchasePutFromType; +import com.skyeye.purchase.dao.PurchasePutDao; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.util.ErpOrderUtil; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PurchasePutServiceImpl + * @Description: 采购入库单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购入库单", groupName = "采购模块", flowable = true) +public class PurchasePutServiceImpl extends SkyeyeErpOrderServiceImpl implements PurchasePutService { + + @Autowired + private QualityInspectionService qualityInspectionService; + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + @Autowired + private PurchaseDeliveryService purchaseDeliveryService; + + @Autowired + private WholeOrderOutService wholeOrderOutService; + + @Autowired + private DepotPutService depotPutService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置采购订单 + purchaseOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 设置质检订单 + qualityInspectionService.setQualityInspectionMationByFromId(beans, "fromId", "fromMation"); + // 设置到货单 + purchaseDeliveryService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 设置整单委外单 + wholeOrderOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(PurchasePut entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(PurchasePut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public PurchasePut selectById(String id) { + PurchasePut purchasePut = super.selectById(id); + if (purchasePut.getFromTypeId() == PurchasePutFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + purchaseOrderService.setDataMation(purchasePut, PurchasePut::getFromId); + } else if (purchasePut.getFromTypeId() == PurchasePutFromType.QUALITY_INSPECTION.getKey()) { + // 质检单 + qualityInspectionService.setDataMation(purchasePut, PurchasePut::getFromId); + } else if (purchasePut.getFromTypeId() == PurchasePutFromType.PURCHASE_DELIVERY.getKey()) { + // 到货单 + purchaseDeliveryService.setDataMation(purchasePut, PurchasePut::getFromId); + } else if (purchasePut.getFromTypeId() == PurchasePutFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + wholeOrderOutService.setDataMation(purchasePut, PurchasePut::getFromId); + } + + return purchasePut; + } + + private void checkMaterialNorms(PurchasePut entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前采购入库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达采购入库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == PurchasePutFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + checkAndUpdatePurchaseOrderState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchasePutFromType.QUALITY_INSPECTION.getKey()) { + // 质检单 + checkAndUpdateQualityInspectionPutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchasePutFromType.PURCHASE_DELIVERY.getKey()) { + // 到货单 + checkAndUpdatePurchaseDeliveryPutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchasePutFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + checkAndUpdateWholeOrderOutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateWholeOrderOutState(PurchasePut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + WholeOrderOut wholeOrderOut = wholeOrderOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(wholeOrderOut.getErpOrderItemList())) { + throw new CustomException("该整单委外单下未包含商品."); + } + // 获取所有免检的商品进行采购入库 + List erpOrderItemList = wholeOrderOut.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() == OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + throw new CustomException("该整单委外单未包含需要免检的商品,请走质检流程"); + } + super.checkFromOrderMaterialNorms(erpOrderItemList, inSqlNormsId); + // 获取已经下达采购退货单的商品信息 + Map returnExecuteNum = purchaseReturnsService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 - 已经退货的商品数量 + super.setOrCheckOperNumber(erpOrderItemList, setData, orderNormsNum, executeNum, returnExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + erpOrderItemList = erpOrderItemList.stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该整单委外单的商品(免检)已经全部生成了采购入库单,那说明已经完成了整单委外单的入库内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + wholeOrderOutService.editStateById(wholeOrderOut.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + wholeOrderOutService.editStateById(wholeOrderOut.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + private void checkAndUpdatePurchaseDeliveryPutState(PurchasePut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + PurchaseDelivery purchaseDelivery = purchaseDeliveryService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(purchaseDelivery.getErpOrderItemList())) { + throw new CustomException("该到货单下未包含商品."); + } + // 获取所有免检的商品进行采购入库 + List erpOrderItemList = purchaseDelivery.getErpOrderItemList().stream() + .filter(bean -> bean.getQualityInspection() == OrderItemQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + throw new CustomException("该到货单下未包含需要免检的商品,请走质检流程"); + } + super.checkFromOrderMaterialNorms(erpOrderItemList, inSqlNormsId); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 + super.setOrCheckOperNumber(erpOrderItemList, setData, orderNormsNum, executeNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + erpOrderItemList = erpOrderItemList.stream() + .filter(qualityInspectionItem -> qualityInspectionItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该到货单的商品(免检)已经全部生成了采购入库单,那说明已经完成了到货单的入库内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseDeliveryService.editOtherState(purchaseDelivery.getId(), DeliveryPutState.COMPLATE_PUT.getKey()); + } else { + purchaseDeliveryService.editOtherState(purchaseDelivery.getId(), DeliveryPutState.PARTIAL_PUT.getKey()); + } + } + } + + private void checkAndUpdateQualityInspectionPutState(PurchasePut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + QualityInspection qualityInspection = qualityInspectionService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(qualityInspection.getQualityInspectionItemList())) { + throw new CustomException("该质检单下未包含商品."); + } + List fromNormsIds = qualityInspection.getQualityInspectionItemList().stream() + .map(QualityInspectionItem::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + // 合格数量 + 让步接收数量 - 当前订单数量 - 采购入库单的数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(qualityInspectionItem.getQualifiedNumber() + qualityInspectionItem.getConcessionNumber(), + qualityInspectionItem.getNormsId(), orderNormsNum, executeNum); + if (setData) { + qualityInspectionItem.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List qualityInspectionItemList = qualityInspection.getQualityInspectionItemList().stream() + .filter(qualityInspectionItem -> qualityInspectionItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该质检单的商品已经全部生成了采购入库单,那说明已经完成了质检单的内容 + if (CollectionUtil.isEmpty(qualityInspectionItemList)) { + qualityInspectionService.editPutState(qualityInspection.getId(), QualityInspectionPutState.COMPLATE_PUT.getKey()); + } else { + qualityInspectionService.editPutState(qualityInspection.getId(), QualityInspectionPutState.PARTIAL_PUT.getKey()); + } + } + } + + private void checkAndUpdatePurchaseOrderState(PurchasePut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + PurchaseOrder purchaseOrder = purchaseOrderService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(purchaseOrder.getErpOrderItemList())) { + throw new CustomException("该采购订单下未包含商品."); + } + super.checkFromOrderMaterialNorms(purchaseOrder.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达采购退货单的商品信息 + Map returnExecuteNum = purchaseReturnsService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经入库的商品数量 - 已经退货的商品数量 + super.setOrCheckOperNumber(purchaseOrder.getErpOrderItemList(), setData, orderNormsNum, executeNum, returnExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = purchaseOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该采购订单的商品已经全部生成了采购入库单,那说明已经完成了采购订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseOrderService.editStateById(purchaseOrder.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + purchaseOrderService.editStateById(purchaseOrder.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(PurchasePut entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void queryPurchasePutTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PurchasePut purchasePut = selectById(id); + // 该采购入库单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(purchasePut.getId()); + // 设置未下达商品数量-----采购入库单数量 - 已入库数量 + super.setOrCheckOperNumber(purchasePut.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + purchasePut.setErpOrderItemList(purchasePut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(purchasePut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertPurchasePutToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取采购入库单状态 + PurchasePut purchasePut = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(purchasePut)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(purchasePut.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.PURCHASE_PUT.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseReturnsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseReturnsServiceImpl.java new file mode 100644 index 0000000..245ef98 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/purchase/service/impl/PurchaseReturnsServiceImpl.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.purchase.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.inspection.classenum.QualityInspectionReturnState; +import com.skyeye.inspection.entity.QualityInspection; +import com.skyeye.inspection.entity.QualityInspectionItem; +import com.skyeye.inspection.service.QualityInspectionService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.purchase.classenum.PurchaseReturnsFromType; +import com.skyeye.purchase.dao.PurchaseReturnsDao; +import com.skyeye.purchase.entity.PurchaseOrder; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseOrderService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.util.ErpOrderUtil; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PurchaseReturnsServiceImpl + * @Description: 采购退货单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购退货单", groupName = "采购模块", flowable = true) +public class PurchaseReturnsServiceImpl extends SkyeyeErpOrderServiceImpl implements PurchaseReturnsService { + + @Autowired + private QualityInspectionService qualityInspectionService; + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private WholeOrderOutService wholeOrderOutService; + + @Autowired + private DepotOutService depotOutService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置采购订单 + purchaseOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 设置质检订单 + qualityInspectionService.setQualityInspectionMationByFromId(beans, "fromId", "fromMation"); + // 设置整单委外单 + wholeOrderOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(PurchaseReturn entity) { + if (entity.getNeedDepot() == WhetherEnum.ENABLE_USING.getKey()) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + } else { + entity.setOtherState(DepotOutState.NOT_NEED_OUT.getKey()); + } + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(PurchaseReturn entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public PurchaseReturn selectById(String id) { + PurchaseReturn purchaseReturn = super.selectById(id); + if (purchaseReturn.getFromTypeId() == PurchaseReturnsFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + purchaseOrderService.setDataMation(purchaseReturn, PurchaseReturn::getFromId); + } else if (purchaseReturn.getFromTypeId() == PurchaseReturnsFromType.QUALITY_INSPECTION.getKey()) { + // 质检单 + qualityInspectionService.setDataMation(purchaseReturn, PurchaseReturn::getFromId); + } else if (purchaseReturn.getFromTypeId() == PurchaseReturnsFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + wholeOrderOutService.setDataMation(purchaseReturn, PurchaseReturn::getFromId); + } + return purchaseReturn; + } + + private void checkMaterialNorms(PurchaseReturn entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前采购退货单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达采购退货单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == PurchaseReturnsFromType.PURCHASE_ORDER.getKey()) { + // 采购订单 + checkAndUpdatePurchaseOrderState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchaseReturnsFromType.QUALITY_INSPECTION.getKey()) { + // 质检单 + checkAndUpdateQualityInspectionPutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } else if (entity.getFromTypeId() == PurchaseReturnsFromType.WHOLE_ORDER_OUT.getKey()) { + // 整单委外单 + checkAndUpdateWholeOrderOutState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateWholeOrderOutState(PurchaseReturn entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + WholeOrderOut wholeOrderOut = wholeOrderOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(wholeOrderOut.getErpOrderItemList())) { + throw new CustomException("该整单委外单下未包含商品."); + } + super.checkFromOrderMaterialNorms(wholeOrderOut.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达采购入库单的商品信息 + Map putExecuteNum = purchasePutService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经退货的商品数量 - 已经入库的商品数量 + super.setOrCheckOperNumber(wholeOrderOut.getErpOrderItemList(), setData, orderNormsNum, executeNum, putExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = wholeOrderOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该整单委外单的商品(免检)已经全部退货完成,那说明已经完成了整单委外单的入库内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + wholeOrderOutService.editStateById(wholeOrderOut.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + wholeOrderOutService.editStateById(wholeOrderOut.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + private void checkAndUpdateQualityInspectionPutState(PurchaseReturn entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + QualityInspection qualityInspection = qualityInspectionService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(qualityInspection.getQualityInspectionItemList())) { + throw new CustomException("该质检单下未包含商品."); + } + List fromNormsIds = qualityInspection.getQualityInspectionItemList().stream() + .map(QualityInspectionItem::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + qualityInspection.getQualityInspectionItemList().forEach(qualityInspectionItem -> { + // 验收退回的商品数量 - 当前单据的商品数量 - 已经退货的商品数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(qualityInspectionItem.getReturnNumber(), + qualityInspectionItem.getNormsId(), orderNormsNum, executeNum); + if (setData) { + qualityInspectionItem.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + List qualityInspectionItemList = qualityInspection.getQualityInspectionItemList().stream() + .filter(qualityInspectionItem -> qualityInspectionItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该质检单的商品已经退货完成,那说明已经完成了质检单的内容 + if (CollectionUtil.isEmpty(qualityInspectionItemList)) { + qualityInspectionService.editReturnState(qualityInspection.getId(), QualityInspectionReturnState.COMPLATE_RETURN.getKey()); + } else { + qualityInspectionService.editReturnState(qualityInspection.getId(), QualityInspectionReturnState.PARTIAL_RETURN.getKey()); + } + } + } + + private void checkAndUpdatePurchaseOrderState(PurchaseReturn entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + PurchaseOrder purchaseOrder = purchaseOrderService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(purchaseOrder.getErpOrderItemList())) { + throw new CustomException("该采购订单下未包含商品."); + } + super.checkFromOrderMaterialNorms(purchaseOrder.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达采购入库单的商品信息 + Map putExecuteNum = purchasePutService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经退货的商品数量 - 已经入库的商品数量 + super.setOrCheckOperNumber(purchaseOrder.getErpOrderItemList(), setData, orderNormsNum, executeNum, putExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = purchaseOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该采购订单的商品已经退货完成,那说明已经完成了采购订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + purchaseOrderService.editStateById(purchaseOrder.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + purchaseOrderService.editStateById(purchaseOrder.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(PurchaseReturn entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void queryPurchaseReturnsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + PurchaseReturn purchaseReturn = selectById(id); + if (purchaseReturn.getNeedDepot() == WhetherEnum.DISABLE_USING.getKey()) { + throw new CustomException("该采购退货单无需进行转出库操作"); + } + // 该采购退货单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(purchaseReturn.getId()); + // 设置未下达商品数量-----采购退货单数量 - 已出库数量 + super.setOrCheckOperNumber(purchaseReturn.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + purchaseReturn.setErpOrderItemList(purchaseReturn.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(purchaseReturn); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertPurchaseReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取采购退货单状态 + PurchaseReturn purchaseReturn = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(purchaseReturn)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(purchaseReturn.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.PURCHASE_RETURNS.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestChildInquiry.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestChildInquiry.java new file mode 100644 index 0000000..3c77cc0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestChildInquiry.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: PurchaseRequestChildInquiry + * @Description: 采购申请子单据是否询价的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 16:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseRequestChildInquiry implements SkyeyeEnumClass { + + NOT_INQUIRY(1, "无需询价", true, true), + INQUIRY(2, "询价", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getName(Integer type) { + for (PurchaseRequestChildInquiry bean : PurchaseRequestChildInquiry.values()) { + if (type == bean.getKey()) { + return bean.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestFromType.java new file mode 100644 index 0000000..aaf6fd7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseRequestFromType + * @Description: 采购申请单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseRequestFromType implements SkyeyeEnumClass { + + PRODUCTION(1, "生产订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestInquiryState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestInquiryState.java new file mode 100644 index 0000000..dff90be --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestInquiryState.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PurchaseRequestInquiry + * @Description: 采购申请单询价状态的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/21 16:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseRequestInquiryState implements SkyeyeEnumClass { + + NOT_INQUIRY(1, "无需询价", "purple", true, true), + WAIT_INQUIRY(2, "待询价", "blue", true, false), + INQUIRYING(3, "询价中", "orange", true, false), + COMPLATE_INQUIRY(4, "询价完毕", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestStateEnum.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestStateEnum.java new file mode 100644 index 0000000..64dd492 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/classenum/PurchaseRequestStateEnum.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: PurchaseRequestStateEnum + * @Description: 采购申请状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PurchaseRequestStateEnum implements SkyeyeEnumClass { + + PARTIAL_PROCUREMENT("partialProcurement", "部分采购合同", true, false), + PROCUREMENT_COMPLETED("procurementCompleted", "采购合同完毕", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/controller/PurchaseRequestController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/controller/PurchaseRequestController.java new file mode 100644 index 0000000..522f244 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/controller/PurchaseRequestController.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.request.entity.PurchaseRequest; +import com.skyeye.request.service.PurchaseRequestService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PurchaseRequestController + * @Description: 采购申请控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "采购申请", tags = "采购申请", modelName = "采购申请") +public class PurchaseRequestController { + + @Autowired + private PurchaseRequestService purchaseRequestService; + + /** + * 获取采购申请信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPurchaseRequestList", value = "获取采购申请信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PurchaseRequestController/queryPurchaseRequestList") + public void queryPurchaseRequestList(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePurchaseRequest", value = "新增/编辑采购申请", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseRequest.class) + @RequestMapping("/post/PurchaseRequestController/writePurchaseRequest") + public void writePurchaseRequest(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 采购申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitPurchaseRequestToApproval", value = "采购申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/PurchaseRequestController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePurchaseRequest", value = "删除采购申请", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseRequestController/deletePurchaseRequest") + public void invalid(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.deleteById(inputObject, outputObject); + } + + /** + * 撤销采购申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokePurchaseRequest", value = "撤销采购申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/PurchaseRequestController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.revoke(inputObject, outputObject); + } + + /** + * 采购申请询价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inquiryPurchaseRequest", value = "采购申请询价", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "purchaseRequestInquiryChildList", name = "purchaseRequestInquiryChildList", value = "采购申请询价明细信息", required = "required,json")}) + @RequestMapping("/post/PurchaseRequestController/inquiryPurchaseRequest") + public void inquiryPurchaseRequest(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.inquiryPurchaseRequest(inputObject, outputObject); + } + + /** + * 采购申请定价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "fixedPricePurchaseRequest", value = "采购申请定价", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "fixedPriceUserId", name = "fixedPriceUserId", value = "定价人员id", required = "required"), + @ApiImplicitParam(id = "purchaseRequestFixedChildList", name = "purchaseRequestFixedChildList", value = "采购申请明细定价信息", required = "required,json")}) + @RequestMapping("/post/PurchaseRequestController/fixedPricePurchaseRequest") + public void fixedPricePurchaseRequest(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.fixedPricePurchaseRequest(inputObject, outputObject); + } + + /** + * 采购申请转合同时获取的详情 + * + * @param inputObject + * @param outputObject + */ + @ApiOperation(id = "queryPurchaseRequestTransferContract", value = "采购申请转合同时获取的详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseRequestController/queryPurchaseRequestTransferContract") + public void queryPurchaseRequestTransferContract(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.queryPurchaseRequestTransferContract(inputObject, outputObject); + } + + /** + * 采购申请单转采购合同 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "purchaseRequestToContract", value = "采购申请单转采购合同", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SupplierContract.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseRequestController/purchaseRequestToContract") + public void purchaseRequestToContract(InputObject inputObject, OutputObject outputObject) { + purchaseRequestService.purchaseRequestToContract(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestChildDao.java new file mode 100644 index 0000000..26616ba --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.request.entity.PurchaseRequestChild; + +/** + * @ClassName: PurchaseRequestChildDao + * @Description: 采购申请-子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestDao.java new file mode 100644 index 0000000..28c3a5d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.request.entity.PurchaseRequest; + +/** + * @ClassName: PurchaseRequestDao + * @Description: 采购申请数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestFixedChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestFixedChildDao.java new file mode 100644 index 0000000..d8aa856 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestFixedChildDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.request.entity.PurchaseRequestFixedChild; + +/** + * @ClassName: PurchaseRequestFixedChildDao + * @Description: 采购申请-定价子单据数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/26 14:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestFixedChildDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestInquiryChildDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestInquiryChildDao.java new file mode 100644 index 0000000..9b1043f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/dao/PurchaseRequestInquiryChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.request.entity.PurchaseRequestInquiryChild; + +/** + * @ClassName: PurchaseRequestInquiryChildDao + * @Description: 采购申请询价明细数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestInquiryChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequest.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequest.java new file mode 100644 index 0000000..e0eba30 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequest.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PurchaseRequest + * @Description: 采购申请实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:purchaseRequest", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "erp_purchase_request") +@ApiModel("采购申请实体类") +public class PurchaseRequest extends SkyeyeFlowable { + + @TableField("title") + @ApiModelProperty(value = "单据主题", required = "required") + private String title; + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("from_type_id") + @ApiModelProperty(value = "来源单据类型,参考#PurchaseRequestFromType") + private Integer fromTypeId; + + @TableField("from_id") + @ApiModelProperty(value = "来源单据id") + private String fromId; + + @TableField("inquiry_state") + @Property(value = "询价状态,参考#PurchaseRequestInquiryState") + private Integer inquiryState; + + @TableField("total_price") + @ApiModelProperty(value = "合计总金额") + private String totalPrice; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("project_id") + @ApiModelProperty(value = "关联项目id") + private String projectId; + + @TableField(exist = false) + @Property(value = "关联项目信息") + private Map projectMation; + + @TableField("fixed_price_user_id") + @ApiModelProperty(value = "定价人员id") + private String fixedPriceUserId; + + @TableField(exist = false) + @Property(value = "定价人员信息") + private Map fixedPriceUserMation; + + @TableField(exist = false) + @ApiModelProperty(value = "采购申请明细信息", required = "required,json") + private List purchaseRequestChildList; + + @TableField(exist = false) + @ApiModelProperty(value = "采购申请询价明细信息", required = "json") + private List purchaseRequestInquiryChildList; + + @TableField(exist = false) + @ApiModelProperty(value = "采购申请定价明细信息", required = "json") + private List purchaseRequestFixedChildList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestChild.java new file mode 100644 index 0000000..ee298da --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestChild.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: PurchaseRequestChild + * @Description: 采购申请-子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_purchase_request_child") +@ApiModel("采购申请-子单据实体类") +public class PurchaseRequestChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("oper_number") + @ApiModelProperty(value = "询价数量", required = "required,num") + private Integer operNumber; + + @TableField("need_inquiry") + @ApiModelProperty(value = "询价状态,参考#PurchaseRequestChildInquiry", required = "required,num") + private Integer needInquiry; + + @TableField(exist = false) + @Property(value = "询价状态信息") + private Map needInquiryMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestFixedChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestFixedChild.java new file mode 100644 index 0000000..d21620e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestFixedChild.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.supplier.entity.Supplier; +import lombok.Data; + +/** + * @ClassName: PurchaseRequestFixedChild + * @Description: 采购申请-定价子单据实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_purchase_request_fixed_child") +@ApiModel("采购申请-定价子单据实体类") +public class PurchaseRequestFixedChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField("oper_number") + @ApiModelProperty(value = "询价数量", required = "required,num") + private Integer operNumber; + + @TableField("last_supplier_id") + @ApiModelProperty(value = "最后供应商id") + private String lastSupplierId; + + @TableField(exist = false) + @Property(value = "最后供应商信息") + private Supplier lastSupplierMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestInquiryChild.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestInquiryChild.java new file mode 100644 index 0000000..d73c1f7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/entity/PurchaseRequestInquiryChild.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.supplier.entity.Supplier; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: PurchaseRequestInquiryChild + * @Description: 采购申请询价明细实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_purchase_request_inquiry_child") +@ApiModel("采购申请询价明细实体类") +public class PurchaseRequestInquiryChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property("单据id") + private String parentId; + + @TableField("supplier_id") + @ApiModelProperty(value = "供应商id") + private String supplierId; + + @TableField(exist = false) + @Property(value = "供应商信息") + private Supplier supplierMation; + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Material materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField("oper_number") + @ApiModelProperty(value = "数量", required = "required,num") + private Integer operNumber; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField(value = "all_price") + @ApiModelProperty(value = "不含税的总金额", defaultValue = "0") + private String allPrice; + + @TableField(value = "tax_rate") + @ApiModelProperty(value = "税率", defaultValue = "0") + private String taxRate; + + @TableField(value = "tax_money") + @ApiModelProperty(value = "税额", required = "double", defaultValue = "0") + private String taxMoney; + + @TableField(value = "tax_unit_price") + @ApiModelProperty(value = "含税单价", required = "double", defaultValue = "0") + private String taxUnitPrice; + + @TableField(value = "tax_last_money") + @ApiModelProperty(value = "价税合计", defaultValue = "0") + private String taxLastMoney; + + @TableField(value = "delivery_time") + @ApiModelProperty(value = "交货日期", required = "required") + private String deliveryTime; + + @TableField(value = "type_id") + @ApiModelProperty(value = "开票类型,参考数据字典") + private String typeId; + + @TableField(exist = false) + @Property("开票类型信息") + private Map typeMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestChildService.java new file mode 100644 index 0000000..575afcb --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestChildService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.request.entity.PurchaseRequestChild; + +import java.util.List; + +/** + * @ClassName: PurchaseRequestChildService + * @Description: 采购申请-子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + String calcOrderAllTotalPrice(List purchaseRequestChildList); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestFixedChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestFixedChildService.java new file mode 100644 index 0000000..2cfbfdf --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestFixedChildService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.request.entity.PurchaseRequestFixedChild; + +import java.util.List; + +/** + * @ClassName: PurchaseRequestFixedChildService + * @Description: 采购申请-定价子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/26 14:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestFixedChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + + String calcOrderAllTotalPrice(List purchaseRequestFixedChildList); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestInquiryChildService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestInquiryChildService.java new file mode 100644 index 0000000..2d2a60d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestInquiryChildService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.request.entity.PurchaseRequestInquiryChild; + +import java.util.List; + +/** + * @ClassName: PurchaseRequestInquiryChildService + * @Description: 采购申请询价明细服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestInquiryChildService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestService.java new file mode 100644 index 0000000..716d93c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/PurchaseRequestService.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.request.entity.PurchaseRequest; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PurchaseRequestService + * @Description: 采购申请服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PurchaseRequestService extends SkyeyeFlowableService { + + /** + * 采购申请询价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void inquiryPurchaseRequest(InputObject inputObject, OutputObject outputObject); + + /** + * 采购申请定价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void fixedPricePurchaseRequest(InputObject inputObject, OutputObject outputObject); + + /** + * 采购申请转合同时获取的详情 + * + * @param inputObject + * @param outputObject + */ + void queryPurchaseRequestTransferContract(InputObject inputObject, OutputObject outputObject); + + void purchaseRequestToContract(InputObject inputObject, OutputObject outputObject); + + void setRequestMationByFromId(List> beans, String idKey, String mationKey); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestChildServiceImpl.java new file mode 100644 index 0000000..cd24288 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestChildServiceImpl.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.request.dao.PurchaseRequestChildDao; +import com.skyeye.request.entity.PurchaseRequestChild; +import com.skyeye.request.service.PurchaseRequestChildService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @ClassName: PurchaseRequestChildServiceImpl + * @Description: 采购申请-子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购申请-子单据", groupName = "采购申请", manageShow = false) +public class PurchaseRequestChildServiceImpl extends SkyeyeBusinessServiceImpl implements PurchaseRequestChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (PurchaseRequestChild purchaseRequestChild : beans) { + purchaseRequestChild.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestChild::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public String calcOrderAllTotalPrice(List purchaseRequestChildList) { + String totalPrice = "0"; + for (PurchaseRequestChild purchaseRequestChild : purchaseRequestChildList) { + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(purchaseRequestChild.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(purchaseRequestChild.getOperNumber())); + purchaseRequestChild.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(purchaseRequestChild.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(purchaseRequestChild.getOperNumber())); + purchaseRequestChild.setTaxLastMoney(taxUnitPrice.toString()); + totalPrice = CalculationUtil.add(totalPrice, purchaseRequestChild.getTaxLastMoney()); + } + return totalPrice; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestFixedChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestFixedChildServiceImpl.java new file mode 100644 index 0000000..ace4e15 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestFixedChildServiceImpl.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.request.dao.PurchaseRequestFixedChildDao; +import com.skyeye.request.entity.PurchaseRequestFixedChild; +import com.skyeye.request.service.PurchaseRequestFixedChildService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @ClassName: PurchaseRequestFixedChildServiceImpl + * @Description: 采购申请-定价子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/26 14:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购申请-定价子单据", groupName = "采购申请", manageShow = false) +public class PurchaseRequestFixedChildServiceImpl extends SkyeyeBusinessServiceImpl implements PurchaseRequestFixedChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (PurchaseRequestFixedChild purchaseRequestFixedChild : beans) { + purchaseRequestFixedChild.setId(null); + purchaseRequestFixedChild.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestFixedChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestFixedChild::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + + @Override + public String calcOrderAllTotalPrice(List purchaseRequestFixedChildList) { + String totalPrice = "0"; + for (PurchaseRequestFixedChild purchaseRequestFixedChild : purchaseRequestFixedChildList) { + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(purchaseRequestFixedChild.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(purchaseRequestFixedChild.getOperNumber())); + purchaseRequestFixedChild.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(purchaseRequestFixedChild.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(purchaseRequestFixedChild.getOperNumber())); + purchaseRequestFixedChild.setTaxLastMoney(taxUnitPrice.toString()); + totalPrice = CalculationUtil.add(totalPrice, purchaseRequestFixedChild.getTaxLastMoney()); + } + return totalPrice; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestInquiryChildServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestInquiryChildServiceImpl.java new file mode 100644 index 0000000..5db2dfe --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestInquiryChildServiceImpl.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.request.dao.PurchaseRequestInquiryChildDao; +import com.skyeye.request.entity.PurchaseRequestInquiryChild; +import com.skyeye.request.service.PurchaseRequestInquiryChildService; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @ClassName: PurchaseRequestInquiryChildServiceImpl + * @Description: 采购申请询价明细服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购申请询价明细", groupName = "采购申请", manageShow = false) +public class PurchaseRequestInquiryChildServiceImpl extends SkyeyeBusinessServiceImpl implements PurchaseRequestInquiryChildService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (PurchaseRequestInquiryChild purchaseRequestInquiryChild : beans) { + purchaseRequestInquiryChild.setParentId(parentId); + // 计算子单据总价:单价 * 数量 + BigDecimal itemAllPrice = new BigDecimal(purchaseRequestInquiryChild.getUnitPrice()); + itemAllPrice = itemAllPrice.multiply(new BigDecimal(purchaseRequestInquiryChild.getOperNumber())); + purchaseRequestInquiryChild.setAllPrice(itemAllPrice.toString()); + + // 计算子单据价税合计:含税单价 * 数量 + BigDecimal taxUnitPrice = new BigDecimal(purchaseRequestInquiryChild.getTaxUnitPrice()); + taxUnitPrice = taxUnitPrice.multiply(new BigDecimal(purchaseRequestInquiryChild.getOperNumber())); + purchaseRequestInquiryChild.setTaxLastMoney(taxUnitPrice.toString()); + + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestInquiryChild::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PurchaseRequestInquiryChild::getParentId), parentId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestServiceImpl.java new file mode 100644 index 0000000..524c940 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/request/service/impl/PurchaseRequestServiceImpl.java @@ -0,0 +1,368 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.request.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.classenum.SupplierContractFromType; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.contract.service.SupplierContractService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.service.MaterialService; +import com.skyeye.request.classenum.PurchaseRequestChildInquiry; +import com.skyeye.request.classenum.PurchaseRequestInquiryState; +import com.skyeye.request.classenum.PurchaseRequestStateEnum; +import com.skyeye.request.dao.PurchaseRequestDao; +import com.skyeye.request.entity.PurchaseRequest; +import com.skyeye.request.entity.PurchaseRequestChild; +import com.skyeye.request.entity.PurchaseRequestFixedChild; +import com.skyeye.request.entity.PurchaseRequestInquiryChild; +import com.skyeye.request.service.PurchaseRequestChildService; +import com.skyeye.request.service.PurchaseRequestFixedChildService; +import com.skyeye.request.service.PurchaseRequestInquiryChildService; +import com.skyeye.request.service.PurchaseRequestService; +import com.skyeye.rest.project.service.IProProjectService; +import com.skyeye.supplier.service.SupplierService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PurchaseRequestServiceImpl + * @Description: 采购申请服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 11:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "采购申请", groupName = "采购申请", flowable = true) +public class PurchaseRequestServiceImpl extends SkyeyeFlowableServiceImpl implements PurchaseRequestService { + + @Autowired + private PurchaseRequestChildService purchaseRequestChildService; + + @Autowired + private PurchaseRequestInquiryChildService purchaseRequestInquiryChildService; + + @Autowired + private PurchaseRequestFixedChildService purchaseRequestFixedChildService; + + @Autowired + private SupplierContractService supplierContractService; + + @Autowired + private MaterialService materialService; + + @Autowired + private SupplierService supplierService; + + @Autowired + private IProProjectService iProProjectService; + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + iProProjectService.setMationForMap(beans, "projectId", "projectMation"); + return beans; + } + + @Override + public void createPrepose(PurchaseRequest entity) { + super.createPrepose(entity); + // 设置询价类型 + Integer inquiryState = PurchaseRequestInquiryState.NOT_INQUIRY.getKey(); + for (PurchaseRequestChild purchaseRequestChild : entity.getPurchaseRequestChildList()) { + if (purchaseRequestChild.getNeedInquiry() == PurchaseRequestChildInquiry.INQUIRY.getKey()) { + inquiryState = PurchaseRequestInquiryState.WAIT_INQUIRY.getKey(); + } + } + entity.setInquiryState(inquiryState); + getTotalPrice(entity); + } + + @Override + public void updatePrepose(PurchaseRequest entity) { + super.updatePrepose(entity); + // 设置询价类型 + Integer inquiryState = PurchaseRequestInquiryState.NOT_INQUIRY.getKey(); + for (PurchaseRequestChild purchaseRequestChild : entity.getPurchaseRequestChildList()) { + if (purchaseRequestChild.getNeedInquiry() == PurchaseRequestChildInquiry.INQUIRY.getKey()) { + inquiryState = PurchaseRequestInquiryState.WAIT_INQUIRY.getKey(); + } + } + entity.setInquiryState(inquiryState); + getTotalPrice(entity); + } + + private void getTotalPrice(PurchaseRequest entity) { + // 计算关联的产品总价 + String totalPrice = purchaseRequestChildService.calcOrderAllTotalPrice(entity.getPurchaseRequestChildList()); + entity.setTotalPrice(totalPrice); + } + + @Override + public void writeChild(PurchaseRequest entity, String userId) { + purchaseRequestChildService.saveList(entity.getId(), entity.getPurchaseRequestChildList()); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + purchaseRequestChildService.deleteByParentId(id); + purchaseRequestInquiryChildService.deleteByParentId(id); + } + + @Override + public PurchaseRequest getDataFromDb(String id) { + PurchaseRequest purchaseRequest = super.getDataFromDb(id); + // 商品明细信息 + List purchaseRequestChildList = purchaseRequestChildService.selectByParentId(purchaseRequest.getId()); + purchaseRequest.setPurchaseRequestChildList(purchaseRequestChildList); + + // 询价信息 + List purchaseRequestInquiryChildList = purchaseRequestInquiryChildService.selectByParentId(purchaseRequest.getId()); + purchaseRequest.setPurchaseRequestInquiryChildList(purchaseRequestInquiryChildList); + + // 定价信息 + List purchaseRequestFixedChildList = purchaseRequestFixedChildService.selectByParentId(purchaseRequest.getId()); + purchaseRequest.setPurchaseRequestFixedChildList(purchaseRequestFixedChildList); + return purchaseRequest; + } + + @Override + public PurchaseRequest selectById(String id) { + PurchaseRequest purchaseRequest = super.selectById(id); + // 设置子单据的产品信息 + materialService.setDataMation(purchaseRequest.getPurchaseRequestChildList(), PurchaseRequestChild::getMaterialId); + purchaseRequest.getPurchaseRequestChildList().forEach(purchaseRequestChild -> { + MaterialNorms norms = purchaseRequestChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(purchaseRequestChild.getNormsId(), bean.getId())).findFirst().orElse(null); + purchaseRequestChild.setNormsMation(norms); + // 设置子单据的询价状态信息 + Map needInquiryMation = new HashMap<>(); + needInquiryMation.put("name", PurchaseRequestChildInquiry.getName(purchaseRequestChild.getNeedInquiry())); + purchaseRequestChild.setNeedInquiryMation(needInquiryMation); + }); + + if (purchaseRequest.getInquiryState() != PurchaseRequestInquiryState.NOT_INQUIRY.getKey()) { + // 需要询价的申请单 + if (purchaseRequest.getInquiryState() == PurchaseRequestInquiryState.INQUIRYING.getKey()) { + // 询价中 + // 采购申请明细定价信息 + List purchaseRequestFixedChildList = JSONUtil.toList( + JSONUtil.toJsonStr(purchaseRequest.getPurchaseRequestChildList()), PurchaseRequestFixedChild.class + ); + purchaseRequest.setPurchaseRequestFixedChildList(purchaseRequestFixedChildList); + } + } + if (CollectionUtil.isNotEmpty(purchaseRequest.getPurchaseRequestFixedChildList())) { + // 设置定价明细信息 + materialService.setDataMation(purchaseRequest.getPurchaseRequestFixedChildList(), PurchaseRequestFixedChild::getMaterialId); + purchaseRequest.getPurchaseRequestFixedChildList().forEach(purchaseRequestFixedChild -> { + MaterialNorms norms = purchaseRequestFixedChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(purchaseRequestFixedChild.getNormsId(), bean.getId())).findFirst().orElse(null); + purchaseRequestFixedChild.setNormsMation(norms); + }); + } + + // 定价供应商 + supplierService.setDataMation(purchaseRequest.getPurchaseRequestFixedChildList(), PurchaseRequestFixedChild::getLastSupplierId); + + // 设置询价明细的产品信息 + materialService.setDataMation(purchaseRequest.getPurchaseRequestInquiryChildList(), PurchaseRequestInquiryChild::getMaterialId); + purchaseRequest.getPurchaseRequestInquiryChildList().forEach(purchaseRequestInquiryChild -> { + MaterialNorms norms = purchaseRequestInquiryChild.getMaterialMation().getMaterialNorms() + .stream().filter(bean -> StrUtil.equals(purchaseRequestInquiryChild.getNormsId(), bean.getId())).findFirst().orElse(null); + purchaseRequestInquiryChild.setNormsMation(norms); + }); + supplierService.setDataMation(purchaseRequest.getPurchaseRequestInquiryChildList(), PurchaseRequestInquiryChild::getSupplierId); + + // 设置子单据开票类型 + iSysDictDataService.setDataMation(purchaseRequest.getPurchaseRequestInquiryChildList(), PurchaseRequestInquiryChild::getTypeId); + // 设置项目信息 + iProProjectService.setDataMation(purchaseRequest, PurchaseRequest::getProjectId); + // 设置定价人员信息 + iAuthUserService.setDataMation(purchaseRequest, PurchaseRequest::getFixedPriceUserId); + return purchaseRequest; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void inquiryPurchaseRequest(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + PurchaseRequest purchaseRequest = selectById(id); + if (!purchaseRequest.getState().equals(FlowableStateEnum.PASS.getKey())) { + throw new CustomException("只有审批通过的申请单可以进行询价."); + } + if (PurchaseRequestInquiryState.NOT_INQUIRY.getKey() == purchaseRequest.getInquiryState()) { + // 无需询价 + throw new CustomException("该申请单无需进行询价."); + } + List oldNormsId = purchaseRequest.getPurchaseRequestChildList().stream() + .map(PurchaseRequestChild::getNormsId).collect(Collectors.toList()); + + List purchaseRequestInquiryChildList = JSONUtil.toList( + params.get("purchaseRequestInquiryChildList").toString(), PurchaseRequestInquiryChild.class + ); + purchaseRequestInquiryChildList.forEach(purchaseRequestInquiryChild -> { + if (!oldNormsId.contains(purchaseRequestInquiryChild.getNormsId())) { + throw new CustomException("存在申请单中不包含的商品规格信息,请确认."); + } + }); + purchaseRequestInquiryChildService.saveList(id, purchaseRequestInquiryChildList); + // 设置为询价中 + editInquiryStateById(id, PurchaseRequestInquiryState.INQUIRYING.getKey(), null); + } + + private void editInquiryStateById(String id, Integer inquiryState, String fixedPriceUserId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(PurchaseRequest::getInquiryState), inquiryState); + if (StrUtil.isNotEmpty(fixedPriceUserId)) { + updateWrapper.set(MybatisPlusUtil.toColumns(PurchaseRequest::getFixedPriceUserId), fixedPriceUserId); + } + update(updateWrapper); + refreshCache(id); + } + + @Override + public void approvalEndIsSuccess(PurchaseRequest entity) { + // 审批通过的且无需询价的需要将采购申请明细转到定价信息表中 + if (PurchaseRequestInquiryState.NOT_INQUIRY.getKey() == entity.getInquiryState()) { + PurchaseRequest purchaseRequest = selectById(entity.getId()); + List purchaseRequestFixedChildList = JSONUtil.toList( + JSONUtil.toJsonStr(purchaseRequest.getPurchaseRequestChildList()), PurchaseRequestFixedChild.class + ); + // 保存定价信息 + purchaseRequestFixedChildService.saveList(entity.getId(), purchaseRequestFixedChildList); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void fixedPricePurchaseRequest(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + PurchaseRequest purchaseRequest = selectById(id); + if (!purchaseRequest.getState().equals(FlowableStateEnum.PASS.getKey())) { + throw new CustomException("只有审批通过的申请单可以进行定价."); + } + if (PurchaseRequestInquiryState.NOT_INQUIRY.getKey() == purchaseRequest.getInquiryState()) { + // 无需定价 + throw new CustomException("该申请单无需进行定价."); + } + // 采购申请明细定价信息 + List purchaseRequestFixedChildList = JSONUtil.toList( + params.get("purchaseRequestFixedChildList").toString(), PurchaseRequestFixedChild.class + ); + // 保存定价信息 + purchaseRequestFixedChildService.saveList(id, purchaseRequestFixedChildList); + // 设置为询价完毕 + String fixedPriceUserId = params.get("fixedPriceUserId").toString(); + editInquiryStateById(id, PurchaseRequestInquiryState.COMPLATE_INQUIRY.getKey(), fixedPriceUserId); + } + + @Override + public void queryPurchaseRequestTransferContract(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + PurchaseRequest purchaseRequest = getPurchaseRequest(id); + // 根据供应商进行分组生成合同 + Map> requestChildMap = purchaseRequest.getPurchaseRequestFixedChildList().stream() + .collect(Collectors.groupingBy(bean -> { + return StrUtil.isEmpty(bean.getLastSupplierId()) ? "-" : bean.getLastSupplierId(); + })); + + outputObject.setBean(requestChildMap); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private PurchaseRequest getPurchaseRequest(String id) { + PurchaseRequest purchaseRequest = selectById(id); + if (purchaseRequest.getState().equals(PurchaseRequestStateEnum.PROCUREMENT_COMPLETED.getKey())) { + throw new CustomException("该申请单已完成采购合同申请,无法再次进行合同"); + } + return getPurchaseRequest(purchaseRequest); + } + + private PurchaseRequest getPurchaseRequest(PurchaseRequest purchaseRequest) { + // 获取已经签订合同的商品信息 + Map executeNum = supplierContractService.calcMaterialNormsNumByFromId(purchaseRequest.getId()); + if (CollectionUtil.isEmpty(purchaseRequest.getPurchaseRequestFixedChildList())) { + purchaseRequest.setPurchaseRequestFixedChildList(CollectionUtil.newArrayList()); + return purchaseRequest; + } + purchaseRequest.getPurchaseRequestFixedChildList().forEach(purchaseRequestFixedChild -> { + Integer surplusNum = purchaseRequestFixedChild.getOperNumber() + - (executeNum.containsKey(purchaseRequestFixedChild.getNormsId()) ? executeNum.get(purchaseRequestFixedChild.getNormsId()) : 0); + // 设置未签合同的商品数量 + purchaseRequestFixedChild.setOperNumber(surplusNum); + }); + // 过滤掉申请数量为0的进行生成合同 + purchaseRequest.setPurchaseRequestFixedChildList(purchaseRequest.getPurchaseRequestFixedChildList().stream() + .filter(purchaseRequestChild -> purchaseRequestChild.getOperNumber() > 0).collect(Collectors.toList())); + return purchaseRequest; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void purchaseRequestToContract(InputObject inputObject, OutputObject outputObject) { + SupplierContract supplierContract = inputObject.getParams(SupplierContract.class); + supplierContract.setFromId(supplierContract.getId()); + supplierContract.setFromTypeId(SupplierContractFromType.PURCHASE_REQUEST.getKey()); + supplierContract.setId(null); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 保存供应商合同 + supplierContractService.createEntity(supplierContract, userId, false); + } + + @Override + public void setRequestMationByFromId(List> beans, String idKey, String mationKey) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List ids = beans.stream().filter(bean -> !MapUtil.checkKeyIsNull(bean, idKey)) + .map(bean -> bean.get(idKey).toString()).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, ids); + List purchaseRequestList = list(queryWrapper); + Map purchaseRequestMap = purchaseRequestList.stream() + .collect(Collectors.toMap(PurchaseRequest::getId, bean -> bean)); + for (Map bean : beans) { + if (!MapUtil.checkKeyIsNull(bean, idKey)) { + PurchaseRequest entity = purchaseRequestMap.get(bean.get(idKey).toString()); + if (ObjectUtil.isEmpty(entity)) { + continue; + } + bean.put(mationKey, entity); + } + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailOutLetController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailOutLetController.java new file mode 100644 index 0000000..8183521 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailOutLetController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.retail.entity.RetailOutLet; +import com.skyeye.retail.service.RetailOutLetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RetailOutLetController + * @Description: 零售出库单控制类 + * @author: skyeye云系列--卫志强 + * @date: 2019/10/16 15:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "零售出库单", tags = "零售出库单", modelName = "零售模块") +public class RetailOutLetController { + + @Autowired + private RetailOutLetService retailOutLetService; + + /** + * 获取零售出库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "retailoutlet001", value = "获取零售出库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RetailOutLetController/queryRetailOutLetList") + public void queryRetailOutLetList(InputObject inputObject, OutputObject outputObject) { + retailOutLetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑零售出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRetailOutLet", value = "新增/编辑零售出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RetailOutLet.class) + @RequestMapping("/post/RetailOutLetController/writeRetailOutLet") + public void writeRetailOutLet(InputObject inputObject, OutputObject outputObject) { + retailOutLetService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询零售出库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRetailOutLetTransById", value = "转仓库出库单时,根据id查询零售出库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RetailOutLetController/queryRetailOutLetTransById") + public void queryRetailOutLetTransById(InputObject inputObject, OutputObject outputObject) { + retailOutLetService.queryRetailOutLetTransById(inputObject, outputObject); + } + + /** + * 零售出库单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertRetailOutLetToTurnDepot", value = "零售出库单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RetailOutLetController/insertRetailOutLetToTurnDepot") + public void insertRetailOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + retailOutLetService.insertRetailOutLetToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailReturnsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailReturnsController.java new file mode 100644 index 0000000..e0b5552 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/controller/RetailReturnsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.retail.entity.RetailReturns; +import com.skyeye.retail.service.RetailReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: RetailReturnsController + * @Description: 零售退货单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "零售退货单", tags = "零售退货单", modelName = "零售模块") +public class RetailReturnsController { + + @Autowired + private RetailReturnsService retailReturnsService; + + /** + * 获取零售退货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "retailreturns001", value = "获取零售退货单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/RetailReturnsController/queryRetailReturnsList") + public void queryRetailReturnsList(InputObject inputObject, OutputObject outputObject) { + retailReturnsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑零售退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeRetailReturns", value = "新增/编辑零售退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = RetailReturns.class) + @RequestMapping("/post/RetailReturnsController/writeRetailReturns") + public void writeRetailReturns(InputObject inputObject, OutputObject outputObject) { + retailReturnsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询零售退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRetailReturnsTransById", value = "转仓库入库单时,根据id查询零售退货信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RetailReturnsController/queryRetailReturnsTransById") + public void queryRetailReturnsTransById(InputObject inputObject, OutputObject outputObject) { + retailReturnsService.queryRetailReturnsTransById(inputObject, outputObject); + } + + /** + * 零售退货单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertRetailReturnsToTurnDepot", value = "零售退货单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/RetailReturnsController/insertRetailReturnsToTurnDepot") + public void insertRetailReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + retailReturnsService.insertRetailReturnsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailOutLetDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailOutLetDao.java new file mode 100644 index 0000000..bee26d2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailOutLetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.retail.entity.RetailOutLet; + +/** + * @ClassName: RetailOutLetDao + * @Description: 零售出库单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RetailOutLetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailReturnsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailReturnsDao.java new file mode 100644 index 0000000..4ba5986 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/dao/RetailReturnsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.retail.entity.RetailReturns; + +/** + * @ClassName: RetailReturnsDao + * @Description: 零售退货单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RetailReturnsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailOutLet.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailOutLet.java new file mode 100644 index 0000000..580ac9e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailOutLet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: RetailOutLet + * @Description: 零售出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:retailOutLet", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("零售出库单实体类") +public class RetailOutLet extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailReturns.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailReturns.java new file mode 100644 index 0000000..ca9a405 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/entity/RetailReturns.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: RetailReturns + * @Description: 零售退货单实体类 + * --otherState:这里表示【零售退货单入库状态】参考#DepotPutState + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:retailReturns", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("零售退货单实体类") +public class RetailReturns extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailOutLetService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailOutLetService.java new file mode 100644 index 0000000..af9aa71 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailOutLetService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.retail.entity.RetailOutLet; + +/** + * @ClassName: RetailOutLetService + * @Description: 零售出库单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RetailOutLetService extends SkyeyeErpOrderService { + + void queryRetailOutLetTransById(InputObject inputObject, OutputObject outputObject); + + void insertRetailOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailReturnsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailReturnsService.java new file mode 100644 index 0000000..417a92c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/RetailReturnsService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.retail.entity.RetailReturns; + +/** + * @ClassName: RetailReturnsService + * @Description: 零售退货单管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RetailReturnsService extends SkyeyeErpOrderService { + + void queryRetailReturnsTransById(InputObject inputObject, OutputObject outputObject); + + void insertRetailReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailOutLetServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailOutLetServiceImpl.java new file mode 100644 index 0000000..b307916 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailOutLetServiceImpl.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.retail.dao.RetailOutLetDao; +import com.skyeye.retail.entity.RetailOutLet; +import com.skyeye.retail.service.RetailOutLetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: RetailOutLetServiceImpl + * @Description: 零售出库单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "零售出库单", groupName = "零售模块", flowable = true) +public class RetailOutLetServiceImpl extends SkyeyeErpOrderServiceImpl implements RetailOutLetService { + + @Autowired + private DepotOutService depotOutService; + + @Override + public void validatorEntity(RetailOutLet entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + } + + @Override + public void createPrepose(RetailOutLet entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void queryRetailOutLetTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + RetailOutLet retailOutLet = selectById(id); + // 该零售出库单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(retailOutLet.getId()); + // 设置未下达商品数量-----零售出库单数量 - 已出库数量 + super.setOrCheckOperNumber(retailOutLet.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + retailOutLet.setErpOrderItemList(retailOutLet.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(retailOutLet); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertRetailOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取零售出库单状态 + RetailOutLet retailOutLet = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(retailOutLet)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(retailOutLet.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.RETAIL_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailReturnsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailReturnsServiceImpl.java new file mode 100644 index 0000000..d1e5c06 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/retail/service/impl/RetailReturnsServiceImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.retail.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.retail.dao.RetailReturnsDao; +import com.skyeye.retail.entity.RetailReturns; +import com.skyeye.retail.service.RetailReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: RetailReturnsServiceImpl + * @Description: 零售退货单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "零售退货单", groupName = "零售模块", flowable = true) +public class RetailReturnsServiceImpl extends SkyeyeErpOrderServiceImpl implements RetailReturnsService { + + @Autowired + private DepotPutService depotPutService; + + @Override + public void validatorEntity(RetailReturns entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + } + + @Override + public void createPrepose(RetailReturns entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void queryRetailReturnsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + RetailReturns retailReturns = selectById(id); + // 该零售退货单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(retailReturns.getId()); + // 设置未下达商品数量-----零售退货单数量 - 已入库数量 + super.setOrCheckOperNumber(retailReturns.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + retailReturns.setErpOrderItemList(retailReturns.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(retailReturns); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertRetailReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取零售退货单状态 + RetailReturns retailReturns = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(retailReturns)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(retailReturns.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.RETAIL_RETURNS.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOrderFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOrderFromType.java new file mode 100644 index 0000000..2561d05 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOrderFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SealOrderFromType + * @Description: 销售订单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SealOrderFromType implements SkyeyeEnumClass { + + CUSTOMER_CONTRACT(1, "客户合同", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOutLetFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOutLetFromType.java new file mode 100644 index 0000000..4199500 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealOutLetFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SealOutLetFromType + * @Description: 销售出库单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SealOutLetFromType implements SkyeyeEnumClass { + + SEAL_ORDER(1, "销售订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealReturnFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealReturnFromType.java new file mode 100644 index 0000000..d979fc8 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/classenum/SealReturnFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SealReturnFromType + * @Description: 销售退货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SealReturnFromType implements SkyeyeEnumClass { + + SEAL_ORDER(1, "销售订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOrderController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOrderController.java new file mode 100644 index 0000000..b7999f8 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOrderController.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.seal.entity.SalesOrder; +import com.skyeye.seal.entity.SalesOutLet; +import com.skyeye.seal.entity.SalesReturns; +import com.skyeye.seal.service.SalesOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SalesOrderController + * @Description: 销售订单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "销售订单", tags = "销售订单", modelName = "销售模块") +public class SalesOrderController { + + @Autowired + private SalesOrderService salesOrderService; + + /** + * 获取销售订单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesorder001", value = "获取销售订单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SalesOrderController/querySalesOrderToList") + public void querySalesOrderToList(InputObject inputObject, OutputObject outputObject) { + salesOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑销售订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSalesOrder", value = "新增/编辑销售订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesOrder.class) + @RequestMapping("/post/SalesOrderController/writeSalesOrder") + public void writeSalesOrder(InputObject inputObject, OutputObject outputObject) { + salesOrderService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取审核通过的销售单列表展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesorder011", value = "获取审核通过的销售单列表展示为树", method = "GET", allUse = "2") + @RequestMapping("/post/SalesOrderController/querySalesOrderListToTree") + public void querySalesOrderListToTree(InputObject inputObject, OutputObject outputObject) { + salesOrderService.querySalesOrderListToTree(inputObject, outputObject); + } + + /** + * 根据销售单id获取子单据列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesorder012", value = "根据销售单id获取子单据列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/querySalesOrderMaterialListByOrderId") + public void querySalesOrderMaterialListByOrderId(InputObject inputObject, OutputObject outputObject) { + salesOrderService.querySalesOrderMaterialListByOrderId(inputObject, outputObject); + } + + /** + * 转销售出库单/销售退货单时,根据id查询销售订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealsOrderTransById", value = "转销售出库单/销售退货单时,根据id查询销售订单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/querySealsOrderTransById") + public void querySealsOrderTransById(InputObject inputObject, OutputObject outputObject) { + salesOrderService.querySealsOrderTransById(inputObject, outputObject); + } + + /** + * 销售订单转销售出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesorder009", value = "销售订单转销售出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesOutLet.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/insertSalesOrderToTurnPut") + public void insertSalesOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + salesOrderService.insertSalesOrderToTurnPut(inputObject, outputObject); + } + + /** + * 销售订单转销售退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSealsOrderToSealsReturns", value = "销售订单转销售退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesReturns.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/insertSealsOrderToSealsReturns") + public void insertSealsOrderToSealsReturns(InputObject inputObject, OutputObject outputObject) { + salesOrderService.insertSealsOrderToSealsReturns(inputObject, outputObject); + } + + /** + * 客户合同转销售订单时,根据id查询客户合同信息 + * 因为这里涉及到了微服务的调用,直接写在ERP微服务会方便很多 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCrmContractTransById", value = "客户合同转销售订单时,根据id查询客户合同信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/queryCrmContractTransById") + public void queryCrmContractTransById(InputObject inputObject, OutputObject outputObject) { + salesOrderService.queryCrmContractTransById(inputObject, outputObject); + } + + /** + * 客户合同转销售订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertCrmContractToSealsOrder", value = "客户合同转销售订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesOrder.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/insertCrmContractToSealsOrder") + public void insertCrmContractToSealsOrder(InputObject inputObject, OutputObject outputObject) { + salesOrderService.insertCrmContractToSealsOrder(inputObject, outputObject); + } + + /** + * 转出货计划单时,根据id查询销售订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealsOrderTransProductionPlanById", value = "转出货计划单时,根据id查询销售订单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/querySealsOrderTransProductionPlanById") + public void querySealsOrderTransProductionPlanById(InputObject inputObject, OutputObject outputObject) { + salesOrderService.querySealsOrderTransProductionPlanById(inputObject, outputObject); + } + + /** + * 销售订单转出货计划单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSealsOrderToProductionPlan", value = "销售订单转出货计划单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ProductionPlan.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOrderController/insertSealsOrderToProductionPlan") + public void insertSealsOrderToProductionPlan(InputObject inputObject, OutputObject outputObject) { + salesOrderService.insertSealsOrderToProductionPlan(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOutLetController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOutLetController.java new file mode 100644 index 0000000..b6b352e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesOutLetController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.seal.entity.SalesOutLet; +import com.skyeye.seal.service.SalesOutLetService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SalesOutLetController + * @Description: 销售出库单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/4/26 17:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "销售出库单", tags = "销售出库单", modelName = "销售模块") +public class SalesOutLetController { + + @Autowired + private SalesOutLetService salesOutLetService; + + /** + * 获取销售出库单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesoutlet001", value = "获取销售出库单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SalesOutLetController/querySalesOutLetList") + public void querySalesOutLetList(InputObject inputObject, OutputObject outputObject) { + salesOutLetService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑销售出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSalesOutLet", value = "新增/编辑销售出库单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesOutLet.class) + @RequestMapping("/post/SalesOutLetController/writeSalesOutLet") + public void writeSalesOutLet(InputObject inputObject, OutputObject outputObject) { + salesOutLetService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询销售出库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySalesOutLetTransById", value = "转仓库出库单时,根据id查询销售出库信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOutLetController/querySalesOutLetTransById") + public void querySalesOutLetTransById(InputObject inputObject, OutputObject outputObject) { + salesOutLetService.querySalesOutLetTransById(inputObject, outputObject); + } + + /** + * 销售出库单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSalesOutLetToTurnDepot", value = "销售出库单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesOutLetController/insertSalesOutLetToTurnDepot") + public void insertSalesOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + salesOutLetService.insertSalesOutLetToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesReturnsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesReturnsController.java new file mode 100644 index 0000000..afa4d7c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/controller/SalesReturnsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.seal.entity.SalesReturns; +import com.skyeye.seal.service.SalesReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SalesReturnsController + * @Description: 销售退货单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "销售退货单", tags = "销售退货单", modelName = "销售模块") +public class SalesReturnsController { + + @Autowired + private SalesReturnsService salesReturnsService; + + /** + * 获取销售退货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "salesreturns001", value = "获取销售退货单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SalesReturnsController/querySalesReturnsList") + public void querySalesReturnsList(InputObject inputObject, OutputObject outputObject) { + salesReturnsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑销售退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSalesReturns", value = "新增/编辑销售退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SalesReturns.class) + @RequestMapping("/post/SalesReturnsController/writeSalesReturns") + public void writeSalesReturns(InputObject inputObject, OutputObject outputObject) { + salesReturnsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询销售退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySalesReturnsTransById", value = "转仓库入库单时,根据id查询销售退货信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesReturnsController/querySalesReturnsTransById") + public void querySalesReturnsTransById(InputObject inputObject, OutputObject outputObject) { + salesReturnsService.querySalesReturnsTransById(inputObject, outputObject); + } + + /** + * 销售退货单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSalesReturnsToTurnDepot", value = "销售退货单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SalesReturnsController/insertSalesReturnsToTurnDepot") + public void insertSalesReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + salesReturnsService.insertSalesReturnsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOrderDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOrderDao.java new file mode 100644 index 0000000..0571ffc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOrderDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.seal.entity.SalesOrder; + +/** + * @ClassName: SalesOrderDao + * @Description: 销售订单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/14 23:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesOrderDao extends SkyeyeBaseMapper { + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOutLetDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOutLetDao.java new file mode 100644 index 0000000..b6db121 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesOutLetDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.seal.entity.SalesOutLet; + +/** + * @ClassName: SalesOutLetDao + * @Description: 销售出库单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesOutLetDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesReturnsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesReturnsDao.java new file mode 100644 index 0000000..c65c7c7 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/dao/SalesReturnsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.seal.entity.SalesReturns; + +/** + * @ClassName: SalesReturnsDao + * @Description: 销售退货单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesReturnsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOrder.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOrder.java new file mode 100644 index 0000000..88ac7ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOrder.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: SalesOrder + * @Description: 销售订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:sales", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("销售订单实体类") +public class SalesOrder extends ErpOrderHead { + + @TableField(exist = false) + @Property(value = "树的名称(单号)") + private String name; + + @TableField(exist = false) + @Property(value = "树的父节点ID") + private String pId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOutLet.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOutLet.java new file mode 100644 index 0000000..50be009 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesOutLet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: SalesOutLet + * @Description: 销售出库单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:salesOutLet", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("销售出库单实体类") +public class SalesOutLet extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesReturns.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesReturns.java new file mode 100644 index 0000000..fd73f3e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/entity/SalesReturns.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: SalesReturns + * @Description: 销售退货单实体类 + * --otherState:这里表示【销售退货单入库状态】参考#DepotPutState + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:salesReturns", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("销售退货单实体类") +public class SalesReturns extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOrderService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOrderService.java new file mode 100644 index 0000000..a938dcd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOrderService.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.seal.entity.SalesOrder; + +/** + * @ClassName: SalesOrderService + * @Description: 销售订单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesOrderService extends SkyeyeErpOrderService { + + void querySalesOrderListToTree(InputObject inputObject, OutputObject outputObject); + + void querySalesOrderMaterialListByOrderId(InputObject inputObject, OutputObject outputObject); + + void querySealsOrderTransById(InputObject inputObject, OutputObject outputObject); + + void insertSalesOrderToTurnPut(InputObject inputObject, OutputObject outputObject); + + void queryCrmContractTransById(InputObject inputObject, OutputObject outputObject); + + void insertCrmContractToSealsOrder(InputObject inputObject, OutputObject outputObject); + + void insertSealsOrderToSealsReturns(InputObject inputObject, OutputObject outputObject); + + void querySealsOrderTransProductionPlanById(InputObject inputObject, OutputObject outputObject); + + void insertSealsOrderToProductionPlan(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOutLetService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOutLetService.java new file mode 100644 index 0000000..2d27615 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesOutLetService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.seal.entity.SalesOutLet; + +/** + * @ClassName: SalesOutLetService + * @Description: 销售出库单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesOutLetService extends SkyeyeErpOrderService { + + void querySalesOutLetTransById(InputObject inputObject, OutputObject outputObject); + + void insertSalesOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesReturnsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesReturnsService.java new file mode 100644 index 0000000..71f1020 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/SalesReturnsService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.seal.entity.SalesReturns; + +/** + * @ClassName: SalesReturnsService + * @Description: 销售退货单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SalesReturnsService extends SkyeyeErpOrderService { + + void querySalesReturnsTransById(InputObject inputObject, OutputObject outputObject); + + void insertSalesReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOrderServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOrderServiceImpl.java new file mode 100644 index 0000000..f5601f0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOrderServiceImpl.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.crm.service.IContractService; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.production.classenum.ProductionPlanFromType; +import com.skyeye.production.entity.ProductionPlan; +import com.skyeye.production.service.ProductionPlanService; +import com.skyeye.seal.classenum.SealOrderFromType; +import com.skyeye.seal.classenum.SealOutLetFromType; +import com.skyeye.seal.classenum.SealReturnFromType; +import com.skyeye.seal.dao.SalesOrderDao; +import com.skyeye.seal.entity.SalesOrder; +import com.skyeye.seal.entity.SalesOutLet; +import com.skyeye.seal.entity.SalesReturns; +import com.skyeye.seal.service.SalesOrderService; +import com.skyeye.seal.service.SalesOutLetService; +import com.skyeye.seal.service.SalesReturnsService; +import com.skyeye.util.ErpOrderUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SalesOrderServiceImpl + * @Description: 销售订单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "销售订单", groupName = "销售模块", flowable = true) +public class SalesOrderServiceImpl extends SkyeyeErpOrderServiceImpl implements SalesOrderService { + + @Autowired + private SalesOutLetService salesOutLetService; + + @Autowired + private SalesReturnsService salesReturnsService; + + @Autowired + private IContractService iContractService; + + @Autowired + private ProductionPlanService productionPlanService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(SalesOrder::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(SalesOrder::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public void validatorEntity(SalesOrder entity) { + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(SalesOrder entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + iContractService.setMationForMap(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public SalesOrder selectById(String id) { + SalesOrder salesOrder = super.selectById(id); + salesOrder.setName(salesOrder.getOddNumber()); + return salesOrder; + } + + private void checkMaterialNorms(SalesOrder entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前销售订单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达订单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == SealOrderFromType.CUSTOMER_CONTRACT.getKey()) { + Map crmContract = iContractService.queryDataMationById(entity.getFromId()); + String crmContractChildListStr = MapUtil.checkKeyIsNull(crmContract, "crmContractChildList") ? + StrUtil.EMPTY : crmContract.get("crmContractChildList").toString(); + if (StrUtil.isEmpty(crmContractChildListStr)) { + throw new CustomException("该销售合同下未包含商品."); + } + List> contractChildList = JSONUtil.toList(crmContractChildListStr, null); + List fromNormsIds = contractChildList.stream() + .map(bean -> bean.get("normsId").toString()).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + + contractChildList.forEach(contractChild -> { + Integer operNumber = Integer.parseInt(contractChild.get("operNumber").toString()); + String normsId = contractChild.get("normsId").toString(); + Integer surplusNum = ErpOrderUtil.checkOperNumber(operNumber, normsId, orderNormsNum, executeNum); + if (setData) { + contractChild.put("operNumber", surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + contractChildList = contractChildList.stream() + .filter(contractChild -> Integer.parseInt(contractChild.get("operNumber").toString()) > 0).collect(Collectors.toList()); + // 如果该合同的商品已经全部下达订单,那说明已经完成了合同的内容 + if (CollectionUtil.isEmpty(contractChildList)) { + iContractService.editCrmContractChildState(entity.getFromId(), "allIssued"); + } else { + iContractService.editCrmContractChildState(entity.getFromId(), "partialRelease"); + } + } + } + } + + @Override + public void approvalEndIsSuccess(SalesOrder entity) { + entity = selectById(entity.getId()); + checkMaterialNorms(entity, true); + } + + /** + * 获取审核通过的销售单列表展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySalesOrderListToTree(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SalesOrder::getState), FlowableStateEnum.PASS.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(SalesOrder::getIdKey), getServiceClassName()); + List salesOrderList = list(queryWrapper); + salesOrderList.forEach(salesOrder -> { + salesOrder.setName(salesOrder.getOddNumber()); + salesOrder.setPId("0"); + }); + outputObject.setBeans(salesOrderList); + outputObject.settotal(salesOrderList.size()); + } + + /** + * 根据销售单id获取子单据列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySalesOrderMaterialListByOrderId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + SalesOrder salesOrder = selectById(id); + outputObject.setBean(salesOrder); + outputObject.setBeans(salesOrder.getErpOrderItemList()); + outputObject.settotal(salesOrder.getErpOrderItemList().size()); + } + + @Override + public void querySealsOrderTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + SalesOrder salesOrder = selectById(id); + // 获取已经入库的数量 + Map normsNum = salesOutLetService.calcMaterialNormsNumByFromId(id); + // 获取已经退货的数量 + Map normsReturnsNum = salesReturnsService.calcMaterialNormsNumByFromId(id); + // 设置未下达销售出库单/销售退货单的商品数量-----订单数量 - 已入库的数量 - 已退货的数量 + super.setOrCheckOperNumber(salesOrder.getErpOrderItemList(), true, normsNum, normsReturnsNum); + // 过滤掉数量为0的进行生成销售出库单/销售退货单 + salesOrder.setErpOrderItemList(salesOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(salesOrder); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertSalesOrderToTurnPut(InputObject inputObject, OutputObject outputObject) { + SalesOutLet salesOutLet = inputObject.getParams(SalesOutLet.class); + // 获取销售单状态 + SalesOrder order = selectById(salesOutLet.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以进行出库 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + salesOutLet.setFromId(salesOutLet.getId()); + salesOutLet.setFromTypeId(SealOutLetFromType.SEAL_ORDER.getKey()); + salesOutLet.setId(StrUtil.EMPTY); + salesOutLetService.createEntity(salesOutLet, userId); + } else { + outputObject.setreturnMessage("状态错误,无法出库."); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertSealsOrderToSealsReturns(InputObject inputObject, OutputObject outputObject) { + SalesReturns salesReturns = inputObject.getParams(SalesReturns.class); + // 获取销售单状态 + SalesOrder order = selectById(salesReturns.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以进行退货 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + salesReturns.setFromId(salesReturns.getId()); + salesReturns.setFromTypeId(SealReturnFromType.SEAL_ORDER.getKey()); + salesReturns.setId(StrUtil.EMPTY); + salesReturnsService.createEntity(salesReturns, userId); + } else { + outputObject.setreturnMessage("状态错误,无法出库."); + } + } + + @Override + public void queryCrmContractTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Map crmContract = iContractService.queryDataMationById(id); + if (CollectionUtil.isEmpty(crmContract)) { + throw new CustomException("该销售合同数据不存在."); + } + String crmContractChildListStr = MapUtil.checkKeyIsNull(crmContract, "crmContractChildList") ? + StrUtil.EMPTY : crmContract.get("crmContractChildList").toString(); + if (StrUtil.isEmpty(crmContractChildListStr)) { + throw new CustomException("该销售合同下未包含商品."); + } + List> contractChildList = JSONUtil.toList(crmContractChildListStr, null); + // 获取已经下达销售订单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(id); + contractChildList.forEach(contractChild -> { + Integer operNumber = Integer.parseInt(contractChild.get("operNumber").toString()); + String normsId = contractChild.get("normsId").toString(); + Integer surplusNum = operNumber + - (executeNum.containsKey(normsId) ? executeNum.get(normsId) : 0); + // 设置未下达销售订单的商品数量 + contractChild.put("operNumber", surplusNum); + }); + // 过滤掉剩余数量为0的商品 + contractChildList = contractChildList.stream() + .filter(contractChild -> Integer.parseInt(contractChild.get("operNumber").toString()) > 0).collect(Collectors.toList()); + + crmContract.put("crmContractChildList", contractChildList); + outputObject.setBean(crmContract); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertCrmContractToSealsOrder(InputObject inputObject, OutputObject outputObject) { + SalesOrder salesOrder = inputObject.getParams(SalesOrder.class); + Map crmContract = iContractService.queryDataMationById(salesOrder.getId()); + if (CollectionUtil.isEmpty(crmContract)) { + throw new CustomException("该销售合同数据不存在."); + } + salesOrder.setFromId(salesOrder.getId()); + salesOrder.setFromTypeId(SealOrderFromType.CUSTOMER_CONTRACT.getKey()); + salesOrder.setId(null); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 保存销售订单 + createEntity(salesOrder, userId); + } + + @Override + public void querySealsOrderTransProductionPlanById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + SalesOrder salesOrder = selectById(id); + // 获取已经下达出货计划单的数量 + Map normsNum = productionPlanService.calcMaterialNormsNumByFromId(id); + // 设置未下达销售出库单/销售退货单的商品数量-----订单数量 - 已经下达出货计划单的数量 + super.setOrCheckOperNumber(salesOrder.getErpOrderItemList(), true, normsNum); + // 过滤掉数量为0的进行生成出货计划单 + salesOrder.setErpOrderItemList(salesOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(salesOrder); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertSealsOrderToProductionPlan(InputObject inputObject, OutputObject outputObject) { + ProductionPlan productionPlan = inputObject.getParams(ProductionPlan.class); + // 获取销售单状态 + SalesOrder order = selectById(productionPlan.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以进行下达出货计划单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + productionPlan.setFromId(productionPlan.getId()); + productionPlan.setFromTypeId(ProductionPlanFromType.SEAL_ORDER.getKey()); + productionPlan.setId(StrUtil.EMPTY); + productionPlanService.createEntity(productionPlan, userId); + } else { + outputObject.setreturnMessage("状态错误,无法出库."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOutLetServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOutLetServiceImpl.java new file mode 100644 index 0000000..12cc3f5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesOutLetServiceImpl.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.seal.classenum.SealOutLetFromType; +import com.skyeye.seal.dao.SalesOutLetDao; +import com.skyeye.seal.entity.SalesOrder; +import com.skyeye.seal.entity.SalesOutLet; +import com.skyeye.seal.service.SalesOrderService; +import com.skyeye.seal.service.SalesOutLetService; +import com.skyeye.seal.service.SalesReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SalesOutLetServiceImpl + * @Description: 销售出库单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "销售出库单", groupName = "销售模块", flowable = true) +public class SalesOutLetServiceImpl extends SkyeyeErpOrderServiceImpl implements SalesOutLetService { + + @Autowired + private SalesOrderService salesOrderService; + + @Autowired + private SalesReturnsService salesReturnsService; + + @Autowired + private DepotOutService depotOutService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置销售订单 + salesOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(SalesOutLet entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(SalesOutLet entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public SalesOutLet selectById(String id) { + SalesOutLet salesOutLet = super.selectById(id); + if (salesOutLet.getFromTypeId() == SealOutLetFromType.SEAL_ORDER.getKey()) { + // 销售订单 + salesOrderService.setDataMation(salesOutLet, SalesOutLet::getFromId); + } + return salesOutLet; + } + + private void checkMaterialNorms(SalesOutLet entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前销售出库单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达销售出库单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == SealOutLetFromType.SEAL_ORDER.getKey()) { + // 销售订单 + checkAndUpdateSalesOrderState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateSalesOrderState(SalesOutLet entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + SalesOrder salesOrder = salesOrderService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(salesOrder.getErpOrderItemList())) { + throw new CustomException("该销售订单下未包含商品."); + } + super.checkFromOrderMaterialNorms(salesOrder.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达销售退货单的商品信息 + Map returnExecuteNum = salesReturnsService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经出库的商品数量 - 已经退货的商品数量 + super.setOrCheckOperNumber(salesOrder.getErpOrderItemList(), setData, orderNormsNum, executeNum, returnExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = salesOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该销售订单的商品已经全部生成了销售出库单/销售退货单,那说明已经完成了销售订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + salesOrderService.editStateById(salesOrder.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + salesOrderService.editStateById(salesOrder.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(SalesOutLet entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void querySalesOutLetTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + SalesOutLet salesOutLet = selectById(id); + // 该销售出库单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(salesOutLet.getId()); + // 设置未下达商品数量-----销售出库单数量 - 已出库数量 + super.setOrCheckOperNumber(salesOutLet.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + salesOutLet.setErpOrderItemList(salesOutLet.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(salesOutLet); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertSalesOutLetToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取销售出库单状态 + SalesOutLet salesOutLet = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(salesOutLet)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(salesOutLet.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.SEAL_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesReturnsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesReturnsServiceImpl.java new file mode 100644 index 0000000..160455b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/seal/service/impl/SalesReturnsServiceImpl.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.seal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.seal.classenum.SealReturnFromType; +import com.skyeye.seal.dao.SalesReturnsDao; +import com.skyeye.seal.entity.SalesOrder; +import com.skyeye.seal.entity.SalesReturns; +import com.skyeye.seal.service.SalesOrderService; +import com.skyeye.seal.service.SalesOutLetService; +import com.skyeye.seal.service.SalesReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SalesReturnsServiceImpl + * @Description: 销售退货单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "销售退货单", groupName = "销售模块", flowable = true) +public class SalesReturnsServiceImpl extends SkyeyeErpOrderServiceImpl implements SalesReturnsService { + + @Autowired + private SalesOrderService salesOrderService; + + @Autowired + private SalesOutLetService salesOutLetService; + + @Autowired + private DepotPutService depotPutService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置销售订单 + salesOrderService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(SalesReturns entity) { + if (entity.getNeedDepot() == WhetherEnum.ENABLE_USING.getKey()) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + } else { + entity.setOtherState(DepotPutState.NOT_NEED_PUT.getKey()); + } + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(SalesReturns entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public SalesReturns selectById(String id) { + SalesReturns salesOutLet = super.selectById(id); + if (salesOutLet.getFromTypeId() == SealReturnFromType.SEAL_ORDER.getKey()) { + // 销售订单 + salesOrderService.setDataMation(salesOutLet, SalesReturns::getFromId); + } + return salesOutLet; + } + + private void checkMaterialNorms(SalesReturns entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前销售退货单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达销售退货单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == SealReturnFromType.SEAL_ORDER.getKey()) { + // 销售订单 + checkAndUpdateSalesOrderState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateSalesOrderState(SalesReturns entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + SalesOrder salesOrder = salesOrderService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(salesOrder.getErpOrderItemList())) { + throw new CustomException("该销售订单下未包含商品."); + } + super.checkFromOrderMaterialNorms(salesOrder.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达销售出库单的商品信息 + Map returnExecuteNum = salesOutLetService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 来源单据的商品数量 - 当前单据的商品数量 - 已经出库的商品数量 - 已经退货的商品数量 + super.setOrCheckOperNumber(salesOrder.getErpOrderItemList(), setData, orderNormsNum, executeNum, returnExecuteNum); + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = salesOrder.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该销售订单的商品已经全部生成了销售出库单/销售退货单,那说明已经完成了销售订单的内容 + if (CollectionUtil.isEmpty(erpOrderItemList)) { + salesOrderService.editStateById(salesOrder.getId(), ErpOrderStateEnum.COMPLETED.getKey()); + } else { + salesOrderService.editStateById(salesOrder.getId(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(SalesReturns entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + } + + @Override + public void querySalesReturnsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + SalesReturns salesReturns = selectById(id); + if (salesReturns.getNeedDepot() == WhetherEnum.DISABLE_USING.getKey()) { + throw new CustomException("该销售退货单无需进行转入库操作"); + } + // 该销售退货单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(salesReturns.getId()); + // 设置未下达商品数量-----销售退货单数量 - 已入库数量 + super.setOrCheckOperNumber(salesReturns.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + salesReturns.setErpOrderItemList(salesReturns.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(salesReturns); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertSalesReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取销售退货单状态 + SalesReturns salesReturns = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(salesReturns)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(salesReturns.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.SEAL_RETURNS.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpCommonService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpCommonService.java new file mode 100644 index 0000000..576abec --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpCommonService.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ErpCommonService + * @Description: ERP公共服务 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 21:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpCommonService { + + void queryDepotHeadDetailsMationById(InputObject inputObject, OutputObject outputObject); + + void deleteErpOrderById(InputObject inputObject, OutputObject outputObject); + + /** + * 修改商品规格库存 + * + * @param depotId 仓库id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 出入库类型,参考#DepotPutOutType + */ + void editMaterialNormsDepotStock(String depotId, String materialId, String normsId, Integer operNumber, int type); + + void editDepotHeadToRevoke(InputObject inputObject, OutputObject outputObject); + + void orderSubmitToApproval(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpPageService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpPageService.java new file mode 100644 index 0000000..c5ccbce --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/ErpPageService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ErpPageService + * @Description: ERP统计模块服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/2 11:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ErpPageService { + + void queryFourTypeMoneyList(InputObject inputObject, OutputObject outputObject); + + void querySixMonthPurchaseMoneyList(InputObject inputObject, OutputObject outputObject); + + void querySixMonthSealsMoneyList(InputObject inputObject, OutputObject outputObject); + + void queryTwelveMonthProfitMoneyList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/StatisticsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/StatisticsService.java new file mode 100644 index 0000000..21a23e3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/StatisticsService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface StatisticsService { + + void queryWarehousingDetails(InputObject inputObject, OutputObject outputObject); + + void queryOutgoingDetails(InputObject inputObject, OutputObject outputObject); + + void queryInComimgDetails(InputObject inputObject, OutputObject outputObject); + + void querySalesDetails(InputObject inputObject, OutputObject outputObject); + + void queryCustomerReconciliationDetails(InputObject inputObject, OutputObject outputObject); + + void querySupplierReconciliationDetails(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpCommonServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpCommonServiceImpl.java new file mode 100644 index 0000000..65fb8ae --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpCommonServiceImpl.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.eve.flowable.classenum.FormSubType; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.util.RedisLock; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsStock; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialNormsStockService; +import com.skyeye.service.ErpCommonService; +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 java.util.Map; + +/** + * @ClassName: ErpCommonServiceImpl + * @Description: ERP公共服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ErpCommonServiceImpl implements ErpCommonService { + + private static Logger LOGGER = LoggerFactory.getLogger(ErpCommonServiceImpl.class); + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private MaterialNormsStockService materialNormsStockService; + + /** + * 获取单据详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDepotHeadDetailsMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String serviceClassName = map.get("serviceClassName").toString(); + String id = map.get("id").toString(); + try { + Class clazz = Class.forName(serviceClassName); + SkyeyeErpOrderService skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + Object object = skyeyeErpOrderService.selectById(id); + outputObject.setBean(object); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } catch (Exception ex) { + throw new RuntimeException("queryDepotHeadDetailsMationById error", ex); + } + } + + /** + * 删除单据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteErpOrderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String serviceClassName = map.get("serviceClassName").toString(); + String id = map.get("id").toString(); + try { + Class clazz = Class.forName(serviceClassName); + SkyeyeErpOrderService skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + skyeyeErpOrderService.deleteById(id); + } catch (Exception ex) { + throw new RuntimeException("deleteErpOrderById error", ex); + } + } + + /** + * 修改商品规格库存 + * + * @param depotId 仓库id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 出入库类型,参考#DepotPutOutType + */ + @Override + public void editMaterialNormsDepotStock(String depotId, String materialId, String normsId, Integer operNumber, int type) { + String lockKey = String.format("%s_%s", depotId, normsId); + RedisLock lock = new RedisLock(lockKey); + try { + if (!lock.lock()) { + // 加锁失败 + throw new CustomException("增减库存失败,当前并发量较大,请稍后再次尝试."); + } + LOGGER.info("get lock success, lockKey is {}.", lockKey); + // 查询规格库存信息 + MaterialNorms materialNorms = materialNormsService.queryMaterialNorms(normsId, depotId); + int depotAllStock = ObjectUtil.isNotEmpty(materialNorms.getDepotTock()) ? materialNorms.getDepotTock().getAllStock() : CommonNumConstants.NUM_ZERO; + depotAllStock = getNewStockNum(type, operNumber, depotAllStock); + // 减去初始库存 + if (CollectionUtil.isNotEmpty(materialNorms.getNormsStock())) { + MaterialNormsStock materialNormsStock = materialNorms.getNormsStock().stream() + .filter(normsStock -> StrUtil.equals(normsStock.getDepotId(), depotId)).findFirst().orElse(null); + if (ObjectUtil.isNotEmpty(materialNormsStock)) { + depotAllStock = depotAllStock - materialNormsStock.getStock(); + } + } + materialNormsStockService.saveMaterialNormsOrderStock(materialId, depotId, normsId, depotAllStock); + LOGGER.info("editMaterialNormsDepotStock is success."); + } catch (Exception ee) { + LOGGER.warn("editMaterialNormsDepotStock error, because {}", ee); + if (ee instanceof CustomException) { + throw new CustomException(ee.getMessage()); + } + throw new RuntimeException(ee.getMessage()); + } finally { + lock.unlock(); + } + } + + private int getNewStockNum(int type, int changeNumber, int depotAllStock) { + if (type == DepotPutOutType.PUT.getKey()) { + // 入库 + depotAllStock = depotAllStock + changeNumber; + } else if (type == DepotPutOutType.OUT.getKey()) { + // 出库 + depotAllStock = depotAllStock - changeNumber; + } + if (depotAllStock < 0) { + throw new CustomException("当前库存不足,无法操作."); + } + return depotAllStock; + } + + /** + * erp相关单据撤销审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editDepotHeadToRevoke(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String serviceClassName = map.get("serviceClassName").toString(); + String processInstanceId = map.get("processInstanceId").toString(); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + try { + Class clazz = Class.forName(serviceClassName); + SkyeyeErpOrderService skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + skyeyeErpOrderService.revoke(processInstanceId, userId); + } catch (Exception ex) { + throw new RuntimeException("editDepotHeadToRevoke error", ex); + } + } + + /** + * 订单信息提交审核 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void orderSubmitToApproval(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String serviceClassName = map.get("serviceClassName").toString(); + String id = map.get("id").toString(); + String approvalId = map.get("approvalId").toString(); + try { + Class clazz = Class.forName(serviceClassName); + SkyeyeErpOrderService skyeyeErpOrderService = (SkyeyeErpOrderService) SpringUtils.getBean(clazz); + skyeyeErpOrderService.submitToApproval(id, FormSubType.SUB_FLOWABLE.getKey(), approvalId); + } catch (Exception ex) { + throw new RuntimeException("orderSubmitToApproval error", ex); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpPageServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpPageServiceImpl.java new file mode 100644 index 0000000..77600e3 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/ErpPageServiceImpl.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.dao.ErpPageDao; +import com.skyeye.other.service.impl.OtherOutLetsServiceImpl; +import com.skyeye.purchase.service.impl.PurchaseOrderServiceImpl; +import com.skyeye.purchase.service.impl.PurchaseReturnsServiceImpl; +import com.skyeye.retail.service.impl.RetailOutLetServiceImpl; +import com.skyeye.seal.service.impl.SalesOrderServiceImpl; +import com.skyeye.seal.service.impl.SalesOutLetServiceImpl; +import com.skyeye.service.ErpPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ErpPageServiceImpl + * @Description: ERP统计模块服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/2 11:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ErpPageServiceImpl implements ErpPageService { + + @Autowired + private ErpPageDao erpPageDao; + + /** + * 获取本月累计销售,本月累计零售,本月累计采购,本月利润(已审核通过) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFourTypeMoneyList(InputObject inputObject, OutputObject outputObject) { + List states = Arrays.asList(FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.COMPLETED.getKey()); + // 1.获取本月累计销售,当前月已审核通过的销售订单金额 + String salesMoney = erpPageDao.queryThisMonthErpOrder(SalesOrderServiceImpl.class.getName(), states); + // 2.获取本月累计零售,当前月已审核通过的零售订单金额 + String retailMoney = erpPageDao.queryThisMonthErpOrder(RetailOutLetServiceImpl.class.getName(), states); + // 3.获取本月累计采购,当前月已审核通过的采购订单金额 + String purchaseMoney = erpPageDao.queryThisMonthErpOrder(PurchaseOrderServiceImpl.class.getName(), states); + // 4.本月利润(已审核通过),零售订单金额 + 销售订单金额 - 采购订单金额 + String profitMoney = CalculationUtil.subtract(CalculationUtil.add(salesMoney, retailMoney), purchaseMoney); + Map map = new HashMap<>(); + map.put("salesMoney", salesMoney); + map.put("retailMoney", retailMoney); + map.put("purchaseMoney", purchaseMoney); + map.put("profitMoney", profitMoney); + outputObject.setBean(map); + } + + /** + * 获取近半年的采购统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySixMonthPurchaseMoneyList(InputObject inputObject, OutputObject outputObject) { + List states = Arrays.asList(FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.COMPLETED.getKey()); + List> beans = erpPageDao.querySixMonthOrderMoneyList(PurchaseOrderServiceImpl.class.getName(), states); + outputObject.setBeans(beans); + } + + /** + * 获取近半年的销售统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySixMonthSealsMoneyList(InputObject inputObject, OutputObject outputObject) { + List states = Arrays.asList(FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.COMPLETED.getKey()); + List> beans = erpPageDao.querySixMonthOrderMoneyList(SalesOrderServiceImpl.class.getName(), states); + outputObject.setBeans(beans); + } + + /** + * 获取近十二个月的利润统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryTwelveMonthProfitMoneyList(InputObject inputObject, OutputObject outputObject) { + List states = Arrays.asList(FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.COMPLETED.getKey()); + List idKeys = Arrays.asList(SalesOrderServiceImpl.class.getName(), + PurchaseOrderServiceImpl.class.getName(), + RetailOutLetServiceImpl.class.getName()); + List> beans = erpPageDao.queryTwelveMonthProfitMoneyList(idKeys, states); + outputObject.setBeans(beans); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/StatisticsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/StatisticsServiceImpl.java new file mode 100644 index 0000000..33c92ad --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/service/impl/StatisticsServiceImpl.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.base.handler.enclosure.helper.ServiceBeanToEntityHelper; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CorrespondentEnterEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.crm.service.ICustomerService; +import com.skyeye.dao.StatisticsDao; +import com.skyeye.depot.service.ErpDepotService; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.other.service.impl.OtherOutLetsServiceImpl; +import com.skyeye.other.service.impl.OtherWareHousServiceImpl; +import com.skyeye.purchase.service.impl.PurchasePutServiceImpl; +import com.skyeye.purchase.service.impl.PurchaseReturnsServiceImpl; +import com.skyeye.retail.service.impl.RetailOutLetServiceImpl; +import com.skyeye.retail.service.impl.RetailReturnsServiceImpl; +import com.skyeye.seal.service.impl.SalesOutLetServiceImpl; +import com.skyeye.seal.service.impl.SalesReturnsServiceImpl; +import com.skyeye.service.StatisticsService; +import com.skyeye.supplier.service.SupplierService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: StatisticsServiceImpl + * @Description: erp统计服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class StatisticsServiceImpl implements StatisticsService { + + @Autowired + private StatisticsDao statisticsDao; + + @Autowired + protected MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + protected ErpDepotService erpDepotService; + + @Autowired + protected ICustomerService iCustomerService; + + @Autowired + protected SupplierService supplierService; + + /** + * 入库明细 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryWarehousingDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setObjectBusiness(Arrays.asList( + PurchasePutServiceImpl.class.getName(), + SalesReturnsServiceImpl.class.getName(), + RetailReturnsServiceImpl.class.getName(), + OtherWareHousServiceImpl.class.getName() + )); + getBeans(outputObject, pageInfo); + } + + private void getBeans(OutputObject outputObject, CommonPageInfo pageInfo) { + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setState(FlowableStateEnum.PASS.getKey()); + List> beans = statisticsDao.queryErpOrderItem(pageInfo); + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + erpDepotService.setMationForMap(beans, "depotId", "depotMation"); + beans.forEach(bean -> { + String idKey = bean.get("idKey").toString(); + String serviceName = ServiceBeanToEntityHelper.getServiceName(idKey); + bean.put("serviceName", serviceName); + }); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 出库明细 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryOutgoingDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setObjectBusiness(Arrays.asList( + SalesOutLetServiceImpl.class.getName(), + PurchaseReturnsServiceImpl.class.getName(), + RetailOutLetServiceImpl.class.getName(), + OtherOutLetsServiceImpl.class.getName() + )); + getBeans(outputObject, pageInfo); + } + + /** + * 进货统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInComimgDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + // ERP入库操作相关单据类型的集合 + List subTypeList = Arrays.asList(PurchasePutServiceImpl.class.getName(), + SalesReturnsServiceImpl.class.getName(), + RetailReturnsServiceImpl.class.getName(), + OtherWareHousServiceImpl.class.getName()); + + // ERP退货入库操作相关单据类型的集合 + List returnSubTypeList = Arrays.asList(SalesReturnsServiceImpl.class.getName(), + RetailReturnsServiceImpl.class.getName()); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + List> beans = getPointSubTypeOrderStatistics(commonPageInfo, subTypeList, returnSubTypeList); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + private List> getPointSubTypeOrderStatistics(CommonPageInfo commonPageInfo, List allSubType, List returnSubTyoe) { + commonPageInfo.setObjectBusiness(allSubType); + List> beans = statisticsDao.queryPointSubTypeOrder(commonPageInfo); + + commonPageInfo.setObjectBusiness(returnSubTyoe); + List> returnBeans = statisticsDao.queryPointSubTypeOrder(commonPageInfo); + Map> returnMaps = returnBeans.stream().collect(Collectors.toMap(bean -> bean.get("normsId").toString(), bean -> bean)); + + // 设置退货入库的数量信息 + beans.forEach(bean -> { + String normsId = bean.get("normsId").toString(); + Map returnBean = returnMaps.get(normsId); + if (CollectionUtils.isEmpty(returnBean)) { + bean.put("returnCurrentTock", CommonNumConstants.NUM_ZERO); + bean.put("returnCurrentTockMoney", CommonNumConstants.NUM_ZERO); + } else { + bean.put("returnCurrentTock", returnBean.get("currentTock")); + bean.put("returnCurrentTockMoney", returnBean.get("currentTockMoney")); + } + }); + // 获取商品规格信息 + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + return beans; + } + + /** + * 销售统计 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySalesDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + // ERP出库操作相关单据类型的集合 + List subTypeList = Arrays.asList(SalesOutLetServiceImpl.class.getName(), + PurchaseReturnsServiceImpl.class.getName(), + RetailOutLetServiceImpl.class.getName(), + OtherOutLetsServiceImpl.class.getName()); + + // ERP退货出库操作相关单据类型的集合 + List returnSubTypeList = Arrays.asList(PurchaseReturnsServiceImpl.class.getName()); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + List> beans = getPointSubTypeOrderStatistics(commonPageInfo, subTypeList, returnSubTypeList); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 客户对账 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCustomerReconciliationDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setState(FlowableStateEnum.PASS.getKey()); + pageInfo.setHolderKey(CorrespondentEnterEnum.CUSTOM.getKey()); + List> beans = statisticsDao.queryErpOrderListByIdKey(pageInfo); + iCustomerService.setMationForMap(beans, "holderId", "holderMation"); + beans.forEach(bean -> { + String idKey = bean.get("idKey").toString(); + String serviceName = ServiceBeanToEntityHelper.getServiceName(idKey); + bean.put("serviceName", serviceName); + }); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 供应商对账 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySupplierReconciliationDetails(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setState(FlowableStateEnum.PASS.getKey()); + pageInfo.setHolderKey(CorrespondentEnterEnum.SUPPLIER.getKey()); + List> beans = statisticsDao.queryErpOrderListByIdKey(pageInfo); + supplierService.setMationForMap(beans, "holderId", "holderMation"); + beans.forEach(bean -> { + String idKey = bean.get("idKey").toString(); + String serviceName = ServiceBeanToEntityHelper.getServiceName(idKey); + bean.put("serviceName", serviceName); + }); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/ShopConfirmFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/ShopConfirmFromType.java new file mode 100644 index 0000000..3818080 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/ShopConfirmFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ConfirmFromType + * @Description: 物料接收单/物料退货单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopConfirmFromType implements SkyeyeEnumClass { + + DEPOT_OUT(1, "仓库出库单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/StoreNormsCodeUseState.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/StoreNormsCodeUseState.java new file mode 100644 index 0000000..4499086 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/classenum/StoreNormsCodeUseState.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: StoreNormsCodeUseState + * @Description: 门店使用时的状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/31 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum StoreNormsCodeUseState implements SkyeyeEnumClass { + + WAIT_USE(1, "待使用", "red", true, false), + USED(2, "已使用", "green", true, false); + + private Integer key; + + private String value; + + private String color; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmPutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmPutController.java new file mode 100644 index 0000000..066edbd --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmPutController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shop.entity.ShopConfirmPut; +import com.skyeye.shop.service.ShopConfirmPutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopConfirmPutController + * @Description: 物料接收单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "物料接收单", tags = "物料接收单", modelName = "门店") +public class ShopConfirmPutController { + + @Autowired + private ShopConfirmPutService shopConfirmPutService; + + /** + * 获取物料接收单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopConfirmPutList", value = "获取物料接收单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopConfirmPutController/queryShopConfirmPutList") + public void queryShopConfirmPutList(InputObject inputObject, OutputObject outputObject) { + shopConfirmPutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑物料接收单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopConfirmPut", value = "新增/编辑物料接收单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopConfirmPut.class) + @RequestMapping("/post/ShopConfirmPutController/writeShopConfirmPut") + public void writeShopConfirmPut(InputObject inputObject, OutputObject outputObject) { + shopConfirmPutService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmReturnController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmReturnController.java new file mode 100644 index 0000000..a32d043 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopConfirmReturnController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.shop.entity.ShopConfirmReturn; +import com.skyeye.shop.service.ShopConfirmReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopConfirmReturnController + * @Description: 物料退货单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "物料退货单", tags = "物料退货单", modelName = "门店") +public class ShopConfirmReturnController { + + @Autowired + private ShopConfirmReturnService shopConfirmReturnService; + + /** + * 获取物料退货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopConfirmReturnList", value = "获取物料退货单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopConfirmReturnController/queryShopConfirmReturnList") + public void queryShopConfirmReturnList(InputObject inputObject, OutputObject outputObject) { + shopConfirmReturnService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑物料退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopConfirmReturn", value = "新增/编辑物料退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopConfirmReturn.class) + @RequestMapping("/post/ShopConfirmReturnController/writeShopConfirmReturn") + public void writeShopConfirmReturn(InputObject inputObject, OutputObject outputObject) { + shopConfirmReturnService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询物料退货信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopConfirmReturnTransById", value = "转仓库入库单时,根据id查询物料退货信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopConfirmReturnController/queryShopConfirmReturnTransById") + public void queryShopConfirmReturnTransById(InputObject inputObject, OutputObject outputObject) { + shopConfirmReturnService.queryShopConfirmReturnTransById(inputObject, outputObject); + } + + /** + * 物料退货单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertShopConfirmReturnToTurnDepot", value = "物料退货单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopConfirmReturnController/insertShopConfirmReturnToTurnDepot") + public void insertShopConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject) { + shopConfirmReturnService.insertShopConfirmReturnToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopOutLetsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopOutLetsController.java new file mode 100644 index 0000000..ebe383e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopOutLetsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.shop.entity.ShopOutLets; +import com.skyeye.shop.service.ShopOutLetsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopOutLetsController + * @Description: 门店申领单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店申领单", tags = "门店申领单", modelName = "门店") +public class ShopOutLetsController { + + @Autowired + private ShopOutLetsService shopOutLetsService; + + /** + * 获取门店申领单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopOutLetsList", value = "获取门店申领单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopOutLetsController/queryShopOutLetsList") + public void queryShopOutLetsList(InputObject inputObject, OutputObject outputObject) { + shopOutLetsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑门店申领单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopOutLets", value = "新增/编辑门店申领单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopOutLets.class) + @RequestMapping("/post/ShopOutLetsController/writeShopOutLets") + public void writeShopOutLets(InputObject inputObject, OutputObject outputObject) { + shopOutLetsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库出库单时,根据id查询门店申领单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopOutLetsTransById", value = "转仓库出库单时,根据id查询门店申领单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopOutLetsController/queryShopOutLetsTransById") + public void queryShopOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + shopOutLetsService.queryShopOutLetsTransById(inputObject, outputObject); + } + + /** + * 门店申领单信息转仓库出库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertShopOutLetsToTurnDepot", value = "门店申领单信息转仓库出库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotOut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopOutLetsController/insertShopOutLetsToTurnDepot") + public void insertShopOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + shopOutLetsService.insertShopOutLetsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopReturnsController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopReturnsController.java new file mode 100644 index 0000000..410c92a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopReturnsController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.shop.entity.ShopReturns; +import com.skyeye.shop.service.ShopReturnsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopReturnsController + * @Description: 门店退货单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店退货单", tags = "门店退货单", modelName = "门店") +public class ShopReturnsController { + + @Autowired + private ShopReturnsService shopReturnsService; + + /** + * 获取门店退货单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopReturnsList", value = "获取门店退货单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopReturnsController/queryShopReturnsList") + public void queryShopReturnsList(InputObject inputObject, OutputObject outputObject) { + shopReturnsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑门店退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopReturns", value = "新增/编辑门店退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopReturns.class) + @RequestMapping("/post/ShopReturnsController/writeShopReturns") + public void writeShopReturns(InputObject inputObject, OutputObject outputObject) { + shopReturnsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转仓库入库单时,根据id查询门店退货单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopReturnsTransById", value = "转仓库入库单时,根据id查询门店退货单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopReturnsController/queryShopReturnsTransById") + public void queryShopReturnsTransById(InputObject inputObject, OutputObject outputObject) { + shopReturnsService.queryShopReturnsTransById(inputObject, outputObject); + } + + /** + * 门店退货单信息转仓库入库单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertShopReturnsToTurnDepot", value = "门店退货单信息转仓库入库单", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DepotPut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopReturnsController/insertShopReturnsToTurnDepot") + public void insertShopReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + shopReturnsService.insertShopReturnsToTurnDepot(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopStockController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopStockController.java new file mode 100644 index 0000000..f89b75c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/controller/ShopStockController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shop.service.ShopStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopStockController + * @Description: 门店物料库存信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/20 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店物料库存信息", tags = "门店物料库存信息", modelName = "门店") +public class ShopStockController { + + @Autowired + private ShopStockService shopStockService; + + /** + * 获取门店物料库存信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopStockList", value = "获取门店物料库存信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopStockController/queryShopStockList") + public void queryShopStockList(InputObject inputObject, OutputObject outputObject) { + shopStockService.queryPageList(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmPutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmPutDao.java new file mode 100644 index 0000000..cb1749c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmPutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shop.entity.ShopConfirmPut; + +/** + * @ClassName: ShopConfirmPutDao + * @Description: 物料接收单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopConfirmPutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmReturnDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmReturnDao.java new file mode 100644 index 0000000..c15d48a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopConfirmReturnDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shop.entity.ShopConfirmReturn; + +/** + * @ClassName: ShopConfirmReturnDao + * @Description: 物料退货单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopConfirmReturnDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopOutLetsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopOutLetsDao.java new file mode 100644 index 0000000..1f3b4d0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopOutLetsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shop.entity.ShopOutLets; + +/** + * @ClassName: ShopOutLetsDao + * @Description: 门店申领单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopOutLetsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopReturnsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopReturnsDao.java new file mode 100644 index 0000000..6d1edb0 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopReturnsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shop.entity.ShopReturns; + +/** + * @ClassName: ShopReturnsDao + * @Description: 门店退货单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 18:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopReturnsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopStockDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopStockDao.java new file mode 100644 index 0000000..7ebdae2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/dao/ShopStockDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shop.entity.ShopStock; + +/** + * @ClassName: ShopStockDao + * @Description: 门店物料库存信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:56 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStockDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmPut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmPut.java new file mode 100644 index 0000000..c5d188f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmPut.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ShopConfirmPut + * @Description: 物料接收单 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:shopConfirmPut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("物料接收单实体类") +public class ShopConfirmPut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmReturn.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmReturn.java new file mode 100644 index 0000000..ebdd507 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopConfirmReturn.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ShopConfirmReturn + * @Description: 物料退货单 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:shopConfirmReturn", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("物料退货单实体类") +public class ShopConfirmReturn extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopOutLets.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopOutLets.java new file mode 100644 index 0000000..4f45383 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopOutLets.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: ShopOutLets + * @Description: 门店申领单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:shopOutLets", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("门店申领单实体类") +public class ShopOutLets extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopReturns.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopReturns.java new file mode 100644 index 0000000..1359217 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopReturns.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: SalesReturns + * @Description: 门店退货单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:shopReturns", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("门店退货单实体类") +public class ShopReturns extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopStock.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopStock.java new file mode 100644 index 0000000..3a9ae21 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/entity/ShopStock.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ShopStock + * @Description: 门店物料库存信息 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:50 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_stock") +@ApiModel("门店物料库存信息") +public class ShopStock extends CommonInfo { + + @TableField(value = "material_id") + @Property(value = "产品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "store_id") + @Property(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + + @TableField(value = "stock") + @Property(value = "数量") + private Integer stock; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmPutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmPutService.java new file mode 100644 index 0000000..52a990c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmPutService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.shop.entity.ShopConfirmPut; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopConfirmPutService + * @Description: 物料接收单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopConfirmPutService extends SkyeyeErpOrderService { + + Map> calcMaterialNormsCodeByFromId(String fromId); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmReturnService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmReturnService.java new file mode 100644 index 0000000..65f2eda --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopConfirmReturnService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shop.entity.ShopConfirmReturn; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopConfirmReturnService + * @Description: 物料退货单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopConfirmReturnService extends SkyeyeErpOrderService { + + void queryShopConfirmReturnTransById(InputObject inputObject, OutputObject outputObject); + + void insertShopConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject); + + Map> calcMaterialNormsCodeByFromId(String fromId); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopOutLetsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopOutLetsService.java new file mode 100644 index 0000000..c74799f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopOutLetsService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.other.entity.OtherOutLets; +import com.skyeye.shop.entity.ShopOutLets; + +/** + * @ClassName: ShopOutLetsService + * @Description: 门店申领单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopOutLetsService extends SkyeyeErpOrderService { + + void queryShopOutLetsTransById(InputObject inputObject, OutputObject outputObject); + + void insertShopOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopReturnsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopReturnsService.java new file mode 100644 index 0000000..568ca1a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopReturnsService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.seal.entity.SalesReturns; +import com.skyeye.shop.entity.ShopReturns; + +/** + * @ClassName: ShopReturnsService + * @Description: 门店退货单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopReturnsService extends SkyeyeErpOrderService { + + void queryShopReturnsTransById(InputObject inputObject, OutputObject outputObject); + + void insertShopReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopStockService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopStockService.java new file mode 100644 index 0000000..6abc4b9 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/ShopStockService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.shop.entity.ShopStock; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopStockService + * @Description: 门店物料库存信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStockService extends SkyeyeBusinessService { + + /** + * 修改门店物料库存存量信息 + * + * @param storeId 门店id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 出入库类型,参考#DepotPutOutType + */ + void updateShopStock(String storeId, String materialId, String normsId, Integer operNumber, int type); + + ShopStock queryShopStock(String storeId, String normsId); + + Map queryNormsShopStock(String storeId, List normsIds); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmPutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmPutServiceImpl.java new file mode 100644 index 0000000..e65a379 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmPutServiceImpl.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutOtherState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.ErpOrderItemCode; +import com.skyeye.exception.CustomException; +import com.skyeye.farm.service.FarmService; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.classenum.ShopConfirmFromType; +import com.skyeye.shop.classenum.StoreNormsCodeUseState; +import com.skyeye.shop.dao.ShopConfirmPutDao; +import com.skyeye.shop.entity.ShopConfirmPut; +import com.skyeye.shop.service.ShopConfirmPutService; +import com.skyeye.shop.service.ShopConfirmReturnService; +import com.skyeye.shop.service.ShopStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopConfirmPutServiceImpl + * @Description: 物料接收单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "物料接收单", groupName = "门店", flowable = true) +public class ShopConfirmPutServiceImpl extends SkyeyeErpOrderServiceImpl implements ShopConfirmPutService { + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private ShopConfirmReturnService shopConfirmReturnService; + + @Autowired + private ShopStockService shopStockService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置仓库出库单 + depotOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + // 门店 + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + return beans; + } + + @Override + public void validatorEntity(ShopConfirmPut entity) { + if (StrUtil.isNotEmpty(entity.getId())) { + ShopConfirmPut shopConfirmPut = selectById(entity.getId()); + entity.setFromId(shopConfirmPut.getFromId()); + entity.setFromTypeId(shopConfirmPut.getFromTypeId()); + entity.setStoreId(shopConfirmPut.getStoreId()); + entity.setSalesman(shopConfirmPut.getSalesman()); + } + checkMaterialNorms(entity, false); + checkNormsCodeAndSave(entity, true); + } + + @Override + public void createPrepose(ShopConfirmPut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ShopConfirmPut entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ShopConfirmPut getDataFromDb(String id) { + ShopConfirmPut shopConfirmPut = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(shopConfirmPut); + return shopConfirmPut; + } + + @Override + public ShopConfirmPut selectById(String id) { + ShopConfirmPut shopConfirmPut = super.selectById(id); + if (shopConfirmPut.getFromTypeId() == ShopConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + depotOutService.setDataMation(shopConfirmPut, ShopConfirmPut::getFromId); + } + // 门店 + iShopStoreService.setDataMation(shopConfirmPut, ShopConfirmPut::getStoreId); + // 部门 + iDepmentService.setDataMation(shopConfirmPut, ShopConfirmPut::getDepartmentId); + return shopConfirmPut; + } + + private void checkMaterialNorms(ShopConfirmPut entity, boolean setData) { + // 当前物料接收单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达物料接收单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ShopConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(ShopConfirmPut entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(depotOut.getErpOrderItemList())) { + throw new CustomException("该仓库出库单下未包含商品."); + } + super.checkFromOrderMaterialNorms(depotOut.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达物料退货单的商品信息 + Map returnExecuteNum = shopConfirmReturnService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 仓库出库单数量 - 当前单据数量 - 已经下达物料接收单的数量 - 已经下达物料退货单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), setData, orderNormsNum, executeNum, returnExecuteNum); + + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } else { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(ShopConfirmPut entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, false); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 接收需要入库到对应的门店的仓库下 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndSave(ShopConfirmPut entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和来源单据的条形码作对比 + // 获取来源单据中的条形码的信息 + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + List inFromOrderNormsCodeList = depotOut.getErpOrderItemList().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(norms -> norms.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在来源单据中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inFromOrderNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在来源出库单中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和数据库中条形码的状态做对比 + // 2.1 从数据库查询出库状态的条形码信息, + // 2.2 只有门店信息为空的说明没有领料,才可以进行物料接收。门店信息不为空,说明该条形码已经在门店的库存里 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream().filter(bean -> StrUtil.isEmpty(bean.getStoreId())) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/已经存在其他仓库中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setStoreId(entity.getStoreId()); + materialNormsCode.setStoreUseState(StoreNormsCodeUseState.WAIT_USE.getKey()); + }); + materialNormsCodeService.updateEntityPick(materialNormsCodeList); + } + } + if (!onlyCheck) { + // 修改门店的库存 + entity.getErpOrderItemList().forEach(erpOrderItem -> { + shopStockService.updateShopStock(entity.getStoreId(), erpOrderItem.getMaterialId(), + erpOrderItem.getNormsId(), erpOrderItem.getOperNumber(), DepotPutOutType.PUT.getKey()); + }); + } + return allNormsCodeList; + } + + @Override + public Map> calcMaterialNormsCodeByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopConfirmPut::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopConfirmPut::getIdKey), getServiceClassName()); + // 只查询审批通过,部分出入库,已完成的单据 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopConfirmPut::getState), stateList); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(ShopConfirmPut::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + // 查询单据子表关联的条形码编号信息 + List erpOrderItemCodeList = erpOrderItemCodeService.selectByParentId(ids.toArray(new String[]{})); + Map> listMap = erpOrderItemCodeList.stream().collect(Collectors.groupingBy(ErpOrderItemCode::getNormsId)); + erpOrderItemList.forEach(erpOrderItem -> { + List erpOrderItemCodes = listMap.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isNotEmpty(erpOrderItemCodes)) { + List normsCodeList = erpOrderItemCodes.stream().map(ErpOrderItemCode::getNormsCode).collect(Collectors.toList()); + erpOrderItem.setNormsCodeList(normsCodeList); + erpOrderItem.setNormsCode(Joiner.on("\n").join(normsCodeList)); + } + }); + Map> collect = erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.mapping(ErpOrderItem::getNormsCodeList, + Collectors.reducing( + new ArrayList<>(), + Function.identity(), + (l1, l2) -> { + if (CollectionUtil.isNotEmpty(l2)) { + l1.addAll(l2); + } + return l1; + } + )))); + return collect; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmReturnServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmReturnServiceImpl.java new file mode 100644 index 0000000..7b73c47 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopConfirmReturnServiceImpl.java @@ -0,0 +1,320 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutOtherState; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.entity.ErpOrderItemCode; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.classenum.ShopConfirmFromType; +import com.skyeye.shop.dao.ShopConfirmReturnDao; +import com.skyeye.shop.entity.ShopConfirmReturn; +import com.skyeye.shop.service.ShopConfirmPutService; +import com.skyeye.shop.service.ShopConfirmReturnService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ConfirmReturnServiceImpl + * @Description: 物料退货单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/27 10:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "物料退货单", groupName = "门店", flowable = true) +public class ShopConfirmReturnServiceImpl extends SkyeyeErpOrderServiceImpl implements ShopConfirmReturnService { + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private ShopConfirmPutService shopConfirmPutService; + + @Autowired + private DepotPutService depotPutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置仓库出库单 + depotOutService.setOrderMationByFromId(beans, "fromId", "fromMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + // 门店 + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + return beans; + } + + @Override + public void validatorEntity(ShopConfirmReturn entity) { + if (StrUtil.isNotEmpty(entity.getId())) { + ShopConfirmReturn shopConfirmReturn = selectById(entity.getId()); + entity.setFromId(shopConfirmReturn.getFromId()); + entity.setFromTypeId(shopConfirmReturn.getFromTypeId()); + entity.setStoreId(shopConfirmReturn.getStoreId()); + entity.setSalesman(shopConfirmReturn.getSalesman()); + } + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + checkMaterialNorms(entity, false); + checkNormsCodeAndSave(entity); + } + + @Override + public void createPrepose(ShopConfirmReturn entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ShopConfirmReturn entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ShopConfirmReturn getDataFromDb(String id) { + ShopConfirmReturn shopConfirmReturn = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(shopConfirmReturn); + return shopConfirmReturn; + } + + @Override + public ShopConfirmReturn selectById(String id) { + ShopConfirmReturn shopConfirmReturn = super.selectById(id); + if (shopConfirmReturn.getFromTypeId() == ShopConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + depotOutService.setDataMation(shopConfirmReturn, ShopConfirmReturn::getFromId); + } + // 门店 + iShopStoreService.setDataMation(shopConfirmReturn, ShopConfirmReturn::getStoreId); + // 部门 + iDepmentService.setDataMation(shopConfirmReturn, ShopConfirmReturn::getDepartmentId); + return shopConfirmReturn; + } + + private void checkMaterialNorms(ShopConfirmReturn entity, boolean setData) { + // 当前物料退货单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达物料退货单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == ShopConfirmFromType.DEPOT_OUT.getKey()) { + // 仓库出库单 + checkAndUpdateFromState(entity, setData, orderNormsNum, executeNum, inSqlNormsId); + } + } + + private void checkAndUpdateFromState(ShopConfirmReturn entity, boolean setData, Map orderNormsNum, Map executeNum, List inSqlNormsId) { + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + if (CollectionUtil.isEmpty(depotOut.getErpOrderItemList())) { + throw new CustomException("该仓库出库单下未包含商品."); + } + super.checkFromOrderMaterialNorms(depotOut.getErpOrderItemList(), inSqlNormsId); + // 获取已经下达物料接收单的商品信息 + Map putExecuteNum = shopConfirmPutService.calcMaterialNormsNumByFromId(entity.getFromId()); + // 仓库出库单数量 - 当前单据数量 - 已经下达物料退货单的数量 - 已经下达物料接收单的数量 + super.setOrCheckOperNumber(depotOut.getErpOrderItemList(), setData, orderNormsNum, executeNum, putExecuteNum); + + if (setData) { + // 过滤掉剩余数量为0的商品 + List erpOrderItemList = depotOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(erpOrderItemList)) { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.COMPLATE_CONFIRM.getKey()); + } else { + depotOutService.editOtherState(depotOut.getId(), DepotOutOtherState.PARTIAL_CONFIRM.getKey()); + } + } + } + + @Override + public void approvalEndIsSuccess(ShopConfirmReturn entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity, true); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * + * @param entity + */ + protected List checkNormsCodeAndSave(ShopConfirmReturn entity) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和来源单据的条形码作对比 + // 获取来源单据中的条形码的信息 + DepotOut depotOut = depotOutService.selectById(entity.getFromId()); + List inFromOrderNormsCodeList = depotOut.getErpOrderItemList().stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getNormsCodeList())) + .flatMap(norms -> norms.getNormsCodeList().stream()).distinct().collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在来源单据中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inFromOrderNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在来源出库单中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 2. 和数据库中条形码的状态做对比 + // 2.1 从数据库查询出库状态的条形码信息, + // 2.2 只有门店信息为空的说明没有领料,才可以进行退货。门店信息不为空,说明该条形码已经在门店的库存里 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + materialNormsCodeList = materialNormsCodeList.stream().filter(bean -> StrUtil.isEmpty(bean.getStoreId())) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/已经存在其他仓库中,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + } + return allNormsCodeList; + } + + @Override + public void queryShopConfirmReturnTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ShopConfirmReturn shopConfirmReturn = selectById(id); + // 该物料退货单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(shopConfirmReturn.getId()); + // 设置未下达商品数量-----物料退货单数量 - 已入库数量 + super.setOrCheckOperNumber(shopConfirmReturn.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + shopConfirmReturn.setErpOrderItemList(shopConfirmReturn.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(shopConfirmReturn); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertShopConfirmReturnToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取物料退货单状态 + ShopConfirmReturn shopConfirmReturn = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(shopConfirmReturn)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(shopConfirmReturn.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.SHOP_CONFIRM_RETURNS.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } + + @Override + public Map> calcMaterialNormsCodeByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(CommonConstants.ID); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopConfirmReturn::getFromId), fromId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopConfirmReturn::getIdKey), getServiceClassName()); + // 只查询审批通过,部分出入库,已完成的单据 + List stateList = Arrays.asList(new String[]{FlowableStateEnum.PASS.getKey(), ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey(), + ErpOrderStateEnum.COMPLETED.getKey()}); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopConfirmReturn::getState), stateList); + List entityList = list(queryWrapper); + List ids = entityList.stream().map(ShopConfirmReturn::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List erpOrderItemList = skyeyeErpOrderItemService.queryErpOrderItemByPIds(ids); + // 查询单据子表关联的条形码编号信息 + List erpOrderItemCodeList = erpOrderItemCodeService.selectByParentId(ids.toArray(new String[]{})); + Map> listMap = erpOrderItemCodeList.stream().collect(Collectors.groupingBy(ErpOrderItemCode::getNormsId)); + erpOrderItemList.forEach(erpOrderItem -> { + List erpOrderItemCodes = listMap.get(erpOrderItem.getNormsId()); + if (CollectionUtil.isNotEmpty(erpOrderItemCodes)) { + List normsCodeList = erpOrderItemCodes.stream().map(ErpOrderItemCode::getNormsCode).collect(Collectors.toList()); + erpOrderItem.setNormsCodeList(normsCodeList); + erpOrderItem.setNormsCode(Joiner.on("\n").join(normsCodeList)); + } + }); + Map> collect = erpOrderItemList.stream() + .collect(Collectors.groupingBy(ErpOrderItem::getNormsId, Collectors.mapping(ErpOrderItem::getNormsCodeList, + Collectors.reducing( + new ArrayList<>(), + Function.identity(), + (l1, l2) -> { + if (CollectionUtil.isNotEmpty(l2)) { + l1.addAll(l2); + } + return l1; + } + )))); + return collect; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopOutLetsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopOutLetsServiceImpl.java new file mode 100644 index 0000000..6b1585f --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopOutLetsServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotOutFromType; +import com.skyeye.depot.classenum.DepotOutState; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.entity.DepotOut; +import com.skyeye.depot.service.DepotOutService; +import com.skyeye.entity.ErpOrderHead; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.dao.ShopOutLetsDao; +import com.skyeye.shop.entity.ShopOutLets; +import com.skyeye.shop.service.ShopOutLetsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopOutLetsServiceImpl + * @Description: 门店申领单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店申领单", groupName = "门店", flowable = true) +public class ShopOutLetsServiceImpl extends SkyeyeErpOrderServiceImpl implements ShopOutLetsService { + + @Autowired + private DepotOutService depotOutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + commonPageInfo.setObjectId("-"); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderHead::getStoreId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + return beans; + } + + @Override + public void validatorEntity(ShopOutLets entity) { + entity.setOtherState(DepotOutState.NEED_OUT.getKey()); + } + + @Override + public void createPrepose(ShopOutLets entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.OUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public ShopOutLets selectById(String id) { + ShopOutLets shopOutLets = super.selectById(id); + // 部门 + iDepmentService.setDataMation(shopOutLets, ShopOutLets::getDepartmentId); + // 门店 + iShopStoreService.setDataMation(shopOutLets, ShopOutLets::getStoreId); + // 业务员 + iAuthUserService.setDataMation(shopOutLets, ShopOutLets::getSalesman); + return shopOutLets; + } + + @Override + public void queryShopOutLetsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ShopOutLets shopOutLets = selectById(id); + // 该门店申领单下的已经下达仓库出库单(审核通过)的数量 + Map depotNumMap = depotOutService.calcMaterialNormsNumByFromId(shopOutLets.getId()); + // 设置未下达商品数量-----门店申领单数量 - 已出库数量 + super.setOrCheckOperNumber(shopOutLets.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + shopOutLets.setErpOrderItemList(shopOutLets.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(shopOutLets); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertShopOutLetsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotOut depotOut = inputObject.getParams(DepotOut.class); + // 获取门店申领单状态 + ShopOutLets shopOutLets = selectById(depotOut.getId()); + if (ObjectUtil.isEmpty(shopOutLets)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库出库单 + if (FlowableStateEnum.PASS.getKey().equals(shopOutLets.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotOut.setFromId(depotOut.getId()); + depotOut.setFromTypeId(DepotOutFromType.SHOP_OUTLET.getKey()); + depotOut.setId(StrUtil.EMPTY); + depotOutService.createEntity(depotOut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库出库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopReturnsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopReturnsServiceImpl.java new file mode 100644 index 0000000..cff6132 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopReturnsServiceImpl.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutFromType; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.depot.classenum.DepotPutState; +import com.skyeye.depot.entity.DepotPut; +import com.skyeye.depot.service.DepotPutService; +import com.skyeye.entity.ErpOrderHead; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.material.classenum.MaterialNormsCodeInDepot; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import com.skyeye.material.entity.MaterialNormsCode; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.classenum.StoreNormsCodeUseState; +import com.skyeye.shop.dao.ShopReturnsDao; +import com.skyeye.shop.entity.ShopReturns; +import com.skyeye.shop.service.ShopReturnsService; +import com.skyeye.shop.service.ShopStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopReturnsServiceImpl + * @Description: 门店退货单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店退货单", groupName = "门店", flowable = true) +public class ShopReturnsServiceImpl extends SkyeyeErpOrderServiceImpl implements ShopReturnsService { + + @Autowired + private DepotPutService depotPutService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Autowired + private ShopStockService shopStockService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + commonPageInfo.setObjectId("-"); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(ErpOrderHead::getStoreId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iDepmentService.setMationForMap(beans, "departmentId", "departmentMation"); + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + // 业务员 + iAuthUserService.setMationForMap(beans, "salesman", "salesmanMation"); + return beans; + } + + @Override + public void validatorEntity(ShopReturns entity) { + entity.setOtherState(DepotPutState.NEED_PUT.getKey()); + checkMaterialNorms(entity); + checkNormsCodeAndSave(entity, true); + } + + @Override + public void createPrepose(ShopReturns entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + entity.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + }); + } + + @Override + public void writeChild(ShopReturns entity, String userId) { + // 保存单据子表关联的条形码编号信息 + super.saveErpOrderItemCode(entity); + super.writeChild(entity, userId); + } + + @Override + public void deletePostpose(String id) { + // 删除关联的编码信息 + super.deleteErpOrderItemCodeById(id); + } + + @Override + public ShopReturns getDataFromDb(String id) { + ShopReturns shopReturns = super.getDataFromDb(id); + // 查询单据子表关联的条形码编号信息 + queryErpOrderItemCodeById(shopReturns); + return shopReturns; + } + + @Override + public ShopReturns selectById(String id) { + ShopReturns returnPut = super.selectById(id); + // 部门 + iDepmentService.setDataMation(returnPut, ShopReturns::getDepartmentId); + // 门店 + iShopStoreService.setDataMation(returnPut, ShopReturns::getStoreId); + // 业务员 + iAuthUserService.setDataMation(returnPut, ShopReturns::getSalesman); + return returnPut; + } + + private void checkMaterialNorms(ShopReturns entity) { + // 和当前门店的库存做对比 + checkStoreStockWhetherOutstrip(entity.getStoreId(), entity.getErpOrderItemList()); + } + + @Override + public void approvalEndIsSuccess(ShopReturns entity) { + entity = selectById(entity.getId()); + // 修改来源单据信息 + checkMaterialNorms(entity); + // 校验并修改条形码信息 + checkNormsCodeAndSave(entity, false); + } + + private void checkStoreStockWhetherOutstrip(String storeId, List erpOrderItemList) { + List normsIds = erpOrderItemList.stream().map(ErpOrderItem::getNormsId).collect(Collectors.toList()); + Map normsStoreStock = shopStockService.queryNormsShopStock(storeId, normsIds); + for (ErpOrderItem bean : erpOrderItemList) { + // 门店库存存量 + int departMentTock = normsStoreStock.get(bean.getNormsId()); + // 单据数量 小于 仓储数量 + if (departMentTock - bean.getOperNumber() < 0) { + throw new CustomException("单据储量小于仓储数量,请确认"); + } + } + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * 从门店的库存入库到仓库的库存 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + protected List checkNormsCodeAndSave(ShopReturns entity, Boolean onlyCheck) { + List materialIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getErpOrderItemList().stream().map(ErpOrderItem::getNormsId).distinct().collect(Collectors.toList()); + Map materialMap = materialService.selectMapByIds(materialIdList); + Map normsMap = materialNormsService.selectMapByIds(normsIdList); + // 所有需要进行入库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 1. 和数据库中条形码的状态做对比 + // 1.1 从数据库查询出库状态的条形码信息, + // 1.2 只有门店信息不为空的说明没有退料,才可以进行退料。门店信息为空,说明该条形码还未进行领料 + List materialNormsCodeList = materialNormsCodeService.queryMaterialNormsCodeByCodeNum(StrUtil.EMPTY, allNormsCodeList, + MaterialNormsCodeInDepot.OUTBOUND.getKey()); + // 1.3 过滤出当前门店的库存 + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StrUtil.equals(entity.getStoreId(), bean.getStoreId())).collect(Collectors.toList()); + // 1.4 只有未使用的可以退料 + materialNormsCodeList = materialNormsCodeList.stream() + .filter(bean -> StoreNormsCodeUseState.WAIT_USE.getKey() == bean.getStoreUseState()) + .collect(Collectors.toList()); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(MaterialNormsCode::getCodeNum).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在或不存在【门店】仓库中或已被使用,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + if (!onlyCheck) { + // 批量修改条形码信息 + materialNormsCodeList.forEach(materialNormsCode -> { + materialNormsCode.setStoreId(StrUtil.EMPTY); + materialNormsCode.setStoreUseState(null); + }); + materialNormsCodeService.updateEntityPick(materialNormsCodeList); + } + } + if (!onlyCheck) { + // 修改门店的库存 + entity.getErpOrderItemList().forEach(erpOrderItem -> { + shopStockService.updateShopStock(entity.getStoreId(), erpOrderItem.getMaterialId(), + erpOrderItem.getNormsId(), erpOrderItem.getOperNumber(), DepotPutOutType.OUT.getKey()); + }); + } + return allNormsCodeList; + } + + @Override + public void queryShopReturnsTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ShopReturns shopReturns = selectById(id); + // 该门店退货单下的已经下达仓库入库单(审核通过)的数量 + Map depotNumMap = depotPutService.calcMaterialNormsNumByFromId(shopReturns.getId()); + // 设置未下达商品数量-----门店退货单数量 - 已入库数量 + super.setOrCheckOperNumber(shopReturns.getErpOrderItemList(), true, depotNumMap); + // 过滤掉数量为0的商品信息 + shopReturns.setErpOrderItemList(shopReturns.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(shopReturns); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertShopReturnsToTurnDepot(InputObject inputObject, OutputObject outputObject) { + DepotPut depotPut = inputObject.getParams(DepotPut.class); + // 获取门店退货单状态 + ShopReturns shopReturns = selectById(depotPut.getId()); + if (ObjectUtil.isEmpty(shopReturns)) { + throw new CustomException("该数据不存在."); + } + // 审核通过的可以转到仓库入库单 + if (FlowableStateEnum.PASS.getKey().equals(shopReturns.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + depotPut.setFromId(depotPut.getId()); + depotPut.setFromTypeId(DepotPutFromType.SHOP_RETURNS.getKey()); + depotPut.setId(StrUtil.EMPTY); + depotPutService.createEntity(depotPut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达仓库入库单."); + } + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopStockServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopStockServiceImpl.java new file mode 100644 index 0000000..fda450d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shop/service/impl/ShopStockServiceImpl.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shop.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.exception.CustomException; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.material.service.MaterialService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shop.dao.ShopStockDao; +import com.skyeye.shop.entity.ShopStock; +import com.skyeye.shop.service.ShopStockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopStockServiceImpl + * @Description: 门店物料库存信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/31 16:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店物料库存信息", groupName = "门店物料库存", manageShow = false) +public class ShopStockServiceImpl extends SkyeyeBusinessServiceImpl implements ShopStockService { + + @Autowired + private MaterialService materialService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "store")) { + // 门店id + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getStoreId), commonPageInfo.getHolderId()); + } + return queryWrapper; + } + + @Override + protected List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + materialService.setMationForMap(beans, "materialId", "materialMation"); + materialNormsService.setMationForMap(beans, "normsId", "normsMation"); + iShopStoreService.setMationForMap(beans, "storeId", "storeMation"); + return beans; + } + + @Override + public void updateShopStock(String storeId, String materialId, String normsId, Integer operNumber, int type) { + ShopStock shopStock = queryShopStock(storeId, normsId); + // 如果该规格在指定门店中已经有存储数据,则直接做修改 + if (ObjectUtil.isNotEmpty(shopStock)) { + int stock = shopStock.getStock(); + if (type == DepotPutOutType.PUT.getKey()) { + // 入库 + stock = stock + operNumber; + } else if (type == DepotPutOutType.OUT.getKey()) { + // 出库 + stock = stock - operNumber; + } + editShopStock(storeId, normsId, stock); + } else { + int stockNum = 0; + if (type == DepotPutOutType.PUT.getKey()) { + // 入库 + stockNum = operNumber; + } else if (type == DepotPutOutType.OUT.getKey()) { + // 出库 + stockNum = stockNum - operNumber; + } + if (stockNum < 0) { + throw new CustomException("门店库存存量不足."); + } + saveShopStock(storeId, materialId, normsId, stockNum); + } + } + + @Override + public ShopStock queryShopStock(String storeId, String normsId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getStoreId), storeId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getNormsId), normsId); + return getOne(queryWrapper); + } + + private void editShopStock(String storeId, String normsId, int stock) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getStoreId), storeId); + updateWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getNormsId), normsId); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStock::getStock), stock); + update(updateWrapper); + } + + private void saveShopStock(String storeId, String materialId, String normsId, int stock) { + ShopStock departmentStock = new ShopStock(); + departmentStock.setStoreId(storeId); + departmentStock.setMaterialId(materialId); + departmentStock.setNormsId(normsId); + departmentStock.setStock(stock); + save(departmentStock); + } + + @Override + public Map queryNormsShopStock(String storeId, List normsIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStock::getStoreId), storeId); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopStock::getNormsId), normsIds); + List departmentStockList = list(queryWrapper); + + Map stockMap = departmentStockList.stream() + .collect(Collectors.toMap(ShopStock::getNormsId, ShopStock::getStock)); + normsIds.forEach(normsId -> { + if (!stockMap.containsKey(normsId)) { + stockMap.put(normsId, 0); + } + }); + return stockMap; + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialController.java new file mode 100644 index 0000000..6354a98 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialController.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shopmaterial.entity.ShopMaterial; +import com.skyeye.shopmaterial.service.ShopMaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopMaterialController + * @Description: 商城商品控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商城商品", tags = "商城商品", modelName = "商城商品") +public class ShopMaterialController { + + @Autowired + private ShopMaterialService shopMaterialService; + + @ApiOperation(id = "queryTransMaterialById", value = "根据id获取商品信息,用于上架商城", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "商品id", required = "required")}) + @RequestMapping("/post/ShopMaterialController/queryTransMaterialById") + public void queryTransMaterialById(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryTransMaterialById(inputObject, outputObject); + } + + @ApiOperation(id = "saveShopMaterial", value = "ERP商品上架商城", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopMaterial.class) + @RequestMapping("/post/ShopMaterialController/saveShopMaterial") + public void saveShopMaterial(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialList", value = "获取商城商品信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopMaterialController/queryShopMaterialList") + public void queryShopMaterialList(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryShopMaterialList(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialListForStore", value = "以门店为主获取商城商品信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopMaterialController/queryShopMaterialListForStore") + public void queryShopMaterialListForStore(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryShopMaterialListForStore(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialByNormsIdList", value = "根据规格id获取商城商品信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "normsIds", name = "normsIds", value = "规格id,多个逗号隔开", required = "required")}) + @RequestMapping("/post/ShopMaterialController/queryShopMaterialByNormsIdList") + public void queryShopMaterialByNormsIdList(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryShopMaterialByNormsIdList(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialByMaterialIdList", value = "根据商品id获取商城商品信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "materialIds", name = "materialIds", value = "商品id,多个逗号隔开", required = "required")}) + @RequestMapping("/post/ShopMaterialController/queryShopMaterialByMaterialIdList") + public void queryShopMaterialByMaterialIdList(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryShopMaterialByMaterialIdList(inputObject, outputObject); + } + + @ApiOperation(id = "queryBrandShopMaterialList", value = "获取商城商品信息列表根据品牌进行分组,只取前8条", method = "GET", allUse = "0") + @RequestMapping("/post/ShopMaterialController/queryBrandShopMaterialList") + public void queryBrandShopMaterialList(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryBrandShopMaterialList(inputObject, outputObject); + } + + @ApiOperation(id = "queryAllShopMaterialListForChoose", value = "获取商城商品信息列表供选择", method = "GET", allUse = "2") + @RequestMapping("/post/ShopMaterialController/queryAllShopMaterialListForChoose") + public void queryAllShopMaterialListForChoose(InputObject inputObject, OutputObject outputObject) { + shopMaterialService.queryAllShopMaterialListForChoose(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialStoreController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialStoreController.java new file mode 100644 index 0000000..c9098ff --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/controller/ShopMaterialStoreController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shopmaterial.service.ShopMaterialStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopMaterialStoreController + * @Description: 商城商品上线的门店控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/18 14:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商城商品上线的门店", tags = "商城商品上线的门店", modelName = "商城商品上线的门店") +public class ShopMaterialStoreController { + + @Autowired + private ShopMaterialStoreService shopMaterialStoreService; + + @ApiOperation(id = "saveShopMaterialStore", value = "新增门店时,将所有商品同步到该门店", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id", required = "required")}) + @RequestMapping("/post/ShopMaterialStoreController/saveShopMaterialStore") + public void saveShopMaterialStore(InputObject inputObject, OutputObject outputObject) { + shopMaterialStoreService.saveShopMaterialStore(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialById", value = "根据id获取商城商品信息", method = "GET", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopMaterialStoreController/queryShopMaterialById") + public void queryShopMaterialById(InputObject inputObject, OutputObject outputObject) { + shopMaterialStoreService.queryShopMaterialById(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialByIds", value = "根据id批量获取商城商品信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个逗号隔开", required = "required")}) + @RequestMapping("/post/ShopMaterialStoreController/queryShopMaterialByIds") + public void queryShopMaterialByIds(InputObject inputObject, OutputObject outputObject) { + shopMaterialStoreService.queryShopMaterialByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialByMaterialIdAndStoreId", value = "根据商品id和门店id获取商城商品信息", method = "GET", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "materialId", name = "materialId", value = "商品id", required = "required"), + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id", required = "required")}) + @RequestMapping("/post/ShopMaterialStoreController/queryShopMaterialByMaterialIdAndStoreId") + public void queryShopMaterialByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject) { + shopMaterialStoreService.queryShopMaterialByMaterialIdAndStoreId(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopMaterialMapByMaterialIdAndStoreId", value = "根据商品id和门店id批量获取商城商品信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "materialId", name = "materialId", value = "商品id,json数组格式", required = "required,json"), + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id,json数组格式", required = "required,json")}) + @RequestMapping("/post/ShopMaterialStoreController/queryShopMaterialMapByMaterialIdAndStoreId") + public void queryShopMaterialMapByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject) { + shopMaterialStoreService.queryShopMaterialMapByMaterialIdAndStoreId(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialDao.java new file mode 100644 index 0000000..65a636a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shopmaterial.entity.ShopMaterial; + +/** + * @ClassName: ShopMaterialDao + * @Description: 商城商品数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialNormsDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialNormsDao.java new file mode 100644 index 0000000..363fbc5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialNormsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shopmaterial.entity.ShopMaterialNorms; + +/** + * @ClassName: ShopMaterialNormsDao + * @Description: 商城商品规格参数数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialNormsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialStoreDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialStoreDao.java new file mode 100644 index 0000000..c5d0a6c --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/dao/ShopMaterialStoreDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.shopmaterial.entity.ShopMaterialStore; + +/** + * @ClassName: ShopMaterialStoreDao + * @Description: 商城商品上线的门店数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/18 12:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialStoreDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterial.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterial.java new file mode 100644 index 0000000..5a20b1b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterial.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.material.entity.Material; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ShopMaterial + * @Description: 商城商品实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.ERP_SHOP_MATERIAL_CACHE_KEY) +@TableName(value = "erp_shop_material", autoResultMap = true) +@ApiModel("商城商品实体类") +public class ShopMaterial extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "content") + @ApiModelProperty(value = "商品详情信息", required = "required") + private String content; + + @TableField("remark") + @ApiModelProperty(value = "商品简介") + private String remark; + + @TableField(value = "logo") + @ApiModelProperty(value = "商品图片", required = "required") + private String logo; + + @TableField(value = "carousel_img") + @ApiModelProperty(value = "商品轮播图,多个逗号隔开") + private String carouselImg; + + @TableField(value = "distribution_type") + @ApiModelProperty(value = "分销类型,参考#ShopMaterialDistributionType", required = "required,num") + private Integer distributionType; + + @TableField(value = "delivery_method", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "配送方式,参考#ShopMaterialDeliveryMethod", required = "required,json") + private List deliveryMethod; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序 值越大越往后", required = "required,num") + private Integer orderBy; + + @TableField(value = "gift_point") + @ApiModelProperty(value = "赠送积分", required = "required,num") + private Integer giftPoint; + + @TableField(value = "virtual_sales") + @ApiModelProperty(value = "虚拟销量", required = "required") + private String virtualSales; + + @TableField(value = "real_sales") + @Property(value = "实际销量") + private String realSales; + + @TableField(exist = false) + @Property("默认门店id") + private String defaultStoreId; + + @TableField(exist = false) + @Property("该商品随机支持的门店信息") + private ShopMaterialStore shopMaterialStore; + + @TableField(exist = false) + @ApiModelProperty(value = "上架的规格信息", required = "json") + private List shopMaterialNormsList; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialNorms.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialNorms.java new file mode 100644 index 0000000..99a2bf5 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialNorms.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.material.entity.Material; +import com.skyeye.material.entity.MaterialNorms; +import lombok.Data; + +/** + * @ClassName: ShopMaterialNorms + * @Description: 商城商品规格参数实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 16:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_shop_material_norms", autoResultMap = true) +@ApiModel("商城商品规格参数实体类") +public class ShopMaterialNorms extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "material_id") + @Property(value = "产品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private MaterialNorms normsMation; + + @TableField(value = "is_default") + @ApiModelProperty(value = "是否默认,参考#IsDefaultEnum", required = "required,num") + private Integer isDefault; + + @TableField(value = "estimate_purchase_price") + @ApiModelProperty(value = "采购价/成本价", required = "required,double") + private String estimatePurchasePrice; + + @TableField(value = "sale_price") + @ApiModelProperty(value = "销售价", required = "required,double") + private String salePrice; + + @TableField(value = "logo_type") + @ApiModelProperty(value = "logo类型,参考#ShopMaterialNormsLogoType", required = "required,num") + private Integer logoType; + + @TableField(value = "logo") + @ApiModelProperty(value = "商品规格图片") + private String logo; + + @TableField(value = "carousel_img") + @ApiModelProperty(value = "商品轮播图,多个逗号隔开") + private String carouselImg; + + @TableField(value = "real_sales") + @Property(value = "实际销量") + private String realSales; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialStore.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialStore.java new file mode 100644 index 0000000..54fef33 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/entity/ShopMaterialStore.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.material.entity.Material; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ShopMaterialNorms + * @Description: 商城商品上线的门店实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 16:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "erp_shop_material_store", autoResultMap = true) +@ApiModel("商城商品上线的门店实体类") +public class ShopMaterialStore extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "material_id") + @Property(value = "产品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Material materialMation; + + @TableField(value = "store_id") + @Property(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + + @TableField(exist = false) + @Property(value = "上架的商品信息") + private ShopMaterial shopMaterial; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialDistributionType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialDistributionType.java new file mode 100644 index 0000000..7a28b58 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialDistributionType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopMaterialDistributionType + * @Description: 商城商品分销方式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopMaterialDistributionType implements SkyeyeEnumClass { + + DEFAULT_SET(1, "默认设置", true, true), + SINGLE_SET(2, "单独设置", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialNormsLogoType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialNormsLogoType.java new file mode 100644 index 0000000..6fce3dc --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/enums/ShopMaterialNormsLogoType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopMaterialNormsLogoType + * @Description: 商城商品规格logo类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopMaterialNormsLogoType implements SkyeyeEnumClass { + + FOLLOW_GOODS(1, "跟随商品", true, true), + SINGLE_SET(2, "单独设置", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialNormsService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialNormsService.java new file mode 100644 index 0000000..c868e1b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialNormsService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.shopmaterial.entity.ShopMaterialNorms; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMaterialNormsService + * @Description: 商城商品规格参数服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialNormsService extends SkyeyeBusinessService { + + void deleteByMaterialId(String materialId); + + List selectByMaterialId(String materialId); + + Map> selectByMaterialId(List materialId); + + void saveList(String materialId, List shopMaterialNormsList); + + List queryShopMaterialByNormsIdList(List normsIdList); + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialService.java new file mode 100644 index 0000000..e7d9128 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialService.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shopmaterial.entity.ShopMaterial; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMaterialService + * @Description: 商城商品服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialService extends SkyeyeBusinessService { + + void queryTransMaterialById(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialList(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialListForStore(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialByNormsIdList(InputObject inputObject, OutputObject outputObject); + + void queryBrandShopMaterialList(InputObject inputObject, OutputObject outputObject); + + ShopMaterial queryShopMaterialByMaterialId(String materialId); + + Map queryShopMaterialByMaterialId(List materialIds); + + void queryAllShopMaterialListForChoose(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialByMaterialIdList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialStoreService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialStoreService.java new file mode 100644 index 0000000..f972bf1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/ShopMaterialStoreService.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.shopmaterial.entity.ShopMaterialStore; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMaterialStoreService + * @Description: 商城商品上线的门店服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/18 14:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMaterialStoreService extends SkyeyeBusinessService { + + void deleteByMaterialId(String materialId); + + List selectByMaterialId(String materialId); + + Map> selectByMaterialId(List materialId); + + void saveList(String materialId, List shopMaterialStoreList); + + /** + * 添加指定商品到所有门店 + * + * @param materialId 商品ID + */ + void addAllStoreForMaterial(String materialId); + + void saveShopMaterialStore(InputObject inputObject, OutputObject outputObject); + + List queryShopMaterialList(InputObject inputObject, OutputObject outputObject); + + Map queryShopMaterialStoreByMaterialIds(String... materialIds); + + void queryShopMaterialById(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject); + + Map> queryShopMaterialListByStoreIds(List storeIds); + + void queryShopMaterialByIds(InputObject inputObject, OutputObject outputObject); + + void queryShopMaterialMapByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialNormsServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialNormsServiceImpl.java new file mode 100644 index 0000000..fe4ac5d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialNormsServiceImpl.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.shopmaterial.dao.ShopMaterialNormsDao; +import com.skyeye.shopmaterial.entity.ShopMaterialNorms; +import com.skyeye.shopmaterial.service.ShopMaterialNormsService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMaterialNormsServiceImpl + * @Description: 商城商品规格参数服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商城商品规格", groupName = "商城商品规格", manageShow = false) +public class ShopMaterialNormsServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMaterialNormsService { + + @Override + public void deleteByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialNorms::getMaterialId), materialId); + remove(queryWrapper); + } + + @Override + public List selectByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialNorms::getMaterialId), materialId); + List shopMaterialNormsList = list(queryWrapper); + return shopMaterialNormsList; + } + + @Override + public Map> selectByMaterialId(List materialId) { + if (CollectionUtil.isEmpty(materialId)) { + return MapUtil.empty(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterialNorms::getMaterialId), materialId); + List shopMaterialNormsList = list(queryWrapper); + Map> collect = shopMaterialNormsList.stream().collect(Collectors.groupingBy(ShopMaterialNorms::getMaterialId)); + return collect; + } + + @Override + public void saveList(String materialId, List shopMaterialNormsList) { + deleteByMaterialId(materialId); + if (CollectionUtil.isNotEmpty(shopMaterialNormsList)) { + for (ShopMaterialNorms shopMaterialNorms : shopMaterialNormsList) { + shopMaterialNorms.setMaterialId(materialId); + shopMaterialNorms.setRealSales(CommonNumConstants.NUM_ZERO.toString()); + } + createEntity(shopMaterialNormsList, StrUtil.EMPTY); + } + } + + @Override + public List queryShopMaterialByNormsIdList(List normsIdList) { + if (CollectionUtil.isEmpty(normsIdList)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterialNorms::getNormsId), normsIdList); + List shopMaterialNormsList = list(queryWrapper); + return shopMaterialNormsList; + } +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialServiceImpl.java new file mode 100644 index 0000000..0eeee22 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialServiceImpl.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.brand.entity.Brand; +import com.skyeye.brand.service.BrandService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.ResultEntity; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.material.classenum.MaterialShelvesState; +import com.skyeye.material.entity.Material; +import com.skyeye.material.service.MaterialService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shopmaterial.dao.ShopMaterialDao; +import com.skyeye.shopmaterial.entity.ShopMaterial; +import com.skyeye.shopmaterial.entity.ShopMaterialNorms; +import com.skyeye.shopmaterial.entity.ShopMaterialStore; +import com.skyeye.shopmaterial.service.ShopMaterialNormsService; +import com.skyeye.shopmaterial.service.ShopMaterialService; +import com.skyeye.shopmaterial.service.ShopMaterialStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMaterialServiceImpl + * @Description: 商城商品服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/4 17:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商城商品", groupName = "商城商品") +public class ShopMaterialServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMaterialService { + + @Autowired + private MaterialService materialService; + + @Autowired + private ShopMaterialNormsService shopMaterialNormsService; + + @Autowired + private ShopMaterialStoreService shopMaterialStoreService; + + @Autowired + private BrandService brandService; + + @Autowired + private IShopStoreService iShopStoreService; + + @Override + public void createPrepose(ShopMaterial entity) { + entity.setRealSales(CommonNumConstants.NUM_ZERO.toString()); + } + + @Override + public void writePostpose(ShopMaterial entity, String userId) { + // 保存商城商品规格 + shopMaterialNormsService.saveList(entity.getMaterialId(), entity.getShopMaterialNormsList()); + + // 更新商品的上架状态 + Material material = materialService.selectById(entity.getMaterialId()); + if (CollectionUtil.isEmpty(entity.getShopMaterialNormsList())) { + materialService.setShelvesState(material.getId(), MaterialShelvesState.NOT_ON_SHELVE.getKey()); + shopMaterialStoreService.deleteByMaterialId(entity.getMaterialId()); + } else if (material.getMaterialNorms().size() > entity.getShopMaterialNormsList().size()) { + materialService.setShelvesState(material.getId(), MaterialShelvesState.PART_ON_SHELVE.getKey()); + shopMaterialStoreService.addAllStoreForMaterial(entity.getMaterialId()); + } else if (material.getMaterialNorms().size() == entity.getShopMaterialNormsList().size()) { + materialService.setShelvesState(material.getId(), MaterialShelvesState.ON_SHELVE.getKey()); + shopMaterialStoreService.addAllStoreForMaterial(entity.getMaterialId()); + } + } + + @Override + public void queryTransMaterialById(InputObject inputObject, OutputObject outputObject) { + String materialId = inputObject.getParams().get("id").toString(); + ShopMaterial shopMaterial = queryShopMaterialByMaterialId(materialId); + if (ObjectUtil.isEmpty(shopMaterial) || StrUtil.isEmpty(shopMaterial.getId())) { + shopMaterial = new ShopMaterial(); + Material material = materialService.selectById(materialId); + shopMaterial.setMaterialId(materialId); + shopMaterial.setMaterialMation(material); + } + outputObject.setBean(shopMaterial); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public ShopMaterial getDataFromDb(String id) { + ShopMaterial shopMaterial = super.getDataFromDb(id); + if (ObjectUtil.isEmpty(shopMaterial) || StrUtil.isEmpty(shopMaterial.getId())) { + return shopMaterial; + } + List shopMaterialNormsList = shopMaterialNormsService.selectByMaterialId(shopMaterial.getMaterialId()); + shopMaterial.setShopMaterialNormsList(shopMaterialNormsList); + return shopMaterial; + } + + @Override + public ShopMaterial selectById(String id) { + ShopMaterial shopMaterial = super.selectById(id); + if (StrUtil.isEmpty(shopMaterial.getId())) { + return null; + } + materialService.setDataMation(shopMaterial, ShopMaterial::getMaterialId); + return shopMaterial; + } + + @Override + public List getDataFromDb(List idList) { + List shopMaterialList = super.getDataFromDb(idList); + if (CollectionUtil.isEmpty(shopMaterialList)) { + return shopMaterialList; + } + List materialIdList = shopMaterialList.stream().map(ShopMaterial::getMaterialId).distinct().collect(Collectors.toList()); + Map> collectMap = shopMaterialNormsService.selectByMaterialId(materialIdList); + shopMaterialList.forEach(shopMaterial -> { + shopMaterial.setShopMaterialNormsList(collectMap.get(shopMaterial.getMaterialId())); + }); + return shopMaterialList; + } + + @Override + public List selectByIds(String... ids) { + List shopMaterialList = super.selectByIds(ids); + materialService.setDataMation(shopMaterialList, ShopMaterial::getMaterialId); + return shopMaterialList; + } + + @Override + public void queryShopMaterialList(InputObject inputObject, OutputObject outputObject) { + List shopMaterialStoreList = shopMaterialStoreService.queryShopMaterialList(inputObject, outputObject); + if (CollectionUtil.isEmpty(shopMaterialStoreList)) { + return; + } + List materialIdList = shopMaterialStoreList.stream().map(ShopMaterialStore::getMaterialId).collect(Collectors.toList()); + // 根据商品id查询上架的商品信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterial::getMaterialId), materialIdList); + List shopMaterialList = list(queryWrapper); + // 根据id批量查询详细的商品信息 + List idList = shopMaterialList.stream().map(ShopMaterial::getId).collect(Collectors.toList()); + List shopMaterials = selectByIds(idList.toArray(new String[]{})); + Map materialMap = shopMaterials.stream().collect( + Collectors.toMap(ShopMaterial::getMaterialId, shopMaterial -> shopMaterial)); + shopMaterialStoreList.forEach(shopMaterialStore -> { + ShopMaterial shopMaterial = materialMap.get(shopMaterialStore.getMaterialId()); + shopMaterial.getMaterialMation().setMaterialNorms(null); + shopMaterial.getMaterialMation().setUnitGroupMation(null); + shopMaterial.getMaterialMation().setMaterialProcedure(null); + shopMaterial.getMaterialMation().setNormsSpec(null); + shopMaterialStore.setShopMaterial(shopMaterial); + }); + + outputObject.setBeans(shopMaterialStoreList); + } + + @Override + public void queryShopMaterialListForStore(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + ResultEntity resultEntity = iShopStoreService.queryStoreListFoServer(commonPageInfo); + // 分页查询门店信息 + List> storeList = resultEntity.getRows(); + if (CollectionUtil.isEmpty(storeList)) { + return; + } + List storeIdList = storeList.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + Map> stringListMap = shopMaterialStoreService.queryShopMaterialListByStoreIds(storeIdList); + storeList.forEach(store -> { + store.put("shopMaterialList", stringListMap.get(store.get("id").toString())); + }); + outputObject.setBeans(storeList); + outputObject.settotal(resultEntity.getTotal()); + } + + @Override + public void queryShopMaterialByNormsIdList(InputObject inputObject, OutputObject outputObject) { + List normsIdList = Arrays.asList(inputObject.getParams().get("normsIds").toString() + .split(CommonCharConstants.COMMA_MARK)) + .stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(normsIdList)) { + return; + } + List shopMaterialNormsList = shopMaterialNormsService.queryShopMaterialByNormsIdList(normsIdList); + outputObject.setBeans(shopMaterialNormsList); + outputObject.settotal(shopMaterialNormsList.size()); + } + + @Override + public void queryBrandShopMaterialList(InputObject inputObject, OutputObject outputObject) { + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .innerJoin(Material.class, Material::getId, ShopMaterial::getMaterialId) + .innerJoin(Brand.class, Brand::getId, Material::getBrandId) + .eq(Brand::getEnabled, EnableEnum.ENABLE_USING.getKey()) + .in(Material::getShelvesState, Arrays.asList(MaterialShelvesState.ON_SHELVE.getKey(), MaterialShelvesState.PART_ON_SHELVE.getKey())); + List shopMaterialList = skyeyeBaseMapper.selectJoinList(ShopMaterial.class, wrapper); + // 根据id批量查询详细的商品信息 + List idList = shopMaterialList.stream().map(ShopMaterial::getId).collect(Collectors.toList()); + // 批量查询商品所属门店信息(门店随机) + List materialIds = shopMaterialList.stream().map(ShopMaterial::getMaterialId).distinct().collect(Collectors.toList()); + Map stringShopMaterialStoreMap = shopMaterialStoreService.queryShopMaterialStoreByMaterialIds(materialIds.toArray(new String[]{})); + shopMaterialList = selectByIds(idList.toArray(new String[]{})); + shopMaterialList.forEach(shopMaterial -> { + shopMaterial.getMaterialMation().setMaterialNorms(null); + shopMaterial.getMaterialMation().setUnitGroupMation(null); + shopMaterial.getMaterialMation().setMaterialProcedure(null); + shopMaterial.getMaterialMation().setNormsSpec(null); + // 设置门店信息 + shopMaterial.setShopMaterialStore(stringShopMaterialStoreMap.get(shopMaterial.getMaterialId())); + if (ObjectUtil.isNotEmpty(shopMaterial.getShopMaterialStore())) { + shopMaterial.setDefaultStoreId(shopMaterial.getShopMaterialStore().getStoreId()); + } + }); + + // 根据品牌id进行分组,并且每个品牌下只取8条数据 + Map> collectMap = shopMaterialList.stream().collect(Collectors.groupingBy(bean -> bean.getMaterialMation().getBrandId(), Collectors.collectingAndThen( + Collectors.toList(), // 分组的 downstream + list -> { + if (list.size() > 8) { + return list.subList(0, 8); // 只取前8个元素 + } + return list; + } + ))); + Map brandMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(collectMap)) { + List brandIdList = shopMaterialList.stream() + .filter(bean -> StrUtil.isNotEmpty(bean.getMaterialMation().getBrandId())) + .map(bean -> bean.getMaterialMation().getBrandId()).distinct().collect(Collectors.toList()); + brandMap = brandService.selectByIds(brandIdList.toArray(new String[]{})).stream() + .collect(Collectors.toMap(Brand::getId, bean -> bean.getName())); + } + outputObject.setBean(collectMap); + outputObject.setCustomBean("brandMap", brandMap); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public ShopMaterial queryShopMaterialByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterial::getMaterialId), materialId); + ShopMaterial shopMaterial = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(shopMaterial)) { + return null; + } + return selectById(shopMaterial.getId()); + } + + @Override + public Map queryShopMaterialByMaterialId(List materialIds) { + materialIds = materialIds.stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(materialIds)) { + return MapUtil.empty(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterial::getMaterialId), materialIds); + queryWrapper.select(CommonConstants.ID); + List shopMaterialList = list(queryWrapper); + if (CollectionUtil.isEmpty(shopMaterialList)) { + return MapUtil.empty(); + } + List ids = shopMaterialList.stream().map(ShopMaterial::getId).collect(Collectors.toList()); + List shopMaterials = selectByIds(ids.toArray(new String[]{})); + return shopMaterials.stream().collect(Collectors.toMap(ShopMaterial::getMaterialId, shopMaterial -> shopMaterial)); + } + + @Override + public void queryAllShopMaterialListForChoose(InputObject inputObject, OutputObject outputObject) { + List shopMaterialList = list(); + // 根据id批量查询详细的商品信息 + List idList = shopMaterialList.stream().map(ShopMaterial::getId).collect(Collectors.toList()); + List shopMaterials = selectByIds(idList.toArray(new String[]{})); + List> result = shopMaterials.stream().map(bean -> { + Map item = new HashMap<>(); + item.put("id", bean.getMaterialId()); + item.put("name", bean.getMaterialMation().getName()); + return item; + }).collect(Collectors.toList()); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + + @Override + public void queryShopMaterialByMaterialIdList(InputObject inputObject, OutputObject outputObject) { + List materialIdList = Arrays.asList(inputObject.getParams().get("materialIds").toString() + .split(CommonCharConstants.COMMA_MARK)) + .stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(materialIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterial::getMaterialId), materialIdList); + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialStoreServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialStoreServiceImpl.java new file mode 100644 index 0000000..e241382 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/shopmaterial/service/impl/ShopMaterialStoreServiceImpl.java @@ -0,0 +1,337 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.shopmaterial.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.entity.Material; +import com.skyeye.material.service.MaterialNormsService; +import com.skyeye.rest.shop.service.IShopStoreService; +import com.skyeye.shopmaterial.dao.ShopMaterialStoreDao; +import com.skyeye.shopmaterial.entity.ShopMaterial; +import com.skyeye.shopmaterial.entity.ShopMaterialNorms; +import com.skyeye.shopmaterial.entity.ShopMaterialStore; +import com.skyeye.shopmaterial.service.ShopMaterialService; +import com.skyeye.shopmaterial.service.ShopMaterialStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMaterialStoreServiceImpl + * @Description: 商城商品上线的门店服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/18 14:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商城商品上线的门店", groupName = "商城商品上线的门店", manageShow = false) +public class ShopMaterialStoreServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMaterialStoreService { + + @Autowired + private IShopStoreService iShopStoreService; + + @Autowired + private MaterialNormsService materialNormsService; + + @Autowired + private ShopMaterialService shopMaterialService; + + @Override + public void deleteByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), materialId); + remove(queryWrapper); + } + + @Override + public List selectByMaterialId(String materialId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), materialId); + List shopMaterialStoreList = list(queryWrapper); + return shopMaterialStoreList; + } + + @Override + public Map> selectByMaterialId(List materialId) { + if (CollectionUtil.isEmpty(materialId)) { + return MapUtil.empty(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), materialId); + List shopMaterialStoreList = list(queryWrapper); + Map> collect = shopMaterialStoreList.stream().collect(Collectors.groupingBy(ShopMaterialStore::getMaterialId)); + return collect; + } + + @Override + public void saveList(String materialId, List shopMaterialStoreList) { + if (CollectionUtil.isNotEmpty(shopMaterialStoreList)) { + // 根据商品id查询已存在的门店商品数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), materialId); + List existShopMaterialStoreList = list(queryWrapper); + List existStoreIdList = existShopMaterialStoreList.stream().map(ShopMaterialStore::getStoreId).collect(Collectors.toList()); + // 构造新的门店商品数据进行保存 + List newList = shopMaterialStoreList.stream().filter(shopMaterialStore -> { + if (existStoreIdList.indexOf(shopMaterialStore.getStoreId()) > -1) { + return false; + } + return true; + }).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(newList)) { + return; + } + for (ShopMaterialStore shopMaterialStore : newList) { + shopMaterialStore.setMaterialId(materialId); + } + String userId = InputObject.getLogParamsStatic().get("id").toString(); + createEntity(newList, userId); + } + } + + @Override + public void addAllStoreForMaterial(String materialId) { + List> storeList = iShopStoreService.queryStoreListByParams(StrUtil.EMPTY, null); + if (CollectionUtil.isEmpty(storeList)) { + return; + } + List shopMaterialStoreList = storeList.stream().map(store -> { + ShopMaterialStore shopMaterialStore = new ShopMaterialStore(); + shopMaterialStore.setStoreId(MapUtil.getStr(store, "id")); + return shopMaterialStore; + }).collect(Collectors.toList()); + saveList(materialId, shopMaterialStoreList); + } + + @Override + public void saveShopMaterialStore(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String storeId = MapUtil.getStr(params, "storeId"); + + // 查询商品id + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId)); + queryWrapper.ne(MybatisPlusUtil.toColumns(ShopMaterialStore::getStoreId), storeId); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId)); + List shopMaterialStoreList = list(queryWrapper); + if (CollectionUtil.isEmpty(shopMaterialStoreList)) { + return; + } + // 构造新的门店商品数据进行保存 + List materialIdList = shopMaterialStoreList.stream().map(ShopMaterialStore::getMaterialId).collect(Collectors.toList()); + List newList = materialIdList.stream().map(materialId -> { + ShopMaterialStore shopMaterialStore = new ShopMaterialStore(); + shopMaterialStore.setMaterialId(materialId); + shopMaterialStore.setStoreId(storeId); + return shopMaterialStore; + }).collect(Collectors.toList()); + // 不管该门店之前有没有添加过商品,都先进行删除 + QueryWrapper removeWrapper = new QueryWrapper<>(); + removeWrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getStoreId), storeId); + remove(removeWrapper); + // 保存门店商品数据 + createEntity(newList, InputObject.getLogParamsStatic().get("id").toString()); + } + + @Override + public List queryShopMaterialList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + // 商品名称,型号,门店,品牌 + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .innerJoin(Material.class, Material::getId, ShopMaterialStore::getMaterialId); + if (StrUtil.isNotBlank(commonPageInfo.getObjectId())) { + wrapper.eq(ShopMaterialStore::getStoreId, commonPageInfo.getObjectId()); + } + if (StrUtil.isNotBlank(commonPageInfo.getHolderId())) { + wrapper.eq(ShopMaterialStore::getMaterialId, commonPageInfo.getHolderId()); + } + if (StrUtil.isNotBlank(commonPageInfo.getType())) { + wrapper.eq(Material::getBrandId, commonPageInfo.getType()); + } + if (StrUtil.isNotBlank(commonPageInfo.getKeyword())) { + wrapper.and(wra -> { + wra.or().like(Material::getName, commonPageInfo.getKeyword()); + wra.or().like(Material::getModel, commonPageInfo.getKeyword()); + }); + } + + + List shopMaterialStoreList = skyeyeBaseMapper.selectJoinList(ShopMaterialStore.class, wrapper); + iShopStoreService.setDataMation(shopMaterialStoreList, ShopMaterialStore::getStoreId); + outputObject.settotal(pages.getTotal()); + return shopMaterialStoreList; + } + + @Override + public Map queryShopMaterialStoreByMaterialIds(String... materialIds) { + List idList = Arrays.asList(materialIds).stream() + .filter(materialId -> StrUtil.isNotEmpty(materialId)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(idList)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), idList); + List shopMaterialStoreList = list(queryWrapper); + Map collect = shopMaterialStoreList.stream() + .collect(Collectors.toMap(ShopMaterialStore::getMaterialId, shopMaterialStore -> shopMaterialStore, (existingValue, newValue) -> existingValue)); + return collect; + } + + @Override + public void queryShopMaterialById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + ShopMaterialStore shopMaterialStore = selectById(id); + ShopMaterial shopMaterial = shopMaterialService.queryShopMaterialByMaterialId(shopMaterialStore.getMaterialId()); + shopMaterial.getMaterialMation().setMaterialNorms(null); + shopMaterial.getMaterialMation().setUnitGroupMation(null); + shopMaterial.getMaterialMation().setMaterialProcedure(null); + shopMaterial.getMaterialMation().setNormsSpec(null); + materialNormsService.setDataMation(shopMaterial.getShopMaterialNormsList(), ShopMaterialNorms::getNormsId); + shopMaterial.getShopMaterialNormsList().forEach(shopMaterialNorms -> { + shopMaterialNorms.setEstimatePurchasePrice(null); + }); + shopMaterial.setShopMaterialStore(shopMaterialStore); + shopMaterial.setDefaultStoreId(shopMaterialStore.getStoreId()); + outputObject.setBean(shopMaterial); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void queryShopMaterialByIds(InputObject inputObject, OutputObject outputObject) { + String ids = inputObject.getParams().get("ids").toString(); + List idList = Arrays.asList(ids.split(CommonCharConstants.COMMA_MARK)) + .stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(idList)) { + return; + } + List shopMaterialStoreList = selectByIds(idList.toArray(new String[]{})); + if (CollectionUtil.isEmpty(shopMaterialStoreList)) { + return; + } + Map storeMap = shopMaterialStoreList.stream() + .collect(Collectors.toMap(ShopMaterialStore::getMaterialId, Function.identity(), (v1, v2) -> v1)); + + List materialIds = shopMaterialStoreList.stream() + .map(ShopMaterialStore::getMaterialId).distinct().collect(Collectors.toList()); + Map shopMaterialMap = shopMaterialService.queryShopMaterialByMaterialId(materialIds); + List shopMaterialList = shopMaterialMap.values().stream().collect(Collectors.toList()); + shopMaterialList.forEach(shopMaterial -> { + shopMaterial.getMaterialMation().setMaterialNorms(null); + shopMaterial.getMaterialMation().setUnitGroupMation(null); + shopMaterial.getMaterialMation().setMaterialProcedure(null); + shopMaterial.getMaterialMation().setNormsSpec(null); + shopMaterial.getShopMaterialNormsList().forEach(shopMaterialNorms -> { + shopMaterialNorms.setEstimatePurchasePrice(null); + }); + // 门店商品数据 + ShopMaterialStore shopMaterialStore = storeMap.get(shopMaterial.getMaterialId()); + shopMaterial.setShopMaterialStore(shopMaterialStore); + shopMaterial.setDefaultStoreId(shopMaterialStore.getStoreId()); + }); + outputObject.setBeans(shopMaterialList); + outputObject.settotal(shopMaterialList.size()); + } + + @Override + public void queryShopMaterialByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String materialId = params.get("materialId").toString(); + String storeId = params.get("storeId").toString(); + ShopMaterialStore shopMaterialStore = getOne(new QueryWrapper() + .eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), materialId) + .eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getStoreId), storeId)); + outputObject.setBean(shopMaterialStore); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public Map> queryShopMaterialListByStoreIds(List storeIds) { + if (CollectionUtil.isEmpty(storeIds)) { + return MapUtil.empty(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMaterialStore::getStoreId), storeIds); + List shopMaterialStoreList = list(queryWrapper); + List materialIds = shopMaterialStoreList.stream() + .map(ShopMaterialStore::getMaterialId).distinct().collect(Collectors.toList()); + Map shopMaterialMap = shopMaterialService.queryShopMaterialByMaterialId(materialIds); + shopMaterialStoreList.forEach(shopMaterialStore -> { + ShopMaterial shopMaterial = shopMaterialMap.get(shopMaterialStore.getMaterialId()); + shopMaterial.getMaterialMation().setMaterialNorms(null); + shopMaterial.getMaterialMation().setBrandMation(null); + shopMaterial.getMaterialMation().setUnitGroupMation(null); + shopMaterial.getMaterialMation().setFirstInUnitMation(null); + shopMaterial.getMaterialMation().setFirstOutUnitMation(null); + shopMaterial.getMaterialMation().setNormsSpec(null); + shopMaterial.setContent(null); + shopMaterialStore.setShopMaterial(shopMaterial); + }); + Map> collect = shopMaterialStoreList.stream().collect(Collectors.groupingBy(ShopMaterialStore::getStoreId, Collectors.collectingAndThen( + Collectors.toList(), // 分组的 downstream + list -> { + if (list.size() > 8) { + return list.subList(0, 8); // 只取前8个元素 + } + return list; + } + ))); + return collect; + } + + @Override + public void queryShopMaterialMapByMaterialIdAndStoreId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + List materialIdList = JSONUtil.toList(params.get("materialId").toString(), null); + List storeIdList = JSONUtil.toList(params.get("storeId").toString(), null); + materialIdList = materialIdList.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList()); + storeIdList = storeIdList.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(materialIdList) || CollectionUtil.isEmpty(storeIdList)) { + return; + } + if (materialIdList.size() != storeIdList.size()) { + throw new CustomException("参数错误,materialId与storeId数量不一致"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + for (int i = 0; i < storeIdList.size(); i++) { + List finalMaterialIdList = materialIdList; + List finalStoreIdList = storeIdList; + int finalI = i; + queryWrapper.or(wrapper -> { + wrapper.eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getMaterialId), finalMaterialIdList.get(finalI)) + .eq(MybatisPlusUtil.toColumns(ShopMaterialStore::getStoreId), finalStoreIdList.get(finalI)); + }); + } + List list = list(queryWrapper); + Map collect = list.stream() + .collect(Collectors.toMap(bean -> String.format("%s_%s", bean.getMaterialId(), bean.getStoreId()), bean -> bean.getId())); + outputObject.setBean(collect); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/controller/SupplierController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/controller/SupplierController.java new file mode 100644 index 0000000..523e41a --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/controller/SupplierController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.supplier.entity.Supplier; +import com.skyeye.supplier.entity.SupplierQueryDo; +import com.skyeye.supplier.service.SupplierService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SupplierController + * @Description: 供应商管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/14 10:48 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "供应商管理", tags = "供应商管理", modelName = "供应商管理") +public class SupplierController { + + @Autowired + private SupplierService supplierService; + + /** + * 获取供应商列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "supplier001", value = "获取供应商列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SupplierQueryDo.class) + @RequestMapping("/post/SupplierController/querySupplierList") + public void querySupplierList(InputObject inputObject, OutputObject outputObject) { + supplierService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑供应商 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSupplier", value = "添加/编辑供应商", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Supplier.class) + @RequestMapping("/post/SupplierContronller/writeSupplier") + public void writeSupplier(InputObject inputObject, OutputObject outputObject) { + supplierService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id批量查询供应商信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySupplierListByIds", value = "根据id批量查询供应商信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierController/querySupplierListByIds") + public void querySupplierListByIds(InputObject inputObject, OutputObject outputObject) { + supplierService.selectByIds(inputObject, outputObject); + } + + /** + * 删除供应商信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "supplier004", value = "删除供应商信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SupplierController/deleteSupplierById") + public void deleteSupplierById(InputObject inputObject, OutputObject outputObject) { + supplierService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/dao/SupplierDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/dao/SupplierDao.java new file mode 100644 index 0000000..f8a51b1 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/dao/SupplierDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.supplier.entity.Supplier; + +/** + * @ClassName: SupplierDao + * @Description: 供应商管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/3 23:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/Supplier.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/Supplier.java new file mode 100644 index 0000000..1b38424 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/Supplier.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Supplier + * @Description: 供应商信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/02/15 13:28 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.ERP_SUPPLIER_CACHE_KEY) +@TableName(value = "erp_supplier") +@ApiModel("供应商信息实体类") +public class Supplier extends BaseGeneralInfo { + + @TableField(value = "fax") + @ApiModelProperty(value = "传真") + private String fax; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "tax_num") + @ApiModelProperty(value = "纳税人识别号") + private String taxNum; + + @TableField(value = "duty_paragraph") + @ApiModelProperty(value = "税号") + private String dutyParagraph; + + @TableField(value = "address") + @ApiModelProperty(value = "地址") + private String address; + + @TableField(value = "cus_url") + @ApiModelProperty(value = "供应商网址") + private String cusUrl; + + @TableField(value = "cor_representative") + @ApiModelProperty(value = "法人代表") + private String corRepresentative; + + @TableField(value = "bank_account") + @ApiModelProperty(value = "银行账号") + private String bankAccount; + + @TableField(value = "account_name") + @ApiModelProperty(value = "开户名称") + private String accountName; + + @TableField(value = "bank_name") + @ApiModelProperty(value = "开户银行名称") + private String bankName; + + @TableField(value = "bank_address") + @ApiModelProperty(value = "开户银行地址") + private String bankAddress; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(value = "team_template_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "团队模板id") + private String teamTemplateId; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/SupplierQueryDo.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/SupplierQueryDo.java new file mode 100644 index 0000000..43caede --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/entity/SupplierQueryDo.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: SupplierQueryDo + * @Description: 供应商列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 16:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("供应商列表查询条件实体类") +public class SupplierQueryDo extends CommonPageInfo implements Serializable { + + /** + * 团队模板id + */ + private List teamTemplateIds; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/SupplierService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/SupplierService.java new file mode 100644 index 0000000..3f5ec24 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/SupplierService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.supplier.entity.Supplier; + +/** + * @ClassName: SupplierService + * @Description: 供应商信息管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SupplierService extends SkyeyeBusinessService { + + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/impl/SupplierServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/impl/SupplierServiceImpl.java new file mode 100644 index 0000000..0aac8ae --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/supplier/service/impl/SupplierServiceImpl.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.supplier.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contract.entity.SupplierContract; +import com.skyeye.contract.service.SupplierContractService; +import com.skyeye.exception.CustomException; +import com.skyeye.sdk.catalog.service.CatalogSdkService; +import com.skyeye.supplier.dao.SupplierDao; +import com.skyeye.supplier.entity.Supplier; +import com.skyeye.supplier.service.SupplierService; +import com.skyeye.team.service.ITeamBusinessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: SupplierServiceImpl + * @Description: 供应商信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "供应商管理", groupName = "供应商管理") +public class SupplierServiceImpl extends SkyeyeBusinessServiceImpl implements SupplierService, CatalogSdkService { + + @Autowired + private ITeamBusinessService iTeamBusinessService; + + @Autowired + private SupplierContractService supplierContractService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "myCreate")) { + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(Supplier::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + } else if (StrUtil.equals(commonPageInfo.getType(), "myCharge")) { + // 我负责的 + List teamTemplateIds = iTeamBusinessService.getMyTeamIds(); + queryWrapper.in(MybatisPlusUtil.toColumns(Supplier::getTeamTemplateId), teamTemplateIds); + } + return queryWrapper; + } + + @Override + public void createPostpose(Supplier entity, String userId) { + // 创建团队信息 + iTeamBusinessService.createTeamBusiness(entity.getTeamTemplateId(), entity.getId(), getServiceClassName()); + } + + @Override + public void deletePreExecution(String id) { + // 获取与供应商相关的合同列表 + List beans = supplierContractService.querySupplierContractListByObjectId(id); + if (CollectionUtil.isNotEmpty(beans)) { + throw new CustomException("存在合同信息,无法删除."); + } + } + + @Override + public Supplier selectById(String id) { + Supplier supplier = super.selectById(id); + supplier.setServiceClassName(getServiceClassName()); + return supplier; + } + + @Override + public List selectByIds(String... ids) { + List suppliers = super.selectByIds(ids); + String serviceClassName = getServiceClassName(); + suppliers.forEach(supplier -> { + supplier.setServiceClassName(serviceClassName); + }); + return suppliers; + } + + @Override + public void deletePostpose(String id) { + iTeamBusinessService.deleteTeamBusiness(id, getServiceClassName()); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/classenum/WholeOrderOutFromType.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/classenum/WholeOrderOutFromType.java new file mode 100644 index 0000000..3a44e8e --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/classenum/WholeOrderOutFromType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: WholeOrderOutFromType + * @Description: 整单委外单来源单据类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/22 10:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum WholeOrderOutFromType implements SkyeyeEnumClass { + + PRODUCTION(1, "生产计划单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/controller/WholeOrderOutController.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/controller/WholeOrderOutController.java new file mode 100644 index 0000000..1db79ed --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/controller/WholeOrderOutController.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WholeOrderOutController + * @Description: 整单委外单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 20:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "整单委外单", tags = "整单委外单", modelName = "整单委外单") +public class WholeOrderOutController { + + @Autowired + private WholeOrderOutService wholeOrderOutService; + + /** + * 获取整单委外单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryWholeOrderOutList", value = "获取整单委外单列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WholeOrderOutController/queryWholeOrderOutList") + public void queryWholeOrderOutList(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑整单委外单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWholeOrderOut", value = "新增/编辑整单委外单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WholeOrderOut.class) + @RequestMapping("/post/WholeOrderOutController/writeWholeOrderOut") + public void writeWholeOrderOut(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 转采购入库单/到货单/采购退货单时,根据id查询整单委外单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryWholeOrderOutTransById", value = "转采购入库单/到货单/采购退货单时,根据id查询整单委外单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WholeOrderOutController/queryWholeOrderOutTransById") + public void queryWholeOrderOutTransById(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.queryWholeOrderOutTransById(inputObject, outputObject); + } + + /** + * 整单委外单信息转采购入库 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertWholeOrderOutToTurnPut", value = "整单委外单信息转采购入库", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchasePut.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WholeOrderOutController/insertWholeOrderOutToTurnPut") + public void insertWholeOrderOutToTurnPut(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.insertWholeOrderOutToTurnPut(inputObject, outputObject); + } + + /** + * 整单委外单信息转到货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertWholeOrderOutToTurnDelivery", value = "整单委外单信息转到货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseDelivery.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PurchaseDeliveryController/insertWholeOrderOutToTurnDelivery") + public void insertWholeOrderOutToTurnDelivery(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.insertWholeOrderOutToTurnDelivery(inputObject, outputObject); + } + + /** + * 整单委外单信息转采购退货单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertWholeOrderOutToReturns", value = "整单委外单信息转采购退货单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PurchaseReturn.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WholeOrderOutController/insertWholeOrderOutToReturns") + public void insertWholeOrderOutToReturns(InputObject inputObject, OutputObject outputObject) { + wholeOrderOutService.insertWholeOrderOutToReturns(inputObject, outputObject); + } + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/dao/WholeOrderOutDao.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/dao/WholeOrderOutDao.java new file mode 100644 index 0000000..9a2e52b --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/dao/WholeOrderOutDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.whole.entity.WholeOrderOut; + +/** + * @ClassName: WholeOrderOutDao + * @Description: 整单委外单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 20:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WholeOrderOutDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/entity/WholeOrderOut.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/entity/WholeOrderOut.java new file mode 100644 index 0000000..3150779 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/entity/WholeOrderOut.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.entity.ErpOrderHead; +import lombok.Data; + +/** + * @ClassName: WholeOrderOut + * @Description: 整单委外单实体类 + * --otherState:这里表示【整单委外单到货状态】参考#OrderArrivalState + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 20:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "erp:order:wholeOut", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "erp_depothead", autoResultMap = true) +@ApiModel("整单委外单实体类") +public class WholeOrderOut extends ErpOrderHead { + +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/WholeOrderOutService.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/WholeOrderOutService.java new file mode 100644 index 0000000..d96926d --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/WholeOrderOutService.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.service; + +import com.skyeye.business.service.SkyeyeErpOrderService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.whole.entity.WholeOrderOut; + +/** + * @ClassName: WholeOrderOutService + * @Description: 整单委外单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 20:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WholeOrderOutService extends SkyeyeErpOrderService { + + /** + * 修改到货状态 + * + * @param id 采购订单id + * @param arrivalState 到货状态 + */ + void editArrivalState(String id, Integer arrivalState); + + /** + * 修改质检状态 + * + * @param id 采购订单id + * @param qualityInspection 质检状态 + */ + void editQualityInspection(String id, Integer qualityInspection); + + void queryWholeOrderOutTransById(InputObject inputObject, OutputObject outputObject); + + void insertWholeOrderOutToTurnPut(InputObject inputObject, OutputObject outputObject); + + void insertWholeOrderOutToTurnDelivery(InputObject inputObject, OutputObject outputObject); + + void insertWholeOrderOutToReturns(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/impl/WholeOrderOutServiceImpl.java b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/impl/WholeOrderOutServiceImpl.java new file mode 100644 index 0000000..fad76ca --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/java/com/skyeye/whole/service/impl/WholeOrderOutServiceImpl.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.whole.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.business.classenum.OrderItemQualityInspectionType; +import com.skyeye.business.classenum.OrderQualityInspectionType; +import com.skyeye.business.service.impl.SkyeyeErpOrderServiceImpl; +import com.skyeye.classenum.ErpOrderStateEnum; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.depot.classenum.DepotPutOutType; +import com.skyeye.entity.ErpOrderItem; +import com.skyeye.exception.CustomException; +import com.skyeye.material.classenum.MaterialInOrderType; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.production.classenum.ProductionChildType; +import com.skyeye.production.classenum.ProductionOutState; +import com.skyeye.production.entity.Production; +import com.skyeye.production.entity.ProductionChild; +import com.skyeye.production.service.ProductionService; +import com.skyeye.purchase.classenum.OrderArrivalState; +import com.skyeye.purchase.classenum.PurchaseDeliveryFromType; +import com.skyeye.purchase.classenum.PurchasePutFromType; +import com.skyeye.purchase.classenum.PurchaseReturnsFromType; +import com.skyeye.purchase.entity.PurchaseDelivery; +import com.skyeye.purchase.entity.PurchasePut; +import com.skyeye.purchase.entity.PurchaseReturn; +import com.skyeye.purchase.service.PurchaseDeliveryService; +import com.skyeye.purchase.service.PurchasePutService; +import com.skyeye.purchase.service.PurchaseReturnsService; +import com.skyeye.util.ErpOrderUtil; +import com.skyeye.whole.classenum.WholeOrderOutFromType; +import com.skyeye.whole.dao.WholeOrderOutDao; +import com.skyeye.whole.entity.WholeOrderOut; +import com.skyeye.whole.service.WholeOrderOutService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WholeOrderOutServiceImpl + * @Description: 整单委外单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/22 20:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "整单委外单", groupName = "整单委外单", flowable = true) +public class WholeOrderOutServiceImpl extends SkyeyeErpOrderServiceImpl implements WholeOrderOutService { + + @Autowired + private ProductionService productionService; + + @Autowired + private PurchasePutService purchasePutService; + + @Autowired + private PurchaseDeliveryService purchaseDeliveryService; + + @Autowired + private PurchaseReturnsService purchaseReturnsService; + + @Autowired + private IDepmentService iDepmentService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(WholeOrderOut::getHolderId), commonPageInfo.getHolderId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getFromId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(WholeOrderOut::getFromId), commonPageInfo.getFromId()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 生产计划单 + productionService.setOrderMationByFromId(beans, "fromId", "fromMation"); + return beans; + } + + @Override + public void validatorEntity(WholeOrderOut entity) { + if (StrUtil.isEmpty(entity.getHolderId())) { + throw new CustomException("请选择供应商."); + } + checkMaterialNorms(entity, false); + } + + @Override + public void createPrepose(WholeOrderOut entity) { + super.createPrepose(entity); + entity.setType(DepotPutOutType.PUT.getKey()); + setOtherMation(entity); + } + + @Override + public void updatePrepose(WholeOrderOut entity) { + super.updatePrepose(entity); + setOtherMation(entity); + } + + @Override + public void approvalEndIsSuccess(WholeOrderOut entity) { + entity = selectById(entity.getId()); + // 修改来源单据的状态信息 + checkMaterialNorms(entity, true); + } + + @Override + public WholeOrderOut selectById(String id) { + WholeOrderOut wholeOrderOut = super.selectById(id); + if (wholeOrderOut.getFromTypeId() == WholeOrderOutFromType.PRODUCTION.getKey()) { + productionService.setDataMation(wholeOrderOut, WholeOrderOut::getFromId); + } + wholeOrderOut.getErpOrderItemList().forEach(erpOrderItem -> { + erpOrderItem.setQualityInspectionMation(OrderItemQualityInspectionType.getMation(erpOrderItem.getQualityInspection())); + }); + // 部门 + iDepmentService.setDataMation(wholeOrderOut, WholeOrderOut::getDepartmentId); + return wholeOrderOut; + } + + private static void setOtherMation(WholeOrderOut entity) { + // 设置质检类型 + Integer qualityInspection = OrderQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey(); + for (ErpOrderItem erpOrderItem : entity.getErpOrderItemList()) { + qualityInspection = setQualityInspection(erpOrderItem, qualityInspection); + erpOrderItem.setMType(MaterialInOrderType.GENERAL.getKey()); + } + entity.setQualityInspection(qualityInspection); + // 设置到货状态 + if (qualityInspection == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + // 如果需要质检,则需要先下【到货单】 + entity.setOtherState(OrderArrivalState.NEED_ARRIVAL.getKey()); + } else { + entity.setOtherState(OrderArrivalState.NOT_NEED_ARRIVAL.getKey()); + } + } + + private void checkMaterialNorms(WholeOrderOut entity, boolean setData) { + if (StrUtil.isEmpty(entity.getFromId())) { + return; + } + // 当前整单委外单的商品数量 + Map orderNormsNum = entity.getErpOrderItemList().stream() + .collect(Collectors.toMap(ErpOrderItem::getNormsId, ErpOrderItem::getOperNumber)); + // 获取已经下达整单委外单的商品信息 + Map executeNum = calcMaterialNormsNumByFromId(entity.getFromId()); + List inSqlNormsId = new ArrayList<>(executeNum.keySet()); + if (entity.getFromTypeId() == WholeOrderOutFromType.PRODUCTION.getKey()) { + Production production = productionService.selectById(entity.getFromId()); + // 获取需要【委外】的商品 + List productionChildList = production.getProductionChildList().stream() + .filter(bean -> bean.getProductionType() == ProductionChildType.OUTSOURCING.getKey()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(productionChildList)) { + throw new CustomException("该生产计划单下未包含需要委外的商品."); + } + List fromNormsIds = productionChildList.stream() + .map(ProductionChild::getNormsId).collect(Collectors.toList()); + super.checkIdFromOrderMaterialNorms(fromNormsIds, inSqlNormsId); + productionChildList.forEach(productionChild -> { + // 生产计划单数量 - 当前订单数量 - 已经下达整单委外单数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(productionChild.getOperNumber(), productionChild.getNormsId(), orderNormsNum, executeNum); + if (setData) { + productionChild.setOperNumber(surplusNum); + } + }); + if (setData) { + // 过滤掉剩余数量为0的商品 + productionChildList = productionChildList.stream() + .filter(productionChild -> productionChild.getOperNumber() > 0).collect(Collectors.toList()); + // 如果该生产计划单的商品已经全部下达整单委外单,那说明已经完成了生产计划单的内容 + if (CollectionUtil.isEmpty(productionChildList)) { + productionService.editOutState(production.getId(), ProductionOutState.COMPLATE_OUT.getKey()); + } else { + productionService.editOutState(production.getId(), ProductionOutState.PARTIAL_OUT.getKey()); + } + } + } + } + + @Override + public void editArrivalState(String id, Integer arrivalState) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(WholeOrderOut::getOtherState), arrivalState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void editQualityInspection(String id, Integer qualityInspection) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(WholeOrderOut::getQualityInspection), qualityInspection); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void queryWholeOrderOutTransById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + WholeOrderOut wholeOrderOut = selectById(id); + // 该整单委外单下的已经下达采购退货单(审核通过)的数量 + Map normsReturnMap = purchaseReturnsService.calcMaterialNormsNumByFromId(wholeOrderOut.getId()); + if (wholeOrderOut.getQualityInspection() == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + // 需要质检,计算未到货数量 + Map normsNum = purchaseDeliveryService.calcMaterialNormsNumByFromId(id); + wholeOrderOut.getErpOrderItemList().forEach(erpOrderItem -> { + // 整单委外单数量 - 已到货数量 - 已退货数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(erpOrderItem.getOperNumber(), erpOrderItem.getNormsId(), normsNum, normsReturnMap); + // 设置未下达到货单的商品数量 + erpOrderItem.setOperNumber(surplusNum); + }); + } else { + // 免检,计算未入库的数量 + Map normsNum = purchasePutService.calcMaterialNormsNumByFromId(id); + wholeOrderOut.getErpOrderItemList().forEach(erpOrderItem -> { + // 整单委外单数量 - 已入库数量 - 已退货数量 + Integer surplusNum = ErpOrderUtil.checkOperNumber(erpOrderItem.getOperNumber(), erpOrderItem.getNormsId(), normsNum, normsReturnMap); + // 设置未下达采购入库单的商品数量 + erpOrderItem.setOperNumber(surplusNum); + }); + } + // 过滤掉数量为0的进行生成采购入库单/到货单/退货单 + wholeOrderOut.setErpOrderItemList(wholeOrderOut.getErpOrderItemList().stream() + .filter(erpOrderItem -> erpOrderItem.getOperNumber() > 0).collect(Collectors.toList())); + outputObject.setBean(wholeOrderOut); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void insertWholeOrderOutToTurnPut(InputObject inputObject, OutputObject outputObject) { + PurchasePut purchasePut = inputObject.getParams(PurchasePut.class); + // 获取整单委外单状态 + WholeOrderOut order = selectById(purchasePut.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以进行入库 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + if (order.getQualityInspection() == OrderQualityInspectionType.NEED_QUALITYINS_INS.getKey()) { + throw new CustomException("该订单需要进行质检,无法直接转采购入库,请先转【到货单】."); + } + String userId = inputObject.getLogParams().get("id").toString(); + purchasePut.setFromId(purchasePut.getId()); + purchasePut.setFromTypeId(PurchasePutFromType.WHOLE_ORDER_OUT.getKey()); + purchasePut.setId(StrUtil.EMPTY); + purchasePutService.createEntity(purchasePut, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购入库单."); + } + } + + @Override + public void insertWholeOrderOutToTurnDelivery(InputObject inputObject, OutputObject outputObject) { + PurchaseDelivery purchaseDelivery = inputObject.getParams(PurchaseDelivery.class); + // 获取整单委外单状态 + WholeOrderOut order = selectById(purchaseDelivery.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到货单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + if (order.getQualityInspection() == OrderQualityInspectionType.NOT_NEED_QUALITYINS_INS.getKey()) { + throw new CustomException("该订单无需进行质检,请直接转采购入库."); + } + String userId = inputObject.getLogParams().get("id").toString(); + purchaseDelivery.setFromId(purchaseDelivery.getId()); + purchaseDelivery.setFromTypeId(PurchaseDeliveryFromType.WHOLE_ORDER_OUT.getKey()); + purchaseDelivery.setId(StrUtil.EMPTY); + purchaseDeliveryService.createEntity(purchaseDelivery, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达到货单."); + } + } + + @Override + public void insertWholeOrderOutToReturns(InputObject inputObject, OutputObject outputObject) { + PurchaseReturn purchaseReturn = inputObject.getParams(PurchaseReturn.class); + // 获取整单委外单状态 + WholeOrderOut order = selectById(purchaseReturn.getId()); + if (ObjectUtil.isEmpty(order)) { + throw new CustomException("该数据不存在."); + } + // 审核通过/部分完成的可以转到采购退货单 + if (FlowableStateEnum.PASS.getKey().equals(order.getState()) || ErpOrderStateEnum.PARTIALLY_COMPLETED.getKey().equals(order.getState())) { + String userId = inputObject.getLogParams().get("id").toString(); + purchaseReturn.setFromId(purchaseReturn.getId()); + purchaseReturn.setFromTypeId(PurchaseReturnsFromType.WHOLE_ORDER_OUT.getKey()); + purchaseReturn.setId(StrUtil.EMPTY); + purchaseReturnsService.createEntity(purchaseReturn, userId); + } else { + outputObject.setreturnMessage("状态错误,无法下达采购退货单."); + } + } + +} diff --git a/skyeye-erp/erp-pro/src/main/resources/mapper/depot/DepotLevelValMapper.xml b/skyeye-erp/erp-pro/src/main/resources/mapper/depot/DepotLevelValMapper.xml new file mode 100644 index 0000000..6a297fa --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/resources/mapper/depot/DepotLevelValMapper.xml @@ -0,0 +1,35 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/resources/mapper/erp/ErpPageMapper.xml b/skyeye-erp/erp-pro/src/main/resources/mapper/erp/ErpPageMapper.xml new file mode 100644 index 0000000..f76a9e2 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/resources/mapper/erp/ErpPageMapper.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/resources/mapper/erp/StatisticsMapper.xml b/skyeye-erp/erp-pro/src/main/resources/mapper/erp/StatisticsMapper.xml new file mode 100644 index 0000000..cb421df --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/resources/mapper/erp/StatisticsMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialMapper.xml b/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialMapper.xml new file mode 100644 index 0000000..071d025 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialMapper.xml @@ -0,0 +1,42 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialNormsStockMapper.xml b/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialNormsStockMapper.xml new file mode 100644 index 0000000..c6dc021 --- /dev/null +++ b/skyeye-erp/erp-pro/src/main/resources/mapper/material/MaterialNormsStockMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + diff --git a/skyeye-erp/erp-web/.gitignore b/skyeye-erp/erp-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-erp/erp-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-erp/erp-web/pom.xml b/skyeye-erp/erp-web/pom.xml new file mode 100644 index 0000000..d478400 --- /dev/null +++ b/skyeye-erp/erp-web/pom.xml @@ -0,0 +1,88 @@ + + + + skyeye-erp + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + erp-web + + + + + com.skyeye + erp-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-erp/erp-web/src/main/java/com/ErpApplication.java b/skyeye-erp/erp-web/src/main/java/com/ErpApplication.java new file mode 100644 index 0000000..2c8b0b3 --- /dev/null +++ b/skyeye-erp/erp-web/src/main/java/com/ErpApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class ErpApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(ErpApplication.class, args); + } + +} diff --git a/skyeye-erp/erp-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-erp/erp-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..3a12491 --- /dev/null +++ b/skyeye-erp/erp-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.github.yulichang.injector.MPJSqlInjector; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + GlobalConfig globalConfig = new GlobalConfig(); + globalConfig.setSqlInjector(new MPJSqlInjector()); + mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-erp/erp-web/src/main/resources/banner.txt b/skyeye-erp/erp-web/src/main/resources/banner.txt new file mode 100644 index 0000000..4ac0199 --- /dev/null +++ b/skyeye-erp/erp-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev erp-web.jar >> /opt/service/project/nohup-erp.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-erp/erp-web/src/main/resources/bootstrap.yml b/skyeye-erp/erp-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..114bddd --- /dev/null +++ b/skyeye-erp/erp-web/src/main/resources/bootstrap.yml @@ -0,0 +1,56 @@ +server: + port: 8106 + +spring: + application: + name: skyeye-erp-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +topic: + # ERP商品规格一物一码生成条形码的消息 + material-norms-code-generate-barcode: MATERIAL_NORMS_CODE_GENERATE_BARCODE + +webroot: + # 项目相关的服务 + skyeye-project: skyeye-project-${spring.profiles.active} + # 售后服务相关的服务 + skyeye-seal-service: skyeye-seal-service-${spring.profiles.active} + # 门店相关的服务 + skyeye-shop: skyeye-shop-${spring.profiles.active} + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-erp/erp-web/src/main/resources/jvm调优参数配置 b/skyeye-erp/erp-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-erp/erp-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-erp/erp-web/src/main/resources/log4j.properties b/skyeye-erp/erp-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-erp/erp-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-erp/pom.xml b/skyeye-erp/pom.xml new file mode 100644 index 0000000..a97c091 --- /dev/null +++ b/skyeye-erp/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + erp-common + erp-web + erp-pro + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-erp + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-flowable/.gitignore b/skyeye-flowable/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-flowable/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-common/.gitignore b/skyeye-flowable/flowable-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-flowable/flowable-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-common/pom.xml b/skyeye-flowable/flowable-common/pom.xml new file mode 100644 index 0000000..11cb3cb --- /dev/null +++ b/skyeye-flowable/flowable-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-flowable + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + flowable-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-common/src/main/java/com/skyeye/common/constans/ActivitiConstants.java b/skyeye-flowable/flowable-common/src/main/java/com/skyeye/common/constans/ActivitiConstants.java new file mode 100644 index 0000000..552ef5d --- /dev/null +++ b/skyeye-flowable/flowable-common/src/main/java/com/skyeye/common/constans/ActivitiConstants.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.constans; + +import cn.hutool.core.bean.BeanUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.*; + +/** + * @ClassName: ActivitiConstants + * @Description: 工作流模块常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/16 23:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class ActivitiConstants { + + public static final String APPROVAL_PASS = "pass"; + + public static final String APPROVAL_NO_PASS = "nopass"; + + public static final String ASSIGNEE_USER = "assignee"; + + public static final String ASSIGNEE_USER_MATION = "assigneeMation"; + + public static final String ASSIGNEE_USER_LIST = "assigneeList"; + + public static final String ASSIGNEE_USER_MATION_LIST = "assigneeMationList"; + + public static final String DEFAULT_ASSIGNEE_LIST_EXP = "${" + ASSIGNEE_USER_LIST + "}"; + + public static final String ASSIGNEE_USER_EXP = "${" + ASSIGNEE_USER + "}"; + + /** + * form表单数据存储在task的varables的key + */ + public static final String PROCESSINSTANCEID_TASK_VARABLES = "baseTask"; + + /** + * 存储在流程信息中的审批/其他操作的历史意见 + */ + public static final String PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES = "leaveOpinionList"; + + /** + * 用户任务 + */ + public static final String USER_TASK = "userTask"; + + /** + * 排他网关 + */ + public static final String EXCLUSIVE_GATEWAY = "exclusiveGateway"; + + /** + * 后加签 + */ + public static final String AFTER_ADDSIGN = "after"; + + /** + * 前加签 + */ + public static final String BEFORE_ADDSIGN = "before"; + + /** + * 并行会签加签子实例的区分 + */ + public static final String PARALLEL_MULTILN_STANCE_EXECTTION_CHILD = "parallelMultilnStanceExecttionChild"; + + /** + * 会签节点必选评审人标识 + */ + public static final String PARALLEL_MULTILN_STANCE_EXECTTION_ISMANDATORY = "parallelMultilnStanceExecttionIsmandatory"; + + /** + * 串行会签存入变量中的主持人的key + */ + public static final String SEQUENTIAL_MULTILN_STANCE_EXECTTION_HOST_ASSIGNEE = "sequentialMultilnStanceExecttionHostAssignee"; + + /** + * 工作流用户表格对象 + */ + @Getter + @NoArgsConstructor + @AllArgsConstructor + public enum ActivitiUserElement { + ROW_INDEX("rowIndex", null, "序号", "ro", "center", false, false, + false, false, "eq", "70", "", false, true, + "#rspan", true, true), + IS_SELECTED("isSelected", null, "选择", "ro", "center", false, false, + false, false, "eq", "50", "fnRenderSelectUser", false, true, + "#rspan", true, true), + ID("id", null, "用户ID", "ro", "center", false, false, + false, false, "eq", "100", "", false, true, + "#rspan", true, true), + FIRST_NAME("firstName", null, "用户名", "ro", "center", false, false, + false, false, "eq", "120", "", false, true, + "#rspan", true, true), + LAST_NAME("lastName", null, "登录名", "ro", "center", false, false, + false, false, "eq", "120", "", false, true, + "#rspan", true, true), + EMAIL("email", null, "邮箱", "ro", "center", false, false, + false, false, "eq", "120", "", false, true, + "#rspan", true, true), + NAME("name", null, "用户组", "ro", "center", false, false, + false, false, "eq", "120", "", false, true, + "#rspan", true, true); + + private String key; + + private String id; + + private String header; + + private String type; + + private String align; + + private boolean allowSort; + + private boolean allowSearch; + + private boolean hidden; + + private boolean enableTooltip; + + private String operator; + + private String width; + + private String fnRender; + + private boolean isServerCondition; + + private boolean isExport; + + private String subHeader; + + private boolean isQuote; + + private boolean isImport; + + } + + public static List> getAllList() { + List> beans = new ArrayList<>(); + for (ActivitiUserElement value : ActivitiUserElement.values()) { + Map bean = BeanUtil.beanToMap(value); + beans.add(bean); + } + return beans; + } + + public static Map getMap2PointKey(String key) { + for (ActivitiUserElement value : ActivitiUserElement.values()) { + if (key.equals(value.getKey())) { + return BeanUtil.beanToMap(value); + } + } + return null; + } + + public static List> getPointKeyList(String... keys) { + List> beans = new ArrayList<>(); + for (ActivitiUserElement value : ActivitiUserElement.values()) { + if (Arrays.asList(keys).contains(value.getKey())) { + Map bean = BeanUtil.beanToMap(value); + beans.add(bean); + } + } + return beans; + } + + public static List> getActivitiUserColumnList() { + return getPointKeyList("rowIndex", "isSelected", "id", "firstName", "lastName", "email"); + } + + public static Map getActivitiUserColumnMap() { + Map bean = new HashMap<>(); + bean.put("rowIndex", getMap2PointKey("rowIndex")); + bean.put("isSelected", getMap2PointKey("isSelected")); + bean.put("id", getMap2PointKey("id")); + bean.put("firstName", getMap2PointKey("firstName")); + bean.put("lastName", getMap2PointKey("lastName")); + bean.put("email", getMap2PointKey("email")); + return bean; + } + + public static List> getActivitiGroupColumnList() { + return getPointKeyList("rowIndex", "isSelected", "id", "name"); + } + + public static Map getActivitiGroupColumnMap() { + Map bean = new HashMap<>(); + bean.put("rowIndex", getMap2PointKey("rowIndex")); + bean.put("isSelected", getMap2PointKey("isSelected")); + bean.put("id", getMap2PointKey("id")); + bean.put("name", getMap2PointKey("name")); + return bean; + } + + public static List> getActivitiUserColumnListByGroupId() { + return getPointKeyList("rowIndex", "firstName", "lastName", "email"); + } + + public static Map getActivitiUserColumnMapByGroupId() { + Map bean = new HashMap<>(); + bean.put("rowIndex", getMap2PointKey("rowIndex")); + bean.put("firstName", getMap2PointKey("firstName")); + bean.put("lastName", getMap2PointKey("lastName")); + bean.put("email", getMap2PointKey("email")); + return bean; + } + + @Getter + @NoArgsConstructor + @AllArgsConstructor + public enum LeaveType { + APPROVAL_COMMENTS(1, "审批意见类型"), + TASK_DELEGATE(2, "任务委派类型"), + TASK_DELEGATE_RESULT(21, "任务委派审批结果"), + TASK_TRANSFER(3, "任务转办类型"), + BEFORE_ADD_SIGN_TASK(4, "前加签类型"), + AFTER_ADD_SIGN_TASK(5, "后加签类型"), + JOINTLY_SIGN_TASK(6, "会签加减签"); + + private Integer type; + + private String name; + } + +} diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/db2.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/db2.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/db2.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/h2.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/h2.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/hsql.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/hsql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/mssql.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/mssql.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/mssql.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/mysql.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/mysql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/oracle.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/oracle.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/oracle.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/postgres.properties b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/postgres.properties new file mode 100644 index 0000000..abe3f3d --- /dev/null +++ b/skyeye-flowable/flowable-common/src/main/resources/org/flowable/db/properties/postgres.properties @@ -0,0 +1 @@ +blobType=BINARY diff --git a/skyeye-flowable/flowable-entity/.gitignore b/skyeye-flowable/flowable-entity/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-flowable/flowable-entity/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-entity/pom.xml b/skyeye-flowable/flowable-entity/pom.xml new file mode 100644 index 0000000..4d24576 --- /dev/null +++ b/skyeye-flowable/flowable-entity/pom.xml @@ -0,0 +1,30 @@ + + + + skyeye-flowable + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + flowable-entity + + + 8 + 8 + + + + + + + com.skyeye + flowable-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/.gitignore b/skyeye-flowable/flowable-main/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-flowable/flowable-main/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/pom.xml b/skyeye-flowable/flowable-main/pom.xml new file mode 100644 index 0000000..bddb90a --- /dev/null +++ b/skyeye-flowable/flowable-main/pom.xml @@ -0,0 +1,57 @@ + + + + skyeye-flowable + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + flowable-main + + + 8 + 8 + + + + + + + com.skyeye + flowable-entity + 1.0-SNAPSHOT + + + + + com.skyeye + flowable-common + 1.0-SNAPSHOT + + + + org.apache.xmlgraphics + batik-codec + 1.7 + + + org.apache.xmlgraphics + batik-css + 1.7 + + + org.apache.xmlgraphics + batik-svg-dom + 1.7 + + + org.apache.xmlgraphics + batik-svggen + 1.7 + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/classenum/ProcessInstanceWeatherEnd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/classenum/ProcessInstanceWeatherEnd.java new file mode 100644 index 0000000..d86f652 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/classenum/ProcessInstanceWeatherEnd.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProcessInstanceWeatherEnd + * @Description: 流程是否结束的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/16 14:00 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProcessInstanceWeatherEnd implements SkyeyeEnumClass { + + NOT_FINISHED(0, "未结束", true, false), + ENDED(1, "已结束", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AbstractCountersignCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AbstractCountersignCmd.java new file mode 100644 index 0000000..1262811 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AbstractCountersignCmd.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.common.util.SpringUtils; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; + +/** + * @ClassName: AbstractCountersignCmd + * @Description: 会签加减签功能公共类 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 19:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public abstract class AbstractCountersignCmd { + + protected RuntimeService runtimeService; + + protected TaskService taskService; + + protected RepositoryService repositoryService; + + protected ActivitiTaskService activitiTaskService; + + protected ManagementService managementService; + + protected ActivitiModelService activitiModelService; + + public AbstractCountersignCmd() { + runtimeService = SpringUtils.getBean(RuntimeService.class); + taskService = SpringUtils.getBean(TaskService.class); + repositoryService = SpringUtils.getBean(RepositoryService.class); + activitiTaskService = SpringUtils.getBean(ActivitiTaskService.class); + managementService = SpringUtils.getBean(ManagementService.class); + activitiModelService = SpringUtils.getBean(ActivitiModelService.class); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AddMultiInstanceExecutionCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AddMultiInstanceExecutionCmd.java new file mode 100644 index 0000000..6f41a17 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/AddMultiInstanceExecutionCmd.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.common.constans.ActivitiConstants; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AddMultiInstanceExecutionCmd + * @Description: 进行会签加签命令 flowable:org.flowable.engine.impl.cmd.AddMultiInstanceExecutionCmd + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 19:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class AddMultiInstanceExecutionCmd extends AbstractCountersignCmd implements Command { + + private static Logger LOGGER = LoggerFactory.getLogger(AddMultiInstanceExecutionCmd.class); + + /** + * 当前任务ID + */ + private String taskId; + + /** + * 审核人 + */ + private List> assigneeList; + + private List> allAssigneeList; + + public AddMultiInstanceExecutionCmd(String taskId, List> assigneeList, List> allAssigneeList) { + super(); + if (ObjectUtils.isEmpty(assigneeList)) { + throw new RuntimeException("assigneeList 不能为空!"); + } + this.taskId = taskId; + this.assigneeList = assigneeList; + this.allAssigneeList = allAssigneeList; + } + + @Override + public String execute(CommandContext commandContext) { + TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + org.flowable.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + UserTask userTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + if (userTask.getLoopCharacteristics() == null) { + LOGGER.info("task:[" + task.getId() + "] 不是会签节任务"); + } + + // 获取父级 + ExecutionEntityImpl parentNode = execution.getParent(); + + // 获取流程变量 + int nrOfInstances = (int) runtimeService.getVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE); + int nrOfActiveInstances = (int) runtimeService.getVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES); + + // 获取管理器 + ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext); + + Object behavior = userTask.getBehavior(); + if (behavior instanceof ParallelMultiInstanceBehavior) { + LOGGER.info("task:[" + task.getId() + "] 并行会签 加签 任务"); + addParallelMultiInstance(commandContext, userTask, parentNode, nrOfInstances, nrOfActiveInstances, executionEntityManager); + } else if (behavior instanceof SequentialMultiInstanceBehavior) { + LOGGER.info("task:[" + task.getId() + "] 串行会签 加签 任务"); + addSequentialMultiInstance(task, execution, parentNode); + } + + return "加签成功"; + } + + private void addParallelMultiInstance(CommandContext commandContext, UserTask userTask, ExecutionEntityImpl parentNode, + int nrOfInstances, int nrOfActiveInstances, ExecutionEntityManager executionEntityManager) { + // 设置循环标志变量 + runtimeService.setVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE, nrOfInstances + assigneeList.size()); + runtimeService.setVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, nrOfActiveInstances + assigneeList.size()); + + // 新建任务列表 + for (Map assignee : this.assigneeList) { + // 创建 子 execution + ExecutionEntity newExecution = executionEntityManager.createChildExecution(parentNode); + newExecution.setActive(true); + newExecution.setVariableLocal(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, nrOfInstances); + newExecution.setVariableLocal(ActivitiConstants.ASSIGNEE_USER, assignee.get("id").toString()); + newExecution.setVariableLocal(ActivitiConstants.PARALLEL_MULTILN_STANCE_EXECTTION_CHILD, true); + newExecution.setCurrentFlowElement(userTask); + if (assignee.containsKey("isMandatory") && "1".equals(assignee.get("isMandatory").toString())) { + // 必选评审人 + newExecution.setVariableLocal(ActivitiConstants.PARALLEL_MULTILN_STANCE_EXECTTION_ISMANDATORY, true); + } + + // 任务总数 +1 + nrOfInstances++; + + // 推入时间表序列 + CommandContextUtil.getAgenda(commandContext).planContinueMultiInstanceOperation(newExecution, parentNode, nrOfInstances); + } + } + + private void addSequentialMultiInstance(TaskEntityImpl task, ExecutionEntityImpl execution, ExecutionEntityImpl parentNode) { + String assignee = task.getAssignee(); + // 当前任务执行位置 + int loopCounterIndex = 0; + List newAllUserIds = allAssigneeList.stream().map(p -> p.get("id").toString()).collect(Collectors.toList()); + for (int i = 0; i < newAllUserIds.size(); i++) { + String temp = newAllUserIds.get(i); + if (assignee.equals(temp)) { + loopCounterIndex = i; + } + } + + // 任务主持人 + String hostAssignee = (String) runtimeService.getVariableLocal(execution.getId(), ActivitiConstants.SEQUENTIAL_MULTILN_STANCE_EXECTTION_HOST_ASSIGNEE); + if (StringUtils.isEmpty(hostAssignee)) { + hostAssignee = task.getAssignee(); + runtimeService.setVariableLocal(execution.getId(), ActivitiConstants.SEQUENTIAL_MULTILN_STANCE_EXECTTION_HOST_ASSIGNEE, hostAssignee); + // 修改当前任务执行人 + taskService.setAssignee(taskId, newAllUserIds.get(0)); + execution.setVariableLocal(ActivitiConstants.ASSIGNEE_USER, newAllUserIds.get(0)); + loopCounterIndex = 0; + } else { + // 获取已经结束的评审任务 + List> tem = + allAssigneeList.stream().filter(bean -> bean.containsKey("isActive") && !(Boolean) bean.get("isActive")) + .collect(Collectors.toList()); + taskService.setAssignee(taskId, newAllUserIds.get(tem.size())); + execution.setVariableLocal(ActivitiConstants.ASSIGNEE_USER, newAllUserIds.get(tem.size())); + } + + // 修改 计数器位置 + execution.setVariableLocal(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, loopCounterIndex); + + // 修改全局变量 + Map variables = new HashMap<>(); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE, allAssigneeList.size()); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, allAssigneeList.size() - loopCounterIndex); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, loopCounterIndex); + variables.put(ActivitiConstants.ASSIGNEE_USER_LIST, newAllUserIds); + + runtimeService.setVariables(parentNode.getId(), variables); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/DeleteMultiInstanceExecutionCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/DeleteMultiInstanceExecutionCmd.java new file mode 100644 index 0000000..426ce29 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/DeleteMultiInstanceExecutionCmd.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.util.ToolUtil; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.Task; +import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +import java.util.*; + +/** + * @ClassName: DeleteMultiInstanceExecutionCmd + * @Description: 进行会签减签 flowable:org.flowable.engine.impl.cmd.DeleteMultiInstanceExecutionCmd + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 20:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class DeleteMultiInstanceExecutionCmd extends AbstractCountersignCmd implements Command { + + private static Logger LOGGER = LoggerFactory.getLogger(DeleteMultiInstanceExecutionCmd.class); + + /** + * 当前任务ID + */ + private String taskId; + + /** + * 审核人 + */ + private List assigneeList; + + public DeleteMultiInstanceExecutionCmd(String taskId, List assigneeList) { + super(); + if (ObjectUtils.isEmpty(assigneeList)) { + throw new RuntimeException("assigneeList 不能为空!"); + } + + this.taskId = taskId; + this.assigneeList = assigneeList; + } + + @Override + public String execute(CommandContext commandContext) { + TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + org.flowable.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + UserTask userTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + if (userTask.getLoopCharacteristics() == null) { + LOGGER.info("task:[" + task.getId() + "] 不是会签节任务"); + } + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + ExecutionEntityImpl parentNode = execution.getParent(); + + /** + * 获取任务完成数 + */ + int nrOfInstances = (int) runtimeService.getVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE); + int nrOfCompletedInstances = (int) runtimeService.getVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES); + + /** + * 转换判断标识 + */ + Set assigneeSet = new HashSet<>(assigneeList); + ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext); + + Object behavior = userTask.getBehavior(); + /** + * 进行并行任务 减签 + */ + if (behavior instanceof ParallelMultiInstanceBehavior) { + LOGGER.info("task:[" + task.getId() + "] 并行会签 减签 任务"); + + /** + * 当前任务列表 + */ + List taskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); + + for (Task obj : taskList) { + ExecutionEntityImpl temp = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(obj.getExecutionId()).singleResult(); + String objAssignee = getParallelMultiInstanceBehaviorAssignee(obj, temp); + if (assigneeSet.contains(objAssignee)) { + nrOfCompletedInstances++; + executionEntityManager.deleteExecutionAndRelatedData(temp, "会签减签", true); + } + } + + /** + * 修改已完成任务变量,增加被删减任务 + */ + runtimeService.setVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, nrOfCompletedInstances); + runtimeService.setVariable(parentNode.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, nrOfInstances - nrOfCompletedInstances); + } else if (behavior instanceof SequentialMultiInstanceBehavior) { + LOGGER.info("task:[" + task.getId() + "] 串行会签 减签 任务"); + + Object obj = parentNode.getVariable(ActivitiConstants.ASSIGNEE_USER_LIST); + if (obj == null || !(obj instanceof ArrayList)) { + throw new RuntimeException("没有找到任务执行人列表"); + } + + ArrayList sourceAssigneeList = (ArrayList) obj; + List newAssigneeList = new ArrayList<>(); + boolean flag = false; + int loopCounterIndex = -1; + String newAssignee = ""; + for (String temp : sourceAssigneeList) { + if (!assigneeSet.contains(temp)) { + newAssigneeList.add(temp); + } + + if (flag) { + newAssignee = temp; + flag = false; + } + + if (temp.equals(task.getAssignee())) { + if (assigneeSet.contains(temp)) { + flag = true; + loopCounterIndex = newAssigneeList.size(); + } else { + loopCounterIndex = newAssigneeList.size() - 1; + } + } + } + + /** + * 修改计数器变量 + */ + Map variables = new HashMap<>(); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE, newAssigneeList.size()); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, loopCounterIndex > 0 ? loopCounterIndex - 1 : 0); + variables.put(ActivitiConstants.ASSIGNEE_USER_LIST, newAssigneeList); + runtimeService.setVariables(parentNode.getId(), variables); + + /** + * 当前任务需要被删除,需要替换下一个任务审批人 + */ + if (!StringUtils.isEmpty(newAssignee)) { + taskService.setAssignee(taskId, newAssignee); + execution.setVariable(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, loopCounterIndex); + execution.setVariable(ActivitiConstants.ASSIGNEE_USER, newAssignee); + } + } + return "减签成功"; + } + + private String getParallelMultiInstanceBehaviorAssignee(Task task, ExecutionEntityImpl temp) { + if (ToolUtil.isBlank(task.getAssignee())) { + LOGGER.info("delete assignee when get assignee user from executionEntity"); + return String.valueOf(temp.getVariableLocal(ActivitiConstants.ASSIGNEE_USER)); + } + LOGGER.info("delete assignee when get assignee user from task"); + return task.getAssignee(); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/FindMultiInstanceExecutionUserCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/FindMultiInstanceExecutionUserCmd.java new file mode 100644 index 0000000..c3c2889 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/FindMultiInstanceExecutionUserCmd.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.eve.service.IAuthUserService; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; + +import java.util.*; + +/** + * @ClassName: FindMultiInstanceExecutionUserCmd + * @Description: 查找多实例节点的执行人 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/30 22:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class FindMultiInstanceExecutionUserCmd extends AbstractCountersignCmd implements Command>> { + + private static Logger LOGGER = LoggerFactory.getLogger(FindMultiInstanceExecutionUserCmd.class); + + /** + * 当前任务ID + */ + private String taskId; + + /** + * true:串行多实例节点,false:并行多实例节点 + */ + private Boolean isSequential; + + private IAuthUserService iAuthUserService; + + public FindMultiInstanceExecutionUserCmd(String taskId, Boolean isSequential) { + super(); + if (ObjectUtils.isEmpty(taskId)) { + throw new RuntimeException("taskId 不能为空!"); + } + this.taskId = taskId; + this.isSequential = isSequential; + iAuthUserService = SpringUtils.getBean(IAuthUserService.class); + } + + + @Override + public List> execute(CommandContext commandContext) { + TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + ExecutionEntityImpl parentNode = execution.getParent(); + + /** + * 获取管理器 + */ + ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext); + + List> assigneeList; + // true:串行多实例节点,false:并行多实例节点 + if (isSequential) { + LOGGER.info("get SequentialMultiInstanceAssigeeList, taskId is {}", taskId); + assigneeList = getSequentialMultiInstanceAssigeeList(taskId); + } else { + LOGGER.info("get ParallelMultiInstanceAssigeeList, taskId is {}", taskId); + assigneeList = getParallelMultiInstanceAssigeeList(executionEntityManager, parentNode, task); + } + + return assigneeList; + } + + /** + * 并行多实例节点获取参与人 + * + * @param executionEntityManager 管理器 + * @param task 任务 + */ + private List> getParallelMultiInstanceAssigeeList(ExecutionEntityManager executionEntityManager, ExecutionEntityImpl parentNode, + TaskEntityImpl task) { + List executionEntitys = executionEntityManager.findChildExecutionsByParentExecutionId(parentNode.getId()); + List> assigneeList = new ArrayList<>(); + executionEntitys.forEach(obj -> { + String assignee = String.valueOf(obj.getVariableLocal(ActivitiConstants.ASSIGNEE_USER)); + Map user = iAuthUserService.queryDataMationById(assignee); + // 参与人 + user.put("type", 0); + if (assignee.equals(task.getAssignee())) { + // 主持人 + user.put("noDelete", true); + user.put("type", 1); + } + // 判断该实例是否还在运行,如果已经结束,则不能删除 + if (!obj.isActive()) { + user.put("noDelete", true); + } + // 运行状态 + user.put("isActive", obj.isActive()); + if (obj.getVariableLocal(ActivitiConstants.PARALLEL_MULTILN_STANCE_EXECTTION_ISMANDATORY) != null) { + user.put("isMandatory", 1); + } + // 标识是回显的数据 + user.put("echo", true); + assigneeList.add(user); + }); + Collections.sort(assigneeList, new Comparator>() { + @Override + public int compare(Map p1, Map p2) { + int a = Integer.parseInt(p1.get("type").toString()); + int b = Integer.parseInt(p2.get("type").toString()); + if (a < b) { + return 1; + } + if (a == b) { + return 0; + } + return -1; + } + }); + return assigneeList; + } + + /** + * 串行多实例节点获取参与人 + * + * @param taskId 任务id + */ + private List> getSequentialMultiInstanceAssigeeList(String taskId) { + TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + ExecutionEntityImpl parentNode = execution.getParent(); + Object obj = parentNode.getVariable(ActivitiConstants.ASSIGNEE_USER_LIST); + if (obj == null || !(obj instanceof ArrayList)) { + LOGGER.info("not find task Executor List, task id is {}, initialization list", taskId); + List temp = new ArrayList<>(); + temp.add(task.getAssignee()); + obj = temp; + } + ArrayList assigneeStrList = (ArrayList) obj; + List> assigneeList = new ArrayList<>(); + int index = getCurrentTaskAssigneeIndex(assigneeStrList, task.getAssignee()); + for (int i = 0; i < assigneeStrList.size(); i++) { + String userId = assigneeStrList.get(i); + Map user = iAuthUserService.queryDataMationById(userId); + // 参与人 + user.put("type", 0); + if (userId.equals(task.getAssignee())) { + // 主持人 + user.put("noDelete", true); + user.put("type", 1); + } + // 运行状态 + user.put("isActive", true); + if (i < index) { + user.put("noDelete", true); + user.put("isActive", false); + } else if (i == index) { + user.put("noDelete", true); + } + // 标识是回显的数据 + user.put("echo", true); + assigneeList.add(user); + } + return assigneeList; + } + + private int getCurrentTaskAssigneeIndex(ArrayList assigneeStrList, String assignee) { + for (int i = 0; i < assigneeStrList.size(); i++) { + if (assignee.equals(assigneeStrList.get(i))) { + return i; + } + } + return 0; + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/GetMultiInstanceExecutionMation.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/GetMultiInstanceExecutionMation.java new file mode 100644 index 0000000..b014366 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/GetMultiInstanceExecutionMation.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.util.ReflexUtil; +import com.skyeye.common.util.ToolUtil; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.task.api.Task; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: GetMultiInstanceExecutionMation + * @Description: 获取多实例节点的信息 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/1 16:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class GetMultiInstanceExecutionMation extends AbstractCountersignCmd implements Command { + + private static Logger LOGGER = LoggerFactory.getLogger(GetMultiInstanceExecutionMation.class); + + /** + * 当前任务ID + */ + private String taskId; + + public GetMultiInstanceExecutionMation(String taskId) { + super(); + if (ObjectUtils.isEmpty(taskId)) { + throw new RuntimeException("taskId 不能为空!"); + } + this.taskId = taskId; + } + + @Override + public Map execute(CommandContext commandContext) { + UserTask currentTaskNode = activitiTaskService.getCurrentUserTaskByTaskId(taskId); + Map result = new HashMap<>(); + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + int nrOfInstances = (int) runtimeService.getVariable(execution.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE); + int nrOfActiveInstances = (int) runtimeService.getVariable(execution.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES); + int nrOfCompletedInstances = (int) runtimeService.getVariable(execution.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES); + // 支持人不参与会签,所以总数和正在执行的会签数需要减1 + result.put("nrOfInstances", nrOfInstances - 1); + result.put("nrOfActiveInstances", nrOfActiveInstances - 1); + result.put("nrOfCompletedInstances", nrOfCompletedInstances); + result.put("completionCondition", currentTaskNode.getLoopCharacteristics().getCompletionCondition()); + Object behavior = currentTaskNode.getBehavior(); + if (behavior instanceof ParallelMultiInstanceBehavior) { + // 并行会签 + // 判断是否是子实例 + if (execution.getVariableLocal(ActivitiConstants.PARALLEL_MULTILN_STANCE_EXECTTION_CHILD) != null) { + // 子实例 + LOGGER.info("ParallelMultiInstance task id [{}] is child ExecutionEntity", task.getId()); + result.put("multilnStanceExecttionChild", true); + } else { + LOGGER.info("ParallelMultiInstance task id [{}] is parent ExecutionEntity", task.getId()); + result.put("multilnStanceExecttionChild", false); + } + } else if (behavior instanceof SequentialMultiInstanceBehavior) { + // 串行会签 + ExecutionEntityImpl parentNode = execution.getParent(); + Object obj = runtimeService.getVariable(parentNode.getId(), ActivitiConstants.ASSIGNEE_USER_LIST); + if (obj == null) { + result.put("multilnStanceExecttionChild", false); + } else { + List assigneeList = (List) obj; + String assignee = task.getAssignee(); + int index = getCurrentTaskAssigneeIndex(assigneeList, assignee); + if (index != assigneeList.size() - 1) { + result.put("nrOfActiveInstances", assigneeList.size() - 1 - index); + result.put("nrOfCompletedInstances", index); + LOGGER.info("SequentialMultiInstance task id [{}] is child ExecutionEntity", task.getId()); + result.put("multilnStanceExecttionChild", true); + } else { + result.put("nrOfActiveInstances", 0); + result.put("nrOfCompletedInstances", assigneeList.size() - 1); + LOGGER.info("SequentialMultiInstance task id [{}] is parent ExecutionEntity", task.getId()); + result.put("multilnStanceExecttionChild", false); + } + } + } + getApprovalResult(currentTaskNode, result); + return result; + } + + private void getApprovalResult(UserTask currentTaskNode, Map result) { + // true:串行多实例节点,false:并行多实例节点 + Boolean isSequential = currentTaskNode.getLoopCharacteristics().isSequential(); + if (isSequential) { + int nrOfActiveInstances = Integer.parseInt(result.get("nrOfActiveInstances").toString()); + if (nrOfActiveInstances != 0) { + return; + } + } + List> assigneeList = managementService.executeCommand(new FindMultiInstanceExecutionUserCmd(taskId, isSequential)); + // 获取必选评审人的活动节点,如果没有活动的必选评审人节点,则去做表达式的校验,判断该节点的结果是否通过 + assigneeList = assigneeList.stream().filter(bean -> (Boolean) bean.get("isActive") && bean.containsKey("isMandatory")).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(assigneeList)) { + Map newMap = result.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue()))); + Boolean approvalResult = (Boolean) ReflexUtil.convertToCode( + regexCompletionCondition(currentTaskNode.getLoopCharacteristics().getCompletionCondition()), newMap); + result.put("approvalResult", approvalResult); + } + } + + private String regexCompletionCondition(String completionCondition) { + if (ToolUtil.isBlank(completionCondition)) { + return "nrOfInstances == nrOfCompletedInstances"; + } + return completionCondition.replace("${", "").replace("}", ""); + } + + private int getCurrentTaskAssigneeIndex(List assigneeStrList, String assignee) { + for (int i = 0; i < assigneeStrList.size(); i++) { + if (assignee.equals(assigneeStrList.get(i))) { + return i; + } + } + return 0; + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/HandlerMultiInstanceExecutionCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/HandlerMultiInstanceExecutionCmd.java new file mode 100644 index 0000000..927e184 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/HandlerMultiInstanceExecutionCmd.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.common.constans.ActivitiConstants; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.task.api.Task; +import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: HandlerMultiInstanceExecutionCmd + * @Description: 任务完成时,完成会签子任务 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/2 13:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class HandlerMultiInstanceExecutionCmd extends AbstractCountersignCmd implements Command { + + private static Logger LOGGER = LoggerFactory.getLogger(HandlerMultiInstanceExecutionCmd.class); + + /** + * 当前任务ID + */ + private String taskId; + + private Map user; + + private boolean flag; + + private String opinion; + + public HandlerMultiInstanceExecutionCmd(String taskId, Map user, boolean flag, String opinion) { + super(); + if (ObjectUtils.isEmpty(taskId)) { + throw new RuntimeException("taskId 不能为空!"); + } + + this.taskId = taskId; + this.user = user; + this.flag = flag; + this.opinion = opinion; + } + + @Override + public Boolean execute(CommandContext commandContext) { + TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + org.flowable.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + UserTask userTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + if (userTask.getLoopCharacteristics() == null) { + LOGGER.info("task:[" + task.getId() + "] 不是会签节任务"); + return true; + } + + ExecutionEntityImpl execution = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult(); + Object behavior = userTask.getBehavior(); + /** + * 进行并行任务 完成多余子任务 + */ + if (behavior instanceof ParallelMultiInstanceBehavior) { + LOGGER.info("task:[" + task.getId() + "] 并行会签 完成多余子任务"); + if (execution.getVariableLocal(ActivitiConstants.PARALLEL_MULTILN_STANCE_EXECTTION_CHILD) != null) { + // 当前任务是子实例不在往下执行 + LOGGER.info("task id [{}] is child ExecutionEntity", task.getId()); + } else { + // 当前任务列表 + List taskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); + for (Task obj : taskList) { + if (!obj.getId().equals(taskId)) { + taskService.complete(obj.getId()); + } + } + } + } else if (behavior instanceof SequentialMultiInstanceBehavior) { + // 获取父级 + ExecutionEntityImpl parentNode = execution.getParent(); + // 设置其他参数信息 + Map variables = runtimeService.getVariables(parentNode.getId()); + Integer nrOfActiveInstances = Integer.parseInt(variables.get(RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES).toString()); + Integer nrOfCompletedInstances = Integer.parseInt(variables.get(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES).toString()); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, nrOfActiveInstances - 1); + variables.put(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, nrOfCompletedInstances + 1); + runtimeService.setVariables(parentNode.getId(), variables); + // 获取设置的会签人集合 + List assigneeList = + (List) runtimeService.getVariable(parentNode.getId(), ActivitiConstants.ASSIGNEE_USER_LIST); + String assignee = task.getAssignee(); + int index = getCurrentTaskAssigneeIndex(assigneeList, assignee); + if (index != assigneeList.size() - 1) { + // 修改审批意见 + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), opinion, flag, task, ActivitiConstants.LeaveType.APPROVAL_COMMENTS.getType()); + runtimeService.setVariable(task.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + taskService.setAssignee(task.getId(), assigneeList.get(index + 1)); + return false; + } + } + + return true; + } + + private int getCurrentTaskAssigneeIndex(List assigneeStrList, String assignee) { + for (int i = 0; i < assigneeStrList.size(); i++) { + if (assignee.equals(assigneeStrList.get(i))) { + return i; + } + } + return 0; + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/NewMultiInstanceExecutionSetAssignee.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/NewMultiInstanceExecutionSetAssignee.java new file mode 100644 index 0000000..876e3d2 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/multiinstanceexecution/NewMultiInstanceExecutionSetAssignee.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.multiinstanceexecution; + +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.util.ToolUtil; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.task.api.Task; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; + +import java.util.List; + +/** + * @ClassName: NewMultiInstanceExecutionSetAssignee + * @Description: flowable 新增会签节点后,task的审批人为空的解决办法 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/1 11:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class NewMultiInstanceExecutionSetAssignee extends AbstractCountersignCmd implements Command { + + private static Logger LOGGER = LoggerFactory.getLogger(NewMultiInstanceExecutionSetAssignee.class); + + /** + * 当前任务ID + */ + private String taskId; + + /** + * 审核人 + */ + private List assigneeList; + + public NewMultiInstanceExecutionSetAssignee(String taskId, List assigneeList) { + super(); + if (ObjectUtils.isEmpty(assigneeList)) { + throw new RuntimeException("assigneeList 不能为空!"); + } + this.taskId = taskId; + this.assigneeList = assigneeList; + } + + @Override + public String execute(CommandContext commandContext) { + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + List taskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list(); + for (Task obj : taskList) { + if (ToolUtil.isBlank(obj.getAssignee())) { + ExecutionEntityImpl temp = (ExecutionEntityImpl) runtimeService.createExecutionQuery().executionId(obj.getExecutionId()).singleResult(); + if (assigneeList.contains(temp.getVariableLocal(ActivitiConstants.ASSIGNEE_USER))) { + obj.setAssignee(temp.getVariableLocal(ActivitiConstants.ASSIGNEE_USER).toString()); + taskService.saveTask(obj); + } + } + } + return null; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/nextusertask/FindNextUserTaskNodeCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/nextusertask/FindNextUserTaskNodeCmd.java new file mode 100644 index 0000000..7914ae1 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/nextusertask/FindNextUserTaskNodeCmd.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.nextusertask; + +import org.apache.commons.collections.CollectionUtils; +import org.flowable.bpmn.model.*; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.condition.ConditionUtil; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FindNextUserTaskNodeCmd + * @Description: 获取下一个UserTask的信息 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 23:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class FindNextUserTaskNodeCmd implements Command { + + private final ExecutionEntity execution; + private final BpmnModel bpmnModel; + private Map vars; + + /** + * 返回下一用户节点 + */ + private UserTask nextUserTask; + + /** + * @param execution 当前执行实例 + * @param bpmnModel 当前执行实例的模型 + * @param vars 参与计算流程条件的变量 + */ + public FindNextUserTaskNodeCmd(ExecutionEntity execution, BpmnModel bpmnModel, Map vars) { + this.execution = execution; + this.bpmnModel = bpmnModel; + this.vars = vars; + } + + @Override + public UserTask execute(CommandContext commandContext) { + // 当前流程节点信息 + FlowElement currentNode = bpmnModel.getFlowElement(execution.getActivityId()); + execution.setVariables(vars); + // 获取流程曲线走向 + List outgoingFlows = ((FlowNode) currentNode).getOutgoingFlows(); + if (CollectionUtils.isNotEmpty(outgoingFlows)) { + this.findNextUserTaskNode(outgoingFlows, execution); + } + return nextUserTask; + } + + /** + * 下一个任务节点信息, + *

+ * 如果下一个节点为用户任务则直接返回, + * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值, + * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务 + * + * @param outgoingFlows 曲线走向 + * @param execution 执行器,包含form表单参数信息 + * @return + */ + void findNextUserTaskNode(List outgoingFlows, ExecutionEntity execution) { + sw: + for (SequenceFlow outgoingFlow : outgoingFlows) { + if (ConditionUtil.hasTrueCondition(outgoingFlow, execution)) { + if (outgoingFlow.getTargetFlowElement() instanceof ExclusiveGateway) { + // 只有排他网关才继续 + ExclusiveGateway exclusiveGateway = (ExclusiveGateway) outgoingFlow.getTargetFlowElement(); + findNextUserTaskNode(exclusiveGateway.getOutgoingFlows(), execution); + } else if (outgoingFlow.getTargetFlowElement() instanceof UserTask) { + nextUserTask = (UserTask) outgoingFlow.getTargetFlowElement(); + // 找到第一个符合条件的userTask就跳出循环 + break sw; + } + } + } + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractGateWayRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractGateWayRollbackOperateStrategy.java new file mode 100644 index 0000000..c448b16 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractGateWayRollbackOperateStrategy.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.Gateway; +import org.flowable.bpmn.model.SequenceFlow; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl; +import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AbstractGateWayRollbackOperateStrategy + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractGateWayRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + public AbstractGateWayRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void existNextFinishedTask() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + List historicTaskInstanceList = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTaskInstancesByQueryCriteria((HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl() + .finished().processInstanceId(hisTask.getProcessInstanceId()).taskCompletedAfter(hisTask.getEndTime())); + + if (!historicTaskInstanceList + .stream() + .filter(obj -> paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) + .collect(Collectors.toList()) + .isEmpty()) { + String msg = "存在已完成下一节点任务"; + throw new FlowableException(msg); + } + } + + @Override + public void deleteRuntimeTasks() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + // 删除正在执行任务 + List taskList = CommandContextUtil.getTaskService(commandContext) + .createTaskQuery() + .processInstanceId(hisTask.getProcessInstanceId()) + .taskCreatedAfter(hisTask.getEndTime()) + .list(); + taskList.stream() + .filter(obj -> paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) + .forEach(obj -> { + log.info("删除运行时任务:" + obj); + removeRuntimeTaskOperate((TaskEntity) obj); + }); + + // 删除历史任务 + List historicTaskInstances = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTasksByProcessInstanceId(hisTask.getProcessInstanceId()); + historicTaskInstances.forEach(obj -> { + if (obj.getCreateTime().getTime() <= hisTask.getEndTime().getTime() && paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) { + log.info("删除历史任务:" + obj); + CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask(obj); + } + }); + } + + /** + * 使用并行网关进行 线条流汇总时候,会出现 特殊bug + * + * @param parent + */ + protected void processGateway(ExecutionEntity parent) { + // 当前正在运行所以任务 + List taskEntityList = CommandContextUtil.getTaskService(commandContext) + .findTasksByProcessInstanceId(parent.getProcessInstanceId()); + + boolean isExistPassGatewayTask = false; + + // 下一节点任务 + List nextTaskList = taskEntityList.stream() + .filter(obj -> paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) + .collect(Collectors.toList()); + + if (!nextTaskList.isEmpty()) { + log.info("已经生成过网关任务"); + isExistPassGatewayTask = true; + + // 网关的连线 + Map sqFlowMap = new HashMap<>(); + + paramsTemplate.getGatewayMap().values().forEach(obj -> { + obj.getIncomingFlows().forEach(item -> { + + if (null != paramsTemplate.getGatewayMap().get(item.getSourceRef())) { + log.info("跳过gateway 间连线:" + item); + return; + } + if (paramsTemplate.getHisTask().getTaskDefinitionKey().equals(item.getSourceRef())) { + log.info("跳过当前回退历史任务:" + item); + return; + } + sqFlowMap.put(item.getSourceRef(), item); + }); + }); + + // 创建网关相关连线 execution + createCompleteGatewayExecution(parent, sqFlowMap); + + // 删除当前正在执行任务 + Set nestTaskIdSet = new HashSet<>(); + nextTaskList.forEach(obj -> { + removeRuntimeTaskOperate(obj); + nestTaskIdSet.add(obj.getId()); + }); + + // 移除正在执行下一节点历史任务 + List historicTaskInstanceList = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTasksByProcessInstanceId(parent.getProcessInstanceId()); + historicTaskInstanceList.forEach(obj -> { + if (nestTaskIdSet.contains(obj.getId())) { + CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask(obj); + } + }); + } + + if (isExistPassGatewayTask) { + } else { + log.info("移除网关连线"); + + List executionEntityList = CommandContextUtil.getExecutionEntityManager(commandContext) + .findExecutionsByParentExecutionAndActivityIds(parent.getProcessInstanceId(), + paramsTemplate.getGatewayMap().keySet()); + + Map targetGatewayMap = paramsTemplate.getCurrentTaskElement() + .getOutgoingFlows().stream().filter(obj -> obj.getTargetFlowElement() instanceof Gateway) + .map(obj -> obj.getTargetFlowElement()) + .collect(Collectors.toMap(FlowElement::getId, obj -> obj)); + + List toRemoveList = new ArrayList<>(); + + executionEntityList.forEach(obj -> { + if (null != targetGatewayMap.get(obj.getActivityId())) { + toRemoveList.add(obj); + targetGatewayMap.put(obj.getActivityId(), null); + } + }); + + if (!toRemoveList.isEmpty()) { + toRemoveList.forEach(obj -> { + log.info("移除连线:" + obj); + CommandContextUtil.getExecutionEntityManager(commandContext).delete(obj); + }); + } + } + } + + /** + * 创建 Gateway 相关连线 + * + * @param parent + * @param sqFlowMap + */ + protected void createCompleteGatewayExecution(ExecutionEntity parent, Map sqFlowMap) { + sqFlowMap.values().forEach(obj -> { + ExecutionEntity newExecution = + CommandContextUtil.getExecutionEntityManager(commandContext).createChildExecution(parent); + + newExecution.setCurrentFlowElement(obj.getTargetFlowElement()); + newExecution.setActive(false); + + log.debug("创建 gateway 连线 execution"); + CommandContextUtil.getAgenda(commandContext).planContinueProcessInCompensation(newExecution); + }); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractRollbackOperateStrategy.java new file mode 100644 index 0000000..5b2b6b4 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/AbstractRollbackOperateStrategy.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import com.skyeye.activiti.mapper.HistoryActivityInstanceMapper; +import com.skyeye.common.util.SpringUtils; +import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.impl.ActivityInstanceQueryImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.runtime.ActivityInstance; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl; +import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AbstractRollbackOperateStrategy + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractRollbackOperateStrategy implements RollbackOperateStrategy { + + protected RollbackParamsTemplate paramsTemplate; + /** + * 任务处理人 + */ + protected String assignee; + + protected Map variables; + + protected CommandContext commandContext; + + /** + * 无法操作 + */ + protected HistoryActivityInstanceMapper historyActivityInstanceMapper; + + protected RuntimeService runtimeService; + + public AbstractRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + this.paramsTemplate = paramsTemplate; + this.historyActivityInstanceMapper = SpringUtils.getBean(HistoryActivityInstanceMapper.class); + this.runtimeService = SpringUtils.getBean(RuntimeService.class); + } + + @Override + public void process(CommandContext commandContext, String assignee) { + process(commandContext, assignee, new HashMap<>()); + } + + @Override + public void process(CommandContext commandContext, String assignee, Map variables) { + + this.commandContext = commandContext; + this.assignee = assignee; + this.variables = variables; + + log.info("处理 existNextFinishedTask"); + existNextFinishedTask(); + log.info("配置任务执行人 setAssignee"); + setAssignee(); + log.info("处理 createExecution"); + createExecution(); + log.info("处理 deleteRuntimeTasks"); + deleteRuntimeTasks(); + log.info("处理 deleteHisActInstance"); + deleteHisActInstance(); + } + + /** + * 获取 当前执行 execution + * + * @return + */ + protected ExecutionEntity getExecutionEntity() { + ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager(commandContext) + .findById(paramsTemplate.getHisTask().getExecutionId()); + + if (null == executionEntity) { + log.info("没找到回退任务的 execution,从同级任务处获取"); + List executionEntityList = CommandContextUtil + .getExecutionEntityManager(commandContext) + .findExecutionsByParentExecutionAndActivityIds(paramsTemplate.getHisTask().getProcessInstanceId(), paramsTemplate.getNextFlowIdList()); + if (executionEntityList.isEmpty()) { + throw new FlowableException("没有找到临近节点"); + } + executionEntity = executionEntityList.get(0); + } + + return executionEntity; + } + + protected void removeHisTask(HistoricTaskInstance hisTask) { + // 移除历史任务列表 + log.info("移除历史任务 [ id = " + hisTask.getId() + " ]"); + CommandContextUtil.getHistoricTaskService().deleteHistoricTask((HistoricTaskInstanceEntity) hisTask); + } + + /** + * 移除 ru_ 相关数据 + * + * @param obj + */ + protected void removeRuntimeTaskOperate(TaskEntity obj) { + log.debug("移除 IdentityLink: " + obj.getId()); + CommandContextUtil.getIdentityLinkService(commandContext).deleteIdentityLinksByTaskId(obj.getId()); + log.debug("移除 Variable: " + obj.getId()); + CommandContextUtil.getVariableService(commandContext).deleteVariablesByExecutionId(obj.getExecutionId()); + log.debug("移除 Task: " + obj.getId()); + CommandContextUtil.getTaskService(commandContext).deleteTasksByExecutionId(obj.getExecutionId()); + log.debug("移除 execution: " + obj.getExecutionId()); + CommandContextUtil.getExecutionEntityManager(commandContext).delete(obj.getExecutionId()); + } + + protected void createExecution(ExecutionEntity newExecution) { + newExecution.setActive(true); + // 测试设置变量 + newExecution.setVariablesLocal(variables); + newExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + + // 创建新任务 + log.debug("创建新任务"); + CommandContextUtil.getAgenda(commandContext).planContinueProcessInCompensation(newExecution); + } + + @Override + public void existNextFinishedTask() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + List hisTaskList = CommandContextUtil.getHistoricTaskService() + .findHistoricTaskInstancesByQueryCriteria((HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl() + .processInstanceId(hisTask.getProcessInstanceId()).taskCompletedAfter(hisTask.getEndTime())); + + if (!hisTaskList.isEmpty()) { + hisTaskList.forEach(obj -> { + if (paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) { + String msg = "存在已完成下一节点任务"; + throw new FlowableException(msg); + } + }); + } + } + + @Override + public void deleteHisActInstance() { + List activityInstanceEntityList = + CommandContextUtil.getActivityInstanceEntityManager(commandContext).findActivityInstancesByQueryCriteria( + new ActivityInstanceQueryImpl().processInstanceId(paramsTemplate.getHisTask().getProcessInstanceId())); + + List ids = new ArrayList<>(); + activityInstanceEntityList.forEach(obj -> { + // 时间大于 任务创建时间 之后线条 + if (obj.getStartTime().getTime() > paramsTemplate.getHisTask().getCreateTime().getTime() + && paramsTemplate.getNextFlowIdList().contains(obj.getActivityId())) { + ids.add(obj.getId()); + } + // 当前任务的连线 ID + if (paramsTemplate.getHisTask().getTaskDefinitionKey().equals(obj.getActivityId()) + && obj.getEndTime().getTime() > paramsTemplate.getHisTask().getCreateTime().getTime() + ) { + ids.add(obj.getId()); + } + }); + + // 移除当前任务连线 +// LOGGER.debug("移除当前任务连线"); +// ids.forEach(obj -> CommandContextUtil.getActivityInstanceEntityManager(commandContext).delete(obj)); + // 移除历史任务连线 + // 历史任务删除失败,改用自己写mapper 完成删除功能 +// ids.forEach(obj -> CommandContextUtil.getHistoricActivityInstanceEntityManager(commandContext).delete(obj)); + log.debug("移除历史任务连线"); + ids.forEach(obj -> historyActivityInstanceMapper.delete(obj)); + + } + + @Override + public void deleteRuntimeTasks() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + List taskEntityList = CommandContextUtil.getTaskService(commandContext).findTasksByProcessInstanceId(hisTask.getProcessInstanceId()); + taskEntityList.forEach(obj -> { + if (paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) { + log.info("移除正在执行的下一节点任务"); + // 移除任务 + removeRuntimeTaskOperate(obj); + } + }); + + // 移除历史任务信息 + List historicTaskInstanceList = + CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTasksByProcessInstanceId(hisTask.getProcessInstanceId()); + historicTaskInstanceList.forEach(obj -> { + if (paramsTemplate.getNextFlowIdList().contains(obj.getTaskDefinitionKey())) { + CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask(obj); + } + }); + } + + @Override + public void setAssignee() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + String key = RollbackConstants.ASSIGNEE_PREFIX_KEY + hisTask.getProcessInstanceId() + hisTask.getTaskDefinitionKey(); + variables.put(key, assignee); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/DefaultRollbackStrategyFactoryBean.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/DefaultRollbackStrategyFactoryBean.java new file mode 100644 index 0000000..5b7b1bc --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/DefaultRollbackStrategyFactoryBean.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import com.skyeye.activiti.cmd.rollback.impl.*; +import org.flowable.bpmn.model.*; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.TaskService; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @ClassName: DefaultRollbackStrategyFactoryBean + * @Description: 回滚策略 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class DefaultRollbackStrategyFactoryBean implements RollbackStrategyFactory { + + private Logger LOGGER = LoggerFactory.getLogger(DefaultRollbackStrategyFactoryBean.class); + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private TaskService taskService; + + @Override + public RollbackOperateStrategy createStrategy(HistoricTaskInstance hisTask) { + BpmnModel bpmnModel = repositoryService.getBpmnModel(hisTask.getProcessDefinitionId()); + + RollbackParamsTemplate template = new RollbackParamsTemplate(); + + template.setHisTask(hisTask); + // 获取当前任务的节点信息 + getThisUserTask(template, bpmnModel, hisTask); + // 获取下一节点信息 + getNextElementInfo(template, bpmnModel); + // 创建策略 + RollbackOperateStrategy strategy = createStrategyInstance(template); + + return strategy; + } + + /** + * @param template + * @return + */ + @Override + public boolean currentMultiInstanceTaskUnfinished(RollbackParamsTemplate template) { + if (template.getCurrentTaskElement().getLoopCharacteristics() == null) { + LOGGER.info("当前任务节点不是会签节点"); + return false; + } + + long count = taskService.createTaskQuery() + .processInstanceId(template.getHisTask().getProcessInstanceId()) + .taskDefinitionKey(template.getHisTask().getTaskDefinitionKey()) + .count(); + if (count > 0) { + LOGGER.info("具有未完成当前节点任务"); + return true; + } + + return false; + } + + /** + * 生成策略 + * + * @param template + * @return + */ + private RollbackOperateStrategy createStrategyInstance(RollbackParamsTemplate template) { + // 处理正在执行会签节点 + if (currentMultiInstanceTaskUnfinished(template)) { + LOGGER.info("-回退 正在执行会签 策略"); + return new ActiveMultiInstanceTaskRollbackOperateStrategy(template); + } + + // 默认节点处理策略 + if (template.getCurrentTaskElement().getLoopCharacteristics() == null + && template.getGatewayMap().isEmpty() + && !template.getNextUserTaskList().isEmpty()) { + LOGGER.info("-回退 普通任务 策略"); + return new NextDefaultUserTaskRollbackOperateStrategy(template); + } + + // 下一节点 嵌入式子流程 + if (template.getCurrentTaskElement().getLoopCharacteristics() == null + && template.getGatewayMap().isEmpty() + && !template.getSubProcessMap().isEmpty()) { + LOGGER.info("-回退 嵌入式子流程 策略"); + return new NextSubProcessRollbackOperateStrategy(template); + } + + // 下一节点 调用式子流程 + if (template.getCurrentTaskElement().getLoopCharacteristics() == null + && template.getGatewayMap().isEmpty() + && !template.getCallActivityMap().isEmpty()) { + LOGGER.info("-回退 调用式子流程 策略"); + return new NextCallActivityRollbackOperateStrategy(template); + } + + // 下一节点 网关,多级网关 + if (template.getCurrentTaskElement().getLoopCharacteristics() == null + && !template.getGatewayMap().isEmpty()) { + LOGGER.info("-回退 网关, 多级网关 策略"); + return new DefaultTaskNextGatewayRollbackOperateStrategy(template); + } + + // 会签已完成 + if (template.getCurrentTaskElement().getLoopCharacteristics() != null) { + if (template.getGatewayMap().isEmpty() && !template.getNextUserTaskList().isEmpty()) { + LOGGER.info("-回退 已完成会签,下一节点普通任务 策略"); + return new CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy(template); + } + return null; + } + return null; + } + + /** + * 获取下一节点任务 + * + * @param template + * @param bpmnModel + */ + private void getNextElementInfo(RollbackParamsTemplate template, BpmnModel bpmnModel) { + if (null != template.getCurrentSubProcess()) { + LOGGER.info("当前任务存在于 SubProcess"); + getNextElementInfo(template, template.getCurrentSubProcess(), template.getCurrentTaskElement().getOutgoingFlows()); + return; + } + LOGGER.info("当前任务存在于 bpmnModel"); + // 主线流程图 + getNextElementInfo(template, bpmnModel.getMainProcess(), template.getCurrentTaskElement().getOutgoingFlows()); + } + + /** + * 获取下一节点网关任务 + * + * @param template + * @param flowElementsContainer + * @param outgoingFlows + */ + private void getNextElementInfo(RollbackParamsTemplate template, FlowElementsContainer flowElementsContainer, List outgoingFlows) { + for (SequenceFlow flow : outgoingFlows) { + template.getNextFlowIdList().add(flow.getId()); + template.getOutGoingMap().put(flow.getId(), flow); + + // 下一节点 + FlowElement flowElement = flowElementsContainer.getFlowElement(flow.getTargetRef()); + template.getNextFlowIdList().add(flowElement.getId()); + + if (flowElement instanceof UserTask) { + LOGGER.info("下一节点:UserTask"); + template.getNextUserTaskList().add((UserTask) flowElement); + } else if (flowElement instanceof Gateway) { + LOGGER.info("下一节点:Gateway"); + Gateway gateway = ((Gateway) flowElement); + template.getGatewayMap().put(gateway.getId(), gateway); + getNextElementInfo(template, flowElementsContainer, gateway.getOutgoingFlows()); + } else if (flowElement instanceof SubProcess) { + LOGGER.info("下一节点:SubProcess"); + SubProcess subProcess = (SubProcess) flowElement; + template.getSubProcessMap().put(subProcess.getId(), subProcess); + } else if (flowElement instanceof CallActivity) { + LOGGER.info("下一节点:CallActivity"); + CallActivity callActivity = (CallActivity) flowElement; + template.getCallActivityMap().put(callActivity.getId(), callActivity); + } + } + } + + /** + * 获取当前任务 + * + * @param template + * @param bpmnModel + * @param hisTask + */ + private void getThisUserTask(RollbackParamsTemplate template, BpmnModel bpmnModel, HistoricTaskInstance hisTask) { + + FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(hisTask.getTaskDefinitionKey()); + if (null != flowElement && flowElement instanceof UserTask) { + LOGGER.info("获取回退任务节点"); + template.setCurrentTaskElement((UserTask) flowElement); + return; + } + + for (FlowElement item : bpmnModel.getMainProcess().getFlowElements()) { + if (item instanceof SubProcess) { + flowElement = ((SubProcess) item).getFlowElement(hisTask.getTaskDefinitionKey()); + if (null != flowElement) { + LOGGER.info("当前节点存在于嵌入式子流程"); + template.setCurrentTaskElement((UserTask) flowElement); + template.setCurrentSubProcess((SubProcess) item); + return; + } + } + } + + LOGGER.error("没有获取回退任务节点"); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackCmd.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackCmd.java new file mode 100644 index 0000000..5ffdb31 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackCmd.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import com.skyeye.common.util.SpringUtils; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @ClassName: RollbackCmd + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class RollbackCmd implements Command { + + private Logger LOGGER = LoggerFactory.getLogger(RollbackCmd.class); + + /** + * 任务ID + */ + private String taskId; + + private String assignee; + + private HistoryService historyService; + + private RuntimeService runtimeService; + + private RollbackStrategyFactory rollbackStrategyFactory; + + public RollbackCmd(String taskId, String assignee) { + this.taskId = taskId; + this.assignee = assignee; + + this.historyService = SpringUtils.getBean(HistoryService.class); + this.runtimeService = SpringUtils.getBean(RuntimeService.class); + this.rollbackStrategyFactory = SpringUtils.getBean(RollbackStrategyFactory.class); + } + + @Override + public Object execute(CommandContext commandContext) { + HistoricTaskInstance hisTask = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); + + if (null == hisTask.getEndTime()) { + String msg = "任务正在执行,不需要回退"; + LOGGER.error(msg); + throw new FlowableException(msg); + } + + ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(hisTask.getProcessInstanceId()).singleResult(); + if (null == pi) { + String msg = "该流程已经完成,无法进行任务回退。"; + LOGGER.error(msg); + throw new FlowableException(msg); + } + + RollbackOperateStrategy strategy = rollbackStrategyFactory.createStrategy(hisTask); + + // 处理 + strategy.process(commandContext, assignee); + + // 判断下一节点类型,根据下一节点类型获得任务处理策略 + return null; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackConstants.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackConstants.java new file mode 100644 index 0000000..fd5157d --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackConstants.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +/** + * @ClassName: RollbackConstants + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RollbackConstants { + + /** + * 配置 任务执行人变量 + */ + String ASSIGNEE_PREFIX_KEY = "ROLLBACK_ASSIGNEE_PREFIX_"; + + /** + * 配置 任务执行人变量 + */ + String TASK_TYPE_PREFIX_KEY = "ROLLBACK_TASK_TYPE_PREFIX_"; + + + /** + * 会签任务变量 + */ + interface MultiInstanceConstants { + + /** + * 正在执行的会签总数 + */ + String NR_OF_ACTIVE_INSTANCES = "nrOfActiveInstances"; + + /** + * 已完成的会签任务总数 + */ + String NR_OF_COMPLETE_INSTANCES = "nrOfCompletedInstances"; + + /** + * 会签任务总数 + */ + String NR_OF_INSTANCE = "nrOfInstances"; + + /** + * 会签任务表示 collectionElementIndexVariable + */ + String LOOP_COUNTER = "loopCounter"; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackOperateStrategy.java new file mode 100644 index 0000000..cdd9e23 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackOperateStrategy.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import org.flowable.common.engine.impl.interceptor.CommandContext; + +import java.util.Map; + +/** + * @ClassName: RollbackOperateStrategy + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RollbackOperateStrategy { + + /** + * 处理 + */ + void process(CommandContext commandContext, String assignee); + + /** + * 处理 + */ + void process(CommandContext commandContext, String assignee, Map variables); + + /** + * 配置任务处理人 + */ + void setAssignee(); + + /** + * 移除相关关联 + */ + void existNextFinishedTask(); + + /** + * 移除历史痕迹 + */ + void deleteHisActInstance(); + + /** + * 移除正在运行的任务 + */ + void deleteRuntimeTasks(); + + /** + * 创建任务 + */ + void createExecution(); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackParamsTemplate.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackParamsTemplate.java new file mode 100644 index 0000000..d1d0091 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackParamsTemplate.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import lombok.Data; +import org.flowable.bpmn.model.*; +import org.flowable.task.api.history.HistoricTaskInstance; + +import java.util.*; + +/** + * @ClassName: RollbackParamsTemplate + * @Author: huangrenhao + * @Description: + * @CreateTime: 2020/3/23 0023 下午 3:52 + * @Version: + **/ +@Data +public class RollbackParamsTemplate { + + /** + * 回滚任务 + */ + private HistoricTaskInstance hisTask; + + /** + * 当前任务节点 + */ + private UserTask currentTaskElement; + + /** + * 当前节点到下一任务节点间的连线(不包含当前任务节点) + */ + private Set nextFlowIdList = new HashSet<>(); + + /** + * 当前任务节点到 下一节点 之间线条 + */ + private Map outGoingMap = new HashMap<>(); + + /** + * 下一任务节点 集合 + */ + private List nextUserTaskList = new ArrayList<>(); + + /** + * 到下一任务节点 之间的网关集合 + */ + private Map gatewayMap = new HashMap<>(); + + /** + * 下一节点是否为 嵌入式子流程 + */ + private Map subProcessMap = new HashMap<>(); + + /** + * 下一节点是否为 调用子流程 + */ + private Map callActivityMap = new HashMap<>(); + + /** + * 当前 嵌入子流程 + */ + private SubProcess currentSubProcess; +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackStrategyFactory.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackStrategyFactory.java new file mode 100644 index 0000000..bb3ee21 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/RollbackStrategyFactory.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback; + +import org.flowable.task.api.history.HistoricTaskInstance; + +/** + * @ClassName: RollbackStrategyFactory + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 19:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface RollbackStrategyFactory { + + /** + * 创建回滚策略 + * + * @param hisTask + * @return + */ + RollbackOperateStrategy createStrategy(HistoricTaskInstance hisTask); + + /** + * 当前任务未完成判定 + * + * @param template + * @return + */ + boolean currentMultiInstanceTaskUnfinished(RollbackParamsTemplate template); +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/ActiveMultiInstanceTaskRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/ActiveMultiInstanceTaskRollbackOperateStrategy.java new file mode 100644 index 0000000..5f1e8bd --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/ActiveMultiInstanceTaskRollbackOperateStrategy.java @@ -0,0 +1,286 @@ +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import com.skyeye.common.constans.ActivitiConstants; +import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl; +import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.flowable.variable.api.history.HistoricVariableInstance; +import org.flowable.variable.service.impl.HistoricVariableInstanceQueryImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ActiveMultiInstanceTaskRollbackOperateStrategy + * @Description: 正在执行会签回滚 ,兼容嵌入式子流程 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class ActiveMultiInstanceTaskRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + private static Logger LOGGER = LoggerFactory.getLogger(NextDefaultUserTaskRollbackOperateStrategy.class); + + public ActiveMultiInstanceTaskRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + boolean isSequential = false; + + @Override + public void process(CommandContext commandContext, String assignee, Map variables) { + this.commandContext = commandContext; + this.assignee = assignee; + this.variables = variables; + + // 串行会签 + if (paramsTemplate.getCurrentTaskElement().getBehavior() instanceof SequentialMultiInstanceBehavior) { + isSequential = true; + } else if (paramsTemplate.getCurrentTaskElement().getBehavior() instanceof MultiInstanceActivityBehavior) { + isSequential = false; + } + + LOGGER.info("创建实例"); + createExecution(); + } + + @Override + public void createExecution() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + List currentTaskList = CommandContextUtil.getTaskService(commandContext) + .createTaskQuery() + .processInstanceId(hisTask.getProcessInstanceId()) + .taskDefinitionKey(hisTask.getTaskDefinitionKey()) + .list(); + + if (currentTaskList.isEmpty()) { + String msg = "当前会签任务已经完成"; + throw new FlowableException(msg); + } + + if (!isSequential) { + LOGGER.info("处理并行会签"); + processMultiInstance(); + } else { + LOGGER.info("处理串行会签"); + processSequentialInstance(); + } + } + + /** + * 处理串行会签 + * 串行特殊场景 : 下一个顺序执行人已完成任务,当前历史任务不可回退 + * a -> b -> c -> d + * b 任务完成时, a 任务不可回退 + */ + private void processSequentialInstance() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + // 确认是否具有下一线性完成任务 + existNextFinishedTask(hisTask); + + // 进行任务回退操作 + ExecutionEntity executionEntity = processCommon(hisTask); + + if (executionEntity.getId().equals(hisTask.getExecutionId())) { + log.info("未生成过下一节点"); + + // 移除正在执行任务 + List taskEntityList = CommandContextUtil.getTaskService(commandContext).findTasksByExecutionId(executionEntity.getId()); + taskEntityList.forEach(obj -> { + LOGGER.info("移除正在当前任务记录 [ id = " + obj.getId() + " ] "); + CommandContextUtil.getTaskService(commandContext).deleteTask(obj, true); + HistoricTaskInstance historicTaskInstance = CommandContextUtil.getHistoricTaskService(commandContext).getHistoricTask(obj.getId()); + CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask((HistoricTaskInstanceEntity) historicTaskInstance); + }); + + // 配置任务执行人 + executionEntity.setVariable(ActivitiConstants.ASSIGNEE_USER, assignee); + // 计数器前置一位 + int loopCounter = (int) executionEntity.getVariable(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER); + executionEntity.setVariable(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, loopCounter - 1); + // 将任务重新激活 + executionEntity.setActive(true); + // 创建新任务 + CommandContextUtil.getAgenda(commandContext).planContinueProcessInCompensation(executionEntity); + } else { + log.info("已生成过下一任务节点,无法找到当前 execution"); + + List taskList = CommandContextUtil.getTaskService(commandContext).createTaskQuery() + .processInstanceId(hisTask.getProcessInstanceId()) + .taskDefinitionKey(hisTask.getTaskDefinitionKey()) + .list(); + + Task currentTask = taskList.get(0); + + Integer currentLoopCounter = (Integer) runtimeService.getVariableLocal(currentTask.getExecutionId(), RollbackConstants.MultiInstanceConstants.LOOP_COUNTER); + List assigneeList = (List) runtimeService.getVariableLocal(currentTask.getProcessInstanceId(), ActivitiConstants.ASSIGNEE_USER_LIST); + + if (StringUtils.isEmpty(hisTask.getAssignee())) { + throw new FlowableException("没有找到历史任务执行人,无法进行 执行顺序判断"); + } + + int index = assigneeList.indexOf(hisTask.getAssignee()); + if (index == -1) { + throw new FlowableException("执行人不存在于初始参数,无法进行 执行顺序判断"); + } + + if (index != currentLoopCounter - 1) { + throw new FlowableException("任务执行人不是 当前执行人的前位 , 不合法回退"); + } + // 持久化变量 + assigneeList.set(index, assignee); + runtimeService.setVariableLocal(currentTask.getProcessInstanceId(), ActivitiConstants.ASSIGNEE_USER_LIST, assigneeList); + + // 修改变量 + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(currentTask.getExecutionId()); + newExecution.setVariableLocal(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, currentLoopCounter - 1); + newExecution.setVariableLocal(ActivitiConstants.ASSIGNEE_USER, assignee); + + // 创建新任务 + CommandContextUtil.getAgenda(commandContext).planContinueMultiInstanceOperation(newExecution, executionEntity, currentLoopCounter - 1); + // 移除当前任务 + CommandContextUtil.getTaskService(commandContext).deleteTask((TaskEntity) currentTask, true); + // 移除历史任务 + HistoricTaskInstance historicTaskInstance = CommandContextUtil.getHistoricTaskService(commandContext).getHistoricTask(currentTask.getId()); + CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask((HistoricTaskInstanceEntity) historicTaskInstance); + } + // 移除当前历史任务 + removeHisTask(hisTask); + } + + public void existNextFinishedTask(HistoricTaskInstance hisTask) { + List list = CommandContextUtil.getHistoricTaskService().findHistoricTaskInstancesByQueryCriteria( + (HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl() + .processInstanceId(hisTask.getProcessInstanceId()) + .taskDefinitionKey(hisTask.getTaskDefinitionKey()) + .finished() + .taskCompletedAfter(hisTask.getEndTime()) + ); + + if (!list.isEmpty()) { + String msg = "串行会签回滚,已经具有下一线性完成任务,无法进行任务回退"; + LOGGER.error(msg); + throw new FlowableException(msg); + } + + } + + /** + * 处理并行会签 + */ + private void processMultiInstance() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + // 通用操作部分 + ExecutionEntity executionEntity = processCommon(hisTask); + + // 未生成过下一节点 + if (executionEntity.getId().equals(hisTask.getExecutionId())) { + log.info("未生成过下一节点"); + // 配置任务执行人 + executionEntity.setVariable(ActivitiConstants.ASSIGNEE_USER, assignee); + // 将任务重新激活 + executionEntity.setActive(true); + // 创建新任务 + CommandContextUtil.getAgenda(commandContext).planContinueProcessInCompensation(executionEntity); + } else { + log.info("已生成过下一任务节点,无法找到当前 execution"); + + List historicVariableInstanceList = CommandContextUtil.getHistoricVariableService().findHistoricVariableInstancesByQueryCriteria( + new HistoricVariableInstanceQueryImpl() + .processInstanceId(hisTask.getProcessInstanceId()) + .executionId(hisTask.getExecutionId()) + ); + + Map hisVarMap = historicVariableInstanceList.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, item -> item.getValue())); + + // 流程执行变量 + Integer loopCounter = (Integer) hisVarMap.get(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER); + + List executionEntities = CommandContextUtil.getExecutionEntityManager(commandContext) + .findChildExecutionsByParentExecutionId(executionEntity.getId()); + + List linkExecutions = executionEntities.stream() + .filter(obj -> { + if (!obj.isActive()) { + Integer currentLoopCounter = (Integer) obj.getVariable(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER); + if (currentLoopCounter.equals(loopCounter)) { + return true; + } + } + return false; + }).collect(Collectors.toList()); + + if (linkExecutions.isEmpty()) { + throw new FlowableException("没有找到映射节点"); + } + + ExecutionEntity newExecution = linkExecutions.get(0); + + newExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + newExecution.setActive(true); + newExecution.setVariables(hisVarMap); + newExecution.setVariable(ActivitiConstants.ASSIGNEE_USER, assignee); + + // 创建新任务 + CommandContextUtil.getAgenda(commandContext).planContinueMultiInstanceOperation(newExecution, executionEntity, loopCounter); + } + + // 移除当前历史任务 + removeHisTask(hisTask); + } + + /** + * 通用处理逻辑 + * + * @param hisTask + * @return + */ + private ExecutionEntity processCommon(HistoricTaskInstance hisTask) { + ExecutionEntity executionEntity = CommandContextUtil + .getExecutionEntityManager(commandContext).findById(hisTask.getExecutionId()); + + if (null == executionEntity) { + LOGGER.error("没有找到历史任务[ executionId = " + hisTask.getExecutionId() + " ]"); + List taskEntityList = CommandContextUtil.getTaskService(commandContext) + .createTaskQuery() + .processInstanceId(hisTask.getProcessInstanceId()) + .taskDefinitionKey(hisTask.getTaskDefinitionKey()) + .list(); + executionEntity = CommandContextUtil.getExecutionEntityManager(commandContext).findById(taskEntityList.get(0).getExecutionId()); + } + + ExecutionEntity parentExecutionEntity = + CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionEntity.getParentId()); + + /** + * 将计数器 进行 前移 + */ + int nrOfActiveInstances = (int) parentExecutionEntity.getVariable(RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES); + int nrOfCompletedInstances = (int) parentExecutionEntity.getVariable(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES); + + runtimeService.setVariable(parentExecutionEntity.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, nrOfActiveInstances + 1); + runtimeService.setVariable(parentExecutionEntity.getId(), RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, nrOfCompletedInstances - 1); + + return parentExecutionEntity; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy.java new file mode 100644 index 0000000..bf74f4b --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import com.skyeye.common.constans.ActivitiConstants; +import lombok.extern.slf4j.Slf4j; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.variable.api.history.HistoricVariableInstance; +import org.flowable.variable.service.impl.HistoricVariableInstanceQueryImpl; +import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy + * @Description: 已完成会签 , 下一节点是普通节点 进行回退 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 19:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + + private boolean isSequence = false; + + public CompletedMultiInstanceTaskAndNextDefaultTaskRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void createExecution() { + if (paramsTemplate.getCurrentTaskElement().getBehavior() instanceof SequentialMultiInstanceBehavior) { + isSequence = true; + } + + // 获取 execution + ExecutionEntity executionEntity = getExecutionEntity(); + + VariableInstanceEntity obj = CommandContextUtil.getVariableService(commandContext) + .findVariableInstanceByExecutionAndName(executionEntity.getProcessInstanceId(), ActivitiConstants.ASSIGNEE_USER_LIST); + + if (obj == null || !(obj.getValue() instanceof Collection)) { + throw new FlowableException("没有可用会签参数:" + ActivitiConstants.ASSIGNEE_USER_LIST); + } + // 会签执行人变量 + Collection assignees = (Collection) obj.getValue(); + + List historicVariableInstances = + CommandContextUtil.getHistoricVariableService().findHistoricVariableInstancesByQueryCriteria( + new HistoricVariableInstanceQueryImpl().executionId(paramsTemplate.getHisTask().getExecutionId())); + + if (historicVariableInstances.isEmpty()) { + throw new FlowableException("没有可用会签任务参数"); + } + + // 历史变量 + Map hisVarMap = historicVariableInstances.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, item -> item.getValue())); + + if (hisVarMap.containsKey(ActivitiConstants.ASSIGNEE_USER) && hisVarMap.containsKey(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER)) { + log.info("变量有效"); + } else { + throw new FlowableException("缺少会签任务变量"); + } + + /** + * 串行 最终的 loopCounter assignee 都会是最后一个人 + */ + if (isSequence) { + List assigneeList = (List) runtimeService.getVariableLocal(paramsTemplate.getHisTask().getProcessInstanceId(), ActivitiConstants.ASSIGNEE_USER_LIST); + if (!assigneeList.get(assigneeList.size() - 1).equals(paramsTemplate.getHisTask().getAssignee())) { + String msg = "不是串行最后一个节点,无法进行回退 "; + throw new FlowableException(msg); + } + // 替换任务执行变量 + assigneeList.set(assigneeList.size() - 1, assignee); + runtimeService.setVariableLocal(paramsTemplate.getHisTask().getProcessInstanceId(), ActivitiConstants.ASSIGNEE_USER_LIST, assigneeList); + } + + // 流程执行变量 + Integer loopCounter = (Integer) hisVarMap.get(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER); + + // 会签主任务 + ExecutionEntity parentExecution = CommandContextUtil.getExecutionEntityManager(commandContext) + .createChildExecution(executionEntity.getParent()); + + parentExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + parentExecution.setActive(false); + // 配置 会签 root execution + parentExecution.setMultiInstanceRoot(true); + + // 配置主 execution 变量 + Map parentVarMap = new HashMap<>(); + parentVarMap.put(RollbackConstants.MultiInstanceConstants.NR_OF_ACTIVE_INSTANCES, 1); + parentVarMap.put(RollbackConstants.MultiInstanceConstants.NR_OF_COMPLETE_INSTANCES, assignees.size() - 1); + parentVarMap.put(RollbackConstants.MultiInstanceConstants.NR_OF_INSTANCE, assignees.size()); + parentExecution.setVariablesLocal(parentVarMap); + + if (isSequence) { + log.info("创建 串行 会签任务"); + createSequenceMultiInstance(parentExecution, assignees); + } else { + log.info("创建 并行 会签任务"); + createParallelMultiInstance(parentExecution, assignees, loopCounter); + } + + removeHisTask(paramsTemplate.getHisTask()); + } + + private void createSequenceMultiInstance(ExecutionEntity parentExecution, Collection assignees) { + + ExecutionEntity newExecution = + CommandContextUtil.getExecutionEntityManager(commandContext).createChildExecution(parentExecution); + + Map varMap = new HashMap<>(); + varMap.put(ActivitiConstants.ASSIGNEE_USER, assignee); + varMap.put(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, assignees.size() - 1); + newExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + + newExecution.setVariablesLocal(varMap); + newExecution.setActive(true); + CommandContextUtil.getAgenda(commandContext).planContinueMultiInstanceOperation(newExecution, parentExecution, assignees.size() - 1); + + } + + /** + * 创建并行会签任务 + * + * @param parentExecution + * @param loopCounter + */ + private void createParallelMultiInstance(ExecutionEntity parentExecution, Collection assignees, Integer loopCounter) { + + for (int i = 0; i < assignees.size(); i++) { + if (i != loopCounter) { + Map varMap = new HashMap<>(); + varMap.put(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, i); + varMap.put(ActivitiConstants.ASSIGNEE_USER, "已完成任务"); + + // 创建 新执行任务 + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext) + .createChildExecution(parentExecution); + newExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + newExecution.setActive(false); + + newExecution.setVariablesLocal(varMap); + } else { + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext) + .createChildExecution(parentExecution); + newExecution.setCurrentFlowElement(paramsTemplate.getCurrentTaskElement()); + + Map varMap = new HashMap<>(); + varMap.put(ActivitiConstants.ASSIGNEE_USER, assignee); + varMap.put(RollbackConstants.MultiInstanceConstants.LOOP_COUNTER, i); + + newExecution.setVariablesLocal(varMap); + newExecution.setActive(true); + + CommandContextUtil.getAgenda(commandContext).planContinueMultiInstanceOperation(newExecution, parentExecution, loopCounter); + } + } + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/DefaultTaskNextGatewayRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/DefaultTaskNextGatewayRollbackOperateStrategy.java new file mode 100644 index 0000000..b175903 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/DefaultTaskNextGatewayRollbackOperateStrategy.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractGateWayRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.history.HistoricTaskInstance; + +/** + * @ClassName: DefaultTaskNextGatewayRollbackOperateStrategy + * @Description: 处理多级网关 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/26 19:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class DefaultTaskNextGatewayRollbackOperateStrategy extends AbstractGateWayRollbackOperateStrategy { + + public DefaultTaskNextGatewayRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void createExecution() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + // 获取正在执行 execution + ExecutionEntity executionEntity = getExecutionEntity(); + + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext) + .createChildExecution(executionEntity.getParent()); + // 创建新任务 + createExecution(newExecution); + // 特殊处理并行网关 + processGateway(executionEntity.getParent()); + + // 移除历史任务 + removeHisTask(hisTask); + + } + + @Override + public void setAssignee() { + // 进行任务执行人配置,之后使用全局监听出发更新 + super.setAssignee(); + String type = RollbackConstants.TASK_TYPE_PREFIX_KEY + paramsTemplate.getHisTask().getProcessInstanceId() + + paramsTemplate.getHisTask().getTaskDefinitionKey(); + variables.put(type, DefaultTaskNextGatewayRollbackOperateStrategy.class.getSimpleName()); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextCallActivityRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextCallActivityRollbackOperateStrategy.java new file mode 100644 index 0000000..f33dbd7 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextCallActivityRollbackOperateStrategy.java @@ -0,0 +1,143 @@ +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.CallActivity; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl; +import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: NextCallActivityRollbackOperateStrategy + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class NextCallActivityRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + /** + * 下一节点 callActivity + */ + private CallActivity callActivity; + + private List callActivityExecutionList; + + private ExecutionEntity callActivityProcess; + + public NextCallActivityRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void existNextFinishedTask() { + + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + Map callActivityMap = paramsTemplate.getCallActivityMap(); + String key = callActivityMap.keySet().iterator().next(); + this.callActivity = callActivityMap.get(key); + + // 下一节点callActivity的 flowId + callActivityExecutionList = CommandContextUtil.getExecutionEntityManager(commandContext) + .findExecutionsByParentExecutionAndActivityIds(hisTask.getProcessInstanceId(), Collections.singletonList(callActivity.getId())); + + // callActivity 在 父级流程的 executionId = 子流程的 processInstanceId + ExecutionEntity executionEntity = callActivityExecutionList.get(0); + + // 子流程 + callActivityProcess = CommandContextUtil.getExecutionEntityManager(commandContext) + .findSubProcessInstanceBySuperExecutionId(executionEntity.getId()); + + List hisTaskList = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTaskInstancesByQueryCriteria( + (HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl() + .finished() + .processInstanceId(callActivityProcess.getId()) + ); + + if (!hisTaskList.isEmpty()) { + throw new FlowableException("子流程已经具有完成的任务,流程无法回退"); + } + } + + @Override + public void setAssignee() { + // 进行任务执行人配置,之后使用全局监听出发更新 + super.setAssignee(); + String type = RollbackConstants.TASK_TYPE_PREFIX_KEY + paramsTemplate.getHisTask().getProcessInstanceId() + paramsTemplate.getHisTask().getTaskDefinitionKey(); + variables.put(type, NextCallActivityRollbackOperateStrategy.class.getSimpleName()); + } + + @Override + public void createExecution() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager(commandContext) + .findById(hisTask.getExecutionId()); + + if (null == executionEntity) { + log.info("没有找到execution"); + executionEntity = callActivityExecutionList.get(0); + } + + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext) + .createChildExecution(executionEntity.getParent()); + + // 创建新任务 + createExecution(newExecution); + // 移除历史任务 + removeHisTask(hisTask); + } + + @Override + public void deleteRuntimeTasks() { + + ExecutionEntity parentExecution = callActivityExecutionList.get(0); + // 清理子流程 + cleanCallActivityProcessInstance(callActivityProcess); + // 清理主流程记录 + CommandContextUtil.getExecutionEntityManager(commandContext) + .delete(parentExecution); + + } + + /** + * // 无效操作 + * CommandContextUtil.getExecutionEntityManager(commandContext) + * .deleteProcessInstance(callActivityProcess.getId(), "进行流程撤回", false); + * 清理 调用子流程 相关数据 + * + * @param processInstance + */ + private void cleanCallActivityProcessInstance(ExecutionEntity processInstance) { + // 移除正在运行任务信息 + List list = CommandContextUtil.getTaskService(commandContext) + .createTaskQuery() + .processInstanceId(processInstance.getId()) + .list(); + list.forEach(obj -> removeRuntimeTaskOperate((TaskEntity) obj)); + + // 移除历史任务信息 + List historicTaskInstanceList = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTasksByProcessInstanceId(processInstance.getId()); + historicTaskInstanceList.forEach(obj -> CommandContextUtil.getHistoricTaskService(commandContext).deleteHistoricTask(obj)); + + // 移除 子流程实例 + CommandContextUtil.getIdentityLinkService(commandContext).deleteIdentityLinksByProcessInstanceId(processInstance.getId()); + CommandContextUtil.getVariableService(commandContext).deleteVariablesByExecutionId(processInstance.getId()); + CommandContextUtil.getExecutionEntityManager(commandContext).delete(processInstance.getId()); + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextDefaultUserTaskRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextDefaultUserTaskRollbackOperateStrategy.java new file mode 100644 index 0000000..d6296bc --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextDefaultUserTaskRollbackOperateStrategy.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.task.api.history.HistoricTaskInstance; + +/** + * @ClassName: NextDefaultUserTaskRollbackOperateStrategy + * @Description: 普通节点 ,兼容嵌入式子流程 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class NextDefaultUserTaskRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + public NextDefaultUserTaskRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void createExecution() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + // 获取正在执行 execution + ExecutionEntity executionEntity = getExecutionEntity(); + + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext).createChildExecution(executionEntity.getParent()); + // 创建新任务 + createExecution(newExecution); + // 移除历史任务 + removeHisTask(hisTask); + } + + @Override + public void setAssignee() { + // 进行任务执行人配置,之后使用全局监听出发更新 + super.setAssignee(); + String type = RollbackConstants.TASK_TYPE_PREFIX_KEY + paramsTemplate.getHisTask().getProcessInstanceId() + + paramsTemplate.getHisTask().getTaskDefinitionKey(); + variables.put(type, NextDefaultUserTaskRollbackOperateStrategy.class.getSimpleName()); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextSubProcessRollbackOperateStrategy.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextSubProcessRollbackOperateStrategy.java new file mode 100644 index 0000000..a8aa8d4 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/impl/NextSubProcessRollbackOperateStrategy.java @@ -0,0 +1,171 @@ +package com.skyeye.activiti.cmd.rollback.impl; + +import com.skyeye.activiti.cmd.rollback.AbstractRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.RollbackParamsTemplate; +import org.flowable.bpmn.model.SubProcess; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.engine.impl.ActivityInstanceQueryImpl; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.runtime.ActivityInstance; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * @ClassName: NextSubProcessRollbackOperateStrategy + * @Description: 下一节点是 嵌入式子流程 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class NextSubProcessRollbackOperateStrategy extends AbstractRollbackOperateStrategy { + + private Logger LOGGER = LoggerFactory.getLogger(NextSubProcessRollbackOperateStrategy.class); + + /** + * 嵌入子流程中所有节点ID集合 + */ + private Set subProcessItemKeySet = new HashSet<>(); + + private SubProcess subProcess; + + public NextSubProcessRollbackOperateStrategy(RollbackParamsTemplate paramsTemplate) { + super(paramsTemplate); + } + + @Override + public void existNextFinishedTask() { + Map subProcessMap = paramsTemplate.getSubProcessMap(); + List historicTaskInstances = CommandContextUtil.getHistoricTaskService(commandContext) + .findHistoricTaskInstancesByQueryCriteria( + (HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl() + .taskCompletedAfter(paramsTemplate.getHisTask().getEndTime()) + .finished() + ); + + String key = subProcessMap.keySet().iterator().next(); + this.subProcess = subProcessMap.get(key); + + subProcess.getFlowElements().forEach(obj -> subProcessItemKeySet.add(obj.getId())); + if (!historicTaskInstances.isEmpty()) { + historicTaskInstances.forEach(obj -> { + if (subProcessItemKeySet.contains(obj.getTaskDefinitionKey())) { + LOGGER.error("出现已完成任务,无法进行流程节点撤回: [" + obj + "]"); + throw new FlowableException("出现已完成任务,无法进行流程节点撤回"); + } + }); + } + + } + + @Override + public void setAssignee() { + // 进行任务执行人配置,之后使用全局监听出发更新 + super.setAssignee(); + String type = RollbackConstants.TASK_TYPE_PREFIX_KEY + paramsTemplate.getHisTask().getProcessInstanceId() + paramsTemplate.getHisTask().getTaskDefinitionKey(); + variables.put(type, NextSubProcessRollbackOperateStrategy.class.getSimpleName()); + } + + + @Override + public void createExecution() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager(commandContext).findById(hisTask.getExecutionId()); + + /** + * subProcess 作为下一节点的时候,hisTask的execution会被关闭调。所以需要重新创建 + */ + if (null == executionEntity) { + LOGGER.info("hisTask:execution 为 null"); + + List executionEntityList = CommandContextUtil + .getExecutionEntityManager(commandContext) + .findExecutionsByParentExecutionAndActivityIds(hisTask.getProcessInstanceId(), paramsTemplate.getNextFlowIdList()); + if (executionEntityList.isEmpty()) { + throw new FlowableException("没有找到临近节点"); + } + executionEntity = executionEntityList.get(0); + } + // 创建主线 + ExecutionEntity newExecution = CommandContextUtil.getExecutionEntityManager(commandContext).createChildExecution(executionEntity.getParent()); + + // 创建新任务 + createExecution(newExecution); + // 移除历史任务 + removeHisTask(hisTask); + } + + @Override + public void deleteHisActInstance() { + List activityInstanceEntityList = CommandContextUtil.getActivityInstanceEntityManager(commandContext) + .findActivityInstancesByQueryCriteria( + new ActivityInstanceQueryImpl() + .processInstanceId(paramsTemplate.getHisTask().getProcessInstanceId()) + ); + + + List ids = new ArrayList<>(); + activityInstanceEntityList.forEach(obj -> { + // 时间大于 任务创建时间 之后线条 + if (obj.getStartTime().getTime() > paramsTemplate.getHisTask().getCreateTime().getTime() + && subProcessItemKeySet.contains(obj.getActivityId())) { + ids.add(obj.getId()); + } + // 当前任务的连线 ID + if (paramsTemplate.getHisTask().getTaskDefinitionKey().equals(obj.getActivityId()) + && obj.getEndTime().getTime() > paramsTemplate.getHisTask().getCreateTime().getTime() + ) { + ids.add(obj.getId()); + } + }); + + LOGGER.debug("移除历史任务连线"); + ids.forEach(obj -> historyActivityInstanceMapper.delete(obj)); + } + + @Override + public void deleteRuntimeTasks() { + HistoricTaskInstance hisTask = paramsTemplate.getHisTask(); + + List taskEntityList = CommandContextUtil.getTaskService(commandContext).findTasksByProcessInstanceId(hisTask.getProcessInstanceId()); + + taskEntityList.forEach(obj -> { + if (subProcessItemKeySet.contains(obj.getTaskDefinitionKey())) { + LOGGER.info("移除正在执行的下一节点任务"); + // 移除任务 + removeRuntimeTaskOperate(obj); + } + }); + + // 获取 subProcess 的 ExecutionEntity + Collection executionEntities = CommandContextUtil + .getExecutionEntityManager(commandContext) + .findExecutionsByParentExecutionAndActivityIds(hisTask.getProcessInstanceId(), Collections.singletonList(subProcess.getId())); + + executionEntities.forEach(obj -> { + LOGGER.info("移除 subProcess 层级execution"); + List children = CommandContextUtil + .getExecutionEntityManager(commandContext) + .findChildExecutionsByParentExecutionId(obj.getId()); + + // 移除级联子节点 + children.forEach(item -> CommandContextUtil + .getExecutionEntityManager(commandContext) + .delete(item)); + + // 移除 subProcess 顶级 + CommandContextUtil + .getExecutionEntityManager(commandContext) + .delete(obj); + }); + + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/listeners/RollbackEventListener.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/listeners/RollbackEventListener.java new file mode 100644 index 0000000..13b4363 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/cmd/rollback/listeners/RollbackEventListener.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.cmd.rollback.listeners; + +import com.skyeye.activiti.cmd.rollback.RollbackConstants; +import com.skyeye.activiti.cmd.rollback.impl.DefaultTaskNextGatewayRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.impl.NextCallActivityRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.impl.NextDefaultUserTaskRollbackOperateStrategy; +import com.skyeye.activiti.cmd.rollback.impl.NextSubProcessRollbackOperateStrategy; +import com.skyeye.common.util.SpringUtils; +import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; +import org.flowable.common.engine.api.delegate.event.FlowableEvent; +import org.flowable.common.engine.api.delegate.event.FlowableEventListener; +import org.flowable.common.engine.impl.event.FlowableEntityEventImpl; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * @ClassName: RollbackEventListener + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class RollbackEventListener implements FlowableEventListener { + + private static Logger LOGGER = LoggerFactory.getLogger(RollbackEventListener.class); + + @Override + public void onEvent(FlowableEvent event) { + if (FlowableEngineEventType.TASK_CREATED.name().equals(event.getType().name())) { + TaskEntity taskEntity = (TaskEntity) ((FlowableEntityEventImpl) event).getEntity(); + + RuntimeService runtimeService = SpringUtils.getBean(RuntimeService.class); + TaskService taskService = SpringUtils.getBean(TaskService.class); + + String key = RollbackConstants.ASSIGNEE_PREFIX_KEY + taskEntity.getProcessInstanceId() + + taskEntity.getTaskDefinitionKey(); + String type = RollbackConstants.TASK_TYPE_PREFIX_KEY + taskEntity.getProcessInstanceId() + + taskEntity.getTaskDefinitionKey(); + + Object assigneeValue = runtimeService.getVariable(taskEntity.getExecutionId(), key); + Object assigneeType = runtimeService.getVariable(taskEntity.getExecutionId(), type); + if (assigneeValue != null && assigneeType != null) { + LOGGER.info("回滚任务处理"); + if (NextDefaultUserTaskRollbackOperateStrategy.class.getSimpleName().equals(assigneeType) + || NextSubProcessRollbackOperateStrategy.class.getSimpleName().equals(assigneeType) + || NextCallActivityRollbackOperateStrategy.class.getSimpleName().equals(assigneeType) + || DefaultTaskNextGatewayRollbackOperateStrategy.class.getSimpleName().equals(assigneeType)) { + LOGGER.info("设置普通任务执行人"); + taskService.setAssignee(taskEntity.getId(), (String) assigneeValue); + } + } + } + } + + @Override + public boolean isFailOnException() { + return false; + } + + @Override + public boolean isFireOnTransactionLifecycleEvent() { + return false; + } + + @Override + public String getOnTransaction() { + return null; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiModelController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiModelController.java new file mode 100644 index 0000000..518cb94 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiModelController.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.controller; + +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActivitiModelController + * @Description: 工作流模型操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 21:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +public class ActivitiModelController { + + @Autowired + private ActivitiModelService activitiModelService; + + /** + * 发布模型为流程定义 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiModelController/editActivitiModelToDeploy") + public void editActivitiModelToDeploy(InputObject inputObject, OutputObject outputObject) { + activitiModelService.editActivitiModelToDeploy(inputObject, outputObject); + } + + /** + * 取消发布 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiModelController/deleteReleasedActivitiModelById") + public void deleteReleasedActivitiModelById(InputObject inputObject, OutputObject outputObject) { + activitiModelService.deleteReleasedActivitiModelById(inputObject, outputObject); + } + + /** + * 导出model的xml文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiModelController/editApprovalActivitiTaskListByUserId") + public void editApprovalActivitiTaskListByUserId(InputObject inputObject, OutputObject outputObject) { + activitiModelService.editApprovalActivitiTaskListByUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiProcessController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiProcessController.java new file mode 100644 index 0000000..b7103c9 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiProcessController.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.controller; + +import com.skyeye.activiti.service.ActivitiProcessService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.flowable.entity.FlowableSubData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActivitiProcessController + * @Description: 工作流流程相关操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 21:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工作流流程相关操作", tags = "工作流流程相关操作", modelName = "工作流模块") +public class ActivitiProcessController { + + @Autowired + private ActivitiProcessService activitiProcessService; + + /** + * 流程挂起 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiProcessController/updateProcessToHangUp") + public void updateProcessToHangUp(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.updateProcessToHangUp(inputObject, outputObject); + } + + /** + * 流程激活 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiProcessController/updateProcessToActivation") + public void updateProcessToActivation(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.updateProcessToActivation(inputObject, outputObject); + } + + /** + * 流程撤回 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiProcessController/editProcessInstanceWithDraw") + public void editProcessInstanceWithDraw(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.editProcessInstanceWithDraw(inputObject, outputObject); + } + + /** + * 刷新流程图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiProcessController/editProcessInstancePicToRefresh") + public void editProcessInstancePicToRefresh(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.editProcessInstancePicToRefresh(inputObject, outputObject); + } + + /** + * 获取流程下一个节点的审批人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiProcessController/nextPrcessApprover") + public void nextPrcessApprover(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.nextPrcessApprover(inputObject, outputObject); + } + + /** + * 启动流程时获取流程下一个用户节点的审批人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiProcess002", value = "启动流程时获取流程下一个用户节点的审批人", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "actKey", name = "actKey", value = "工作流模型的key", required = "required"), + @ApiImplicitParam(id = "businessData", name = "businessData", value = "业务数据,根据不同的业务数据走不同的工作流")}) + @RequestMapping("/post/ActivitiProcessController/nextPrcessApproverByProcessDefinitionKey") + public void nextPrcessApproverByProcessDefinitionKey(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.nextPrcessApproverByProcessDefinitionKey(inputObject, outputObject); + } + + /** + * 启动流程--基础服务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "startProcess", value = "启动流程", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = FlowableSubData.class) + @RequestMapping("/post/ActivitiProcessController/startProcess") + public void startProcess(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.startProcess(inputObject, outputObject); + } + + /** + * 撤销流程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeProcess", value = "撤销流程", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ActivitiProcessController/revokeProcess") + public void revokeProcess(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.revokeProcess(inputObject, outputObject); + } + + /** + * 根据流程实例id获取流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProcessInstance", value = "根据流程实例id获取流程信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ActivitiProcessController/queryProcessInstance") + public void queryProcessInstance(InputObject inputObject, OutputObject outputObject) { + activitiProcessService.queryProcessInstance(inputObject, outputObject); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiTaskController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiTaskController.java new file mode 100644 index 0000000..f1f0f22 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiTaskController.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.controller; + +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActivitiTaskController + * @Description: 工作流用户任务相关 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工作流用户任务操作", tags = "工作流用户任务操作", modelName = "工作流模块") +public class ActivitiTaskController { + + @Autowired + private ActivitiTaskService activitiTaskService; + + /** + * 获取我的待办任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode008", value = "获取我的待办任务", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActivitiTaskController/queryUserAgencyTasksListByUserId") + public void queryUserAgencyTasksListByUserId(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryUserAgencyTasksListByUserId(inputObject, outputObject); + } + + /** + * 获取我的流程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode013", value = "获取我的流程", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActivitiTaskController/queryStartProcessNotSubByUserId") + public void queryStartProcessNotSubByUserId(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryStartProcessNotSubByUserId(inputObject, outputObject); + } + + /** + * 获取我的历史审批任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode014", value = "获取我的历史审批任务", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActivitiTaskController/queryMyHistoryTaskByUserId") + public void queryMyHistoryTaskByUserId(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryMyHistoryTaskByUserId(inputObject, outputObject); + } + + /** + * 获取历史审批列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode017", value = "获取历史审批列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/queryApprovalTasksHistoryByProcessInstanceId") + public void queryApprovalTasksHistoryByProcessInstanceId(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryApprovalTasksHistoryByProcessInstanceId(inputObject, outputObject); + } + + /** + * 获取所有已完成的流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode018", value = "获取所有已完成的流程信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActivitiTaskController/queryAllComplateProcessList") + public void queryAllComplateProcessList(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryAllComplateProcessList(inputObject, outputObject); + } + + /** + * 获取所有待办的流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode019", value = "获取所有待办的流程信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActivitiTaskController/queryAllConductProcessList") + public void queryAllConductProcessList(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.queryAllConductProcessList(inputObject, outputObject); + } + + /** + * 根据taskId获取表单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode016", value = "根据taskId获取表单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/querySubFormMationByTaskId") + public void querySubFormMationByTaskId(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.querySubFormMationByTaskId(inputObject, outputObject); + } + + /** + * 提交审批结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ActivitiTaskController/editActivitiModelToRun") + public void editActivitiModelToRun(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.editActivitiModelToRun(inputObject, outputObject); + } + + /** + * 委派 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask001", value = "委派", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "principalUserId", name = "principalUserId", value = "被委托人id", required = "required"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/delegateTask") + public void delegateTask(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.delegateTask(inputObject, outputObject); + } + + /** + * 转办 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask002", value = "委派", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "transferredPersonId", name = "transferredPersonId", value = "被转办人id", required = "required"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/transferTask") + public void transferTask(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.transferTask(inputObject, outputObject); + } + + /** + * 前加签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask003", value = "前加签", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "chooseUserMation", name = "chooseUserMation", value = "加签人的用户json串", required = "required,json"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/beforeAddSignTask") + public void beforeAddSignTask(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.beforeAddSignTask(inputObject, outputObject); + } + + /** + * 后加签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask004", value = "后加签", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "chooseUserMation", name = "chooseUserMation", value = "加签人的用户json串", required = "required,json"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/afterAddSignTask") + public void afterAddSignTask(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.afterAddSignTask(inputObject, outputObject); + } + + /** + * 获取会签节点的数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask006", value = "获取会签节点的数据信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/jointlySignTaskDetail") + public void jointlySignTaskDetail(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.jointlySignTaskDetail(inputObject, outputObject); + } + + /** + * 会签加减签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitiTask005", value = "会签加减签", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "chooseUserMation", name = "chooseUserMation", value = "加签人的用户json串", required = "required,json"), + @ApiImplicitParam(id = "taskId", name = "taskId", value = "任务id", required = "required")}) + @RequestMapping("/post/ActivitiTaskController/jointlySignAddSignTask") + public void jointlySignAddSignTask(InputObject inputObject, OutputObject outputObject) { + activitiTaskService.jointlySignAddSignTask(inputObject, outputObject); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiUserController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiUserController.java new file mode 100644 index 0000000..fb20ec9 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/controller/ActivitiUserController.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.controller; + +import com.skyeye.activiti.service.ActivitiUserService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActivitiUserController + * @Description: 工作流用户相关内容 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "工作流用户相关操作", tags = "工作流用户相关操作", modelName = "工作流用户相关操作") +public class ActivitiUserController { + + @Autowired + private ActivitiUserService activitiUserService; + + /** + * 获取人员选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode011", value = "获取人员选择", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "reqObj", name = "reqObj", value = "参数", required = "required")}) + @RequestMapping("/post/ActivitiUserController/queryUserListToActiviti") + public void queryUserListToActiviti(InputObject inputObject, OutputObject outputObject) { + activitiUserService.queryUserListToActiviti(inputObject, outputObject); + } + + /** + * 获取组人员选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode012", value = "获取组人员选择", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "reqObj", name = "reqObj", value = "参数", required = "required")}) + @RequestMapping("/post/ActivitiUserController/queryUserGroupListToActiviti") + public void queryUserGroupListToActiviti(InputObject inputObject, OutputObject outputObject) { + activitiUserService.queryUserGroupListToActiviti(inputObject, outputObject); + } + + /** + * 用户以及用户组信息同步到act表中 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "activitimode015", value = "获取组人员选择", method = "POST", allUse = "1") + @RequestMapping("/post/ActivitiUserController/insertSyncUserListMationToAct") + public void insertSyncUserListMationToAct(InputObject inputObject, OutputObject outputObject) { + activitiUserService.insertSyncUserListMationToAct(inputObject, outputObject); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/entity/NextTaskInfo.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/entity/NextTaskInfo.java new file mode 100644 index 0000000..d6d8df8 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/entity/NextTaskInfo.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.entity; + +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; +import org.flowable.bpmn.model.UserTask; + +import java.io.Serializable; + +/** + * @ClassName: NextTaskInfo + * @Description: 流程中下一个UserTask的信息 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/23 23:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class NextTaskInfo implements Serializable { + + @ApiModelProperty("用户任务节点信息") + private UserTask userTask; + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/FlowImgService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/FlowImgService.java new file mode 100644 index 0000000..aad5879 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/FlowImgService.java @@ -0,0 +1,303 @@ +package com.skyeye.activiti.flowimg; + +import com.skyeye.activiti.flowimg.img.CustomProcessDiagramGenerator; +import com.skyeye.common.util.FileUtil; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.bpmn.model.SequenceFlow; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.history.HistoricActivityInstance; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.runtime.Execution; +import org.flowable.image.ProcessDiagramGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @Description: FlowImgService + * @Author: liyang + * @Date: 2019/10/15 0015 9:32 + * @Version 1.0 + */ +@Component +public class FlowImgService { + private static final Logger LOG = LoggerFactory.getLogger(FlowImgService.class); + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private HistoryService historyService; + + /** + * 通过流程实例ID获取历史流程实例 + * + * @param procInstId + * @return + */ + public HistoricProcessInstance getHistoricProcInst(String procInstId) { + return historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult(); + } + + /** + * 通过流程实例ID获取流程中已经执行的节点,按照执行先后顺序排序 + * + * @param procInstId + * @return + */ + public List getHistoricActivityInstAsc(String procInstId) { + return historyService.createHistoricActivityInstanceQuery().processInstanceId(procInstId) + .orderByHistoricActivityInstanceId().asc().list(); + } + + /** + * 通过流程实例ID获取流程中正在执行的节点 + * + * @param procInstId + * @return + */ + public List getRunningActivityInst(String procInstId) { + return runtimeService.createExecutionQuery().processInstanceId(procInstId).list(); + } + + /** + * 通过流程实例ID获取已经完成的历史流程实例 + * + * @param procInstId + * @return + */ + public List getHistoricFinishedProcInst(String procInstId) { + return historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).finished().list(); + } + + /** + * 获取已流经的流程线,需要高亮显示高亮流程已发生流转的线id集合 + * + * @param bpmnModel + * @param historicActivityInstanceList + * @return + */ + public List getHighLightedFlows(BpmnModel bpmnModel, + List historicActivityInstanceList) { + // 已流经的流程线,需要高亮显示 + List highLightedFlowIdList = new ArrayList<>(); + // 全部活动节点 + List allHistoricActivityNodeList = new ArrayList<>(); + // 已完成的历史活动节点 + List finishedActivityInstanceList = new ArrayList<>(); + + for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) { + // 获取流程节点 + FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true); + String className = flowElement.getClass().getSimpleName(); + if (!"SequenceFlow".equals(className)) { + FlowNode flowNode = (FlowNode) flowElement; + allHistoricActivityNodeList.add(flowNode); + // 结束时间不为空,当前节点则已经完成 + if (historicActivityInstance.getEndTime() != null) { + finishedActivityInstanceList.add(historicActivityInstance); + } + } + } + + FlowNode currentFlowNode = null; + FlowNode targetFlowNode = null; + HistoricActivityInstance currentActivityInstance; + // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的 + for (int k = 0; k < finishedActivityInstanceList.size(); k++) { + currentActivityInstance = finishedActivityInstanceList.get(k); + // 获得当前活动对应的节点信息及outgoingFlows信息 + currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance + .getActivityId(), true); + // 当前节点的所有流出线 + List outgoingFlowList = currentFlowNode.getOutgoingFlows(); + + /** + * 遍历outgoingFlows并找到已流转的 满足如下条件认为已流转: + * 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 + * 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转 + * (第2点有问题,有过驳回的,会只绘制驳回的流程线,通过走向下一级的流程线没有高亮显示) + */ + if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals( + currentActivityInstance.getActivityType())) { + // 遍历历史活动节点,找到匹配流程目标节点的 + for (SequenceFlow outgoingFlow : outgoingFlowList) { + // 获取当前节点流程线对应的下级节点 + targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef(), + true); + // 如果下级节点包含在所有历史节点中,则将当前节点的流出线高亮显示 + if (allHistoricActivityNodeList.contains(targetFlowNode)) { + highLightedFlowIdList.add(outgoingFlow.getId()); + } + } + } else { + /** + * 2、当前节点不是并行网关或兼容网关 + * 【已解决-问题】如果当前节点有驳回功能,驳回到申请节点, + * 则因为申请节点在历史节点中,导致当前节点驳回到申请节点的流程线被高亮显示,但实际并没有进行驳回操作 + */ + List> tempMapList = new ArrayList<>(); + // 当前节点ID + String currentActivityId = currentActivityInstance.getActivityId(); + int size = historicActivityInstanceList.size(); + boolean ifStartFind = false; + boolean ifFinded = false; + HistoricActivityInstance historicActivityInstance; + // 循环当前节点的所有流出线 + // 循环所有历史节点 + LOG.info("【开始】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线:" + currentActivityId); + LOG.info("循环历史节点"); + for (int i = 0; i < historicActivityInstanceList.size(); i++) { + // // 如果当前节点流程线对应的下级节点在历史节点中,则该条流程线进行高亮显示(【问题】有驳回流程线时,即使没有进行驳回操作,因为申请节点在历史节点中,也会将驳回流程线高亮显示-_-||) + // if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) { + // Map map = new HashMap<>(); + // map.put("highLightedFlowId", sequenceFlow.getId()); + // map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime()); + // tempMapList.add(map); + // // highLightedFlowIdList.add(sequenceFlow.getId()); + // } + // 历史节点 + historicActivityInstance = historicActivityInstanceList.get(i); + LOG.info("第【" + (i + 1) + "/" + size + "】个历史节点-ActivityId=[" + historicActivityInstance.getActivityId() + "]"); + // 如果循环历史节点中的id等于当前节点id,从当前历史节点继续先后查找是否有当前节点流程线等于的节点 + // 历史节点的序号需要大于等于已完成历史节点的序号,防止驳回重审一个节点经过两次是只取第一次的流出线高亮显示,第二次的不显示 + if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) { + LOG.info("第[" + (i + 1) + "]个历史节点和当前节点一致-ActivityId=[" + historicActivityInstance.getActivityId() + "]"); + ifStartFind = true; + // 跳过当前节点继续查找下一个节点 + continue; + } + if (ifStartFind) { + LOG.info("[开始]-循环当前节点-ActivityId=【" + currentActivityId + "】的所有流出线"); + + ifFinded = false; + for (SequenceFlow sequenceFlow : outgoingFlowList) { + // 如果当前节点流程线对应的下级节点在其后面的历史节点中,则该条流程线进行高亮显示 + // 【问题】 + LOG.info("当前流出线的下级节点=[{}]:" + sequenceFlow.getTargetRef()); + if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) { + LOG.info("当前节点[" + currentActivityId + "]需高亮显示的流出线=[" + sequenceFlow.getId() + "]"); + highLightedFlowIdList.add(sequenceFlow.getId()); + // 暂时默认找到离当前节点最近的下一级节点即退出循环,否则有多条流出线时将全部被高亮显示 + ifFinded = true; + break; + } + } + LOG.info("[完成]-循环当前节点-ActivityId=【" + currentActivityId + "】的所有流出线"); + } + if (ifFinded) { + // 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环,否则有多条流出线时将全部被高亮显示 + break; + } + } + LOG.info("【完成】-匹配当前节点-ActivityId=【" + currentActivityId + "】需要高亮显示的流出线"); + // if (!CollectionUtils.isEmpty(tempMapList)) { + // // 遍历匹配的集合,取得开始时间最早的一个 + // long earliestStamp = 0L; + // String highLightedFlowId = null; + // for (Map map : tempMapList) { + // long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString()); + // if (earliestStamp == 0 || earliestStamp <= highLightedFlowStartTime) { + // highLightedFlowId = map.get("highLightedFlowId").toString(); + // earliestStamp = highLightedFlowStartTime; + // } + // } + // highLightedFlowIdList.add(highLightedFlowId); + // } + + } + + } + return highLightedFlowIdList; + } + + /** + * 根据流程实例Id,获取实时流程图片 + * + * @param procInstId + * @return + */ + public byte[] generateImageByProcInstId(String procInstId) { + if (StringUtils.isEmpty(procInstId)) { + LOG.error("[错误]-传入的参数procInstId为空!"); + throw new CustomException("[异常]-传入的参数procInstId为空!"); + } + InputStream imageStream = null; + try { + // 通过流程实例ID获取历史流程实例 + HistoricProcessInstance historicProcessInstance = getHistoricProcInst(procInstId); + + // 通过流程实例ID获取流程中已经执行的节点,按照执行先后顺序排序 + List historicActivityInstanceList = getHistoricActivityInstAsc(procInstId); + + // 将已经执行的节点ID放入高亮显示节点集合 + List highLightedActivitiIdList = new ArrayList<>(); + for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) { + highLightedActivitiIdList.add(historicActivityInstance.getActivityId()); + LOG.info("已执行的节点[" + historicActivityInstance.getId() + "-" + historicActivityInstance.getActivityId() + "-" + historicActivityInstance.getActivityName() + "-" + historicActivityInstance.getAssignee() + "]"); + } + + // 通过流程实例ID获取流程中正在执行的节点 + List runningActivityInstanceList = getRunningActivityInst(procInstId); + List runningActivitiIdList = new ArrayList(); + for (Execution execution : runningActivityInstanceList) { + if (StringUtils.isNotEmpty(execution.getActivityId())) { + runningActivitiIdList.add(execution.getActivityId()); + LOG.info("执行中的节点[" + execution.getId() + "-" + execution.getActivityId() + "-" + execution.getName() + "]"); + } + } + + // 通过流程实例ID获取已经完成的历史流程实例 + List historicFinishedProcessInstanceList = getHistoricFinishedProcInst(procInstId); + + // 定义流程画布生成器 + ProcessDiagramGenerator processDiagramGenerator = null; + // 如果还没完成,流程图高亮颜色为绿色,如果已经完成为红色 + // if (!CollectionUtils.isEmpty(historicFinishedProcessInstanceList)) { + // // 如果不为空,说明已经完成 + // processDiagramGenerator = processEngineConfiguration.getProcessDiagramGenerator(); + // } else { + processDiagramGenerator = new CustomProcessDiagramGenerator(); + // } + + // 获取流程定义Model对象 + BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId()); + + + // 获取已流经的流程线,需要高亮显示高亮流程已发生流转的线id集合 + List highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstanceList); + + // 使用默认配置获得流程图表生成器,并生成追踪图片字符流 + imageStream = ((CustomProcessDiagramGenerator) processDiagramGenerator) + .generateDiagramCustom(bpmnModel, "png", + highLightedActivitiIdList, runningActivitiIdList, highLightedFlowIds, + "宋体", "微软雅黑", "黑体", + null, 2.0); + // 将InputStream数据流转换为byte[] + byte[] buffer = new byte[imageStream.available()]; + imageStream.read(buffer); + return buffer; + } catch (Exception e) { + e.printStackTrace(); + LOG.error("通过流程实例ID[" + procInstId + "]获取流程图时出现异常!", e); + throw new CustomException("通过流程实例ID" + procInstId + "获取流程图时出现异常!", e); + } finally { + FileUtil.close(imageStream); + } + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramCanvas.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramCanvas.java new file mode 100644 index 0000000..422c6bf --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramCanvas.java @@ -0,0 +1,1328 @@ +package com.skyeye.activiti.flowimg.img; + + +import org.flowable.bpmn.model.AssociationDirection; +import org.flowable.bpmn.model.GraphicInfo; +import org.flowable.image.exception.FlowableImageException; +import org.flowable.image.util.ReflectUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.font.FontRenderContext; +import java.awt.font.LineBreakMeasurer; +import java.awt.font.TextAttribute; +import java.awt.font.TextLayout; +import java.awt.geom.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: CustomProcessDiagramCanvas + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 1:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class CustomProcessDiagramCanvas { + private static final Logger LOG = LoggerFactory.getLogger(CustomProcessDiagramCanvas.class); + + /** + * 形状类型:长方形、菱形、椭圆 + */ + public enum SHAPE_TYPE { + Rectangle, Rhombus, Ellipse + } + + // Predefined sized + protected static final int ARROW_WIDTH = 5; + protected static final int CONDITIONAL_INDICATOR_WIDTH = 16; + protected static final int DEFAULT_INDICATOR_WIDTH = 10; + protected static final int MARKER_WIDTH = 12; + protected static final int FONT_SIZE = 11; + protected static final int FONT_SPACING = 2; + protected static final int TEXT_PADDING = 3; + protected static final int ANNOTATION_TEXT_PADDING = 7; + protected static final int LINE_HEIGHT = FONT_SIZE + FONT_SPACING; + + // Colors + protected static Color TASK_BOX_COLOR = new Color(249, 249, 249); + protected static Color SUBPROCESS_BOX_COLOR = new Color(255, 255, 255); + protected static Color EVENT_COLOR = new Color(255, 255, 255); + protected static Color CONNECTION_COLOR = new Color(88, 88, 88); + protected static Color CONDITIONAL_INDICATOR_COLOR = new Color(255, 255, 255); + protected static Color RUNNING_HIGHLIGHT_COLOR = Color.RED; + protected static Color HIGHLIGHT_COLOR = Color.GREEN; + protected static Color LABEL_COLOR = new Color(112, 146, 190); + // protected static Color LABEL_COLOR = Color.blue; + protected static Color TASK_BORDER_COLOR = new Color(187, 187, 187); + protected static Color EVENT_BORDER_COLOR = new Color(88, 88, 88); + protected static Color SUBPROCESS_BORDER_COLOR = new Color(0, 0, 0); + + // Fonts + protected static Font LABEL_FONT = new Font("微软雅黑", Font.ITALIC, 11); + protected static Font ANNOTATION_FONT = new Font("Arial", Font.PLAIN, FONT_SIZE); + protected static Font TASK_FONT = new Font("Arial", Font.PLAIN, FONT_SIZE); + + // Strokes + // 边框宽度修改 + //protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(3.0f); + protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(2.0f); + protected static Stroke GATEWAY_TYPE_STROKE = new BasicStroke(3.0f); + protected static Stroke END_EVENT_STROKE = new BasicStroke(3.0f); + protected static Stroke MULTI_INSTANCE_STROKE = new BasicStroke(1.3f); + protected static Stroke EVENT_SUBPROCESS_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{1.0f}, 0.0f); + protected static Stroke NON_INTERRUPTING_EVENT_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{4.0f, 3.0f}, 0.0f); + protected static Stroke HIGHLIGHT_FLOW_STROKE = new BasicStroke(1.3f); + protected static Stroke ANNOTATION_STROKE = new BasicStroke(2.0f); + protected static Stroke ASSOCIATION_STROKE = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{2.0f, 2.0f}, 0.0f); + + // icons + protected static int ICON_PADDING = 5; + protected static BufferedImage USERTASK_IMAGE; + protected static BufferedImage SCRIPTTASK_IMAGE; + protected static BufferedImage SERVICETASK_IMAGE; + protected static BufferedImage RECEIVETASK_IMAGE; + protected static BufferedImage SENDTASK_IMAGE; + protected static BufferedImage MANUALTASK_IMAGE; + protected static BufferedImage BUSINESS_RULE_TASK_IMAGE; + protected static BufferedImage SHELL_TASK_IMAGE; + protected static BufferedImage MULE_TASK_IMAGE; + protected static BufferedImage CAMEL_TASK_IMAGE; + + protected static BufferedImage TIMER_IMAGE; + protected static BufferedImage COMPENSATE_THROW_IMAGE; + protected static BufferedImage COMPENSATE_CATCH_IMAGE; + protected static BufferedImage ERROR_THROW_IMAGE; + protected static BufferedImage ERROR_CATCH_IMAGE; + protected static BufferedImage MESSAGE_THROW_IMAGE; + protected static BufferedImage MESSAGE_CATCH_IMAGE; + protected static BufferedImage SIGNAL_CATCH_IMAGE; + protected static BufferedImage SIGNAL_THROW_IMAGE; + + protected int canvasWidth = -1; + protected int canvasHeight = -1; + protected int minX = -1; + protected int minY = -1; + protected BufferedImage processDiagram; + protected Graphics2D g; + protected FontMetrics fontMetrics; + protected boolean closed; + protected ClassLoader customClassLoader; + protected String activityFontName = "Arial"; + protected String labelFontName = "Arial"; + + /** + * Creates an empty canvas with given width and height. Allows to specify minimal boundaries on the left and upper side of the canvas. This is useful for diagrams that have + * white space there. Everything beneath these minimum values will be cropped. It's also possible to pass a specific font name and a class loader for the icon images. + */ + public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, ClassLoader customClassLoader) { + + this.canvasWidth = width; + this.canvasHeight = height; + this.minX = minX; + this.minY = minY; + if (activityFontName != null) { + this.activityFontName = activityFontName; + } + if (labelFontName != null) { + this.labelFontName = labelFontName; + } + this.customClassLoader = customClassLoader; + + initialize(imageType); + } + + /** + * Creates an empty canvas with given width and height. Allows to specify minimal boundaries on the left and upper side of the canvas. This is useful for diagrams that have + * white space there (eg Signavio). Everything beneath these minimum values will be cropped. + * + * @param minX Hint that will be used when generating the image. Parts that fall below minX on the horizontal scale will be cropped. + * @param minY Hint that will be used when generating the image. Parts that fall below minX on the horizontal scale will be cropped. + */ + public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType) { + this.canvasWidth = width; + this.canvasHeight = height; + this.minX = minX; + this.minY = minY; + + initialize(imageType); + } + + public void initialize(String imageType) { + if ("png".equalsIgnoreCase(imageType)) { + this.processDiagram = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB); + } else { + this.processDiagram = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB); + } + + this.g = processDiagram.createGraphics(); + if ("png".equalsIgnoreCase(imageType) == false) { + this.g.setBackground(new Color(255, 255, 255, 0)); + this.g.clearRect(0, 0, canvasWidth, canvasHeight); + } + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setPaint(Color.black); + + Font font = new Font(activityFontName, Font.BOLD, FONT_SIZE); + g.setFont(font); + this.fontMetrics = g.getFontMetrics(); + +// LABEL_FONT = new Font(labelFontName, Font.ITALIC, 10); + + try { + USERTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/userTask.png", customClassLoader)); + SCRIPTTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/scriptTask.png", customClassLoader)); + SERVICETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/serviceTask.png", customClassLoader)); + RECEIVETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/receiveTask.png", customClassLoader)); + SENDTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/sendTask.png", customClassLoader)); + MANUALTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/manualTask.png", customClassLoader)); + BUSINESS_RULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/businessRuleTask.png", customClassLoader)); + SHELL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/shellTask.png", customClassLoader)); + CAMEL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/camelTask.png", customClassLoader)); + MULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/muleTask.png", customClassLoader)); + + TIMER_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/timer.png", customClassLoader)); + COMPENSATE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate-throw.png", customClassLoader)); + COMPENSATE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate.png", customClassLoader)); + ERROR_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error-throw.png", customClassLoader)); + ERROR_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error.png", customClassLoader)); + MESSAGE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message-throw.png", customClassLoader)); + MESSAGE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message.png", customClassLoader)); + SIGNAL_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal-throw.png", customClassLoader)); + SIGNAL_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal.png", customClassLoader)); + } catch (IOException e) { + LOG.warn("Could not load image for process diagram creation: ", e); + } + } + + /** + * Generates an image of what currently is drawn on the canvas. Throws an + * {@link FlowableImageException} when {@link #close()} is already called. + */ + public InputStream generateImage(String imageType) { + if (closed) { + throw new FlowableImageException("ProcessDiagramGenerator already closed"); + } + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + // Try to remove white space + minX = (minX <= 5) ? 5 : minX; + minY = (minY <= 5) ? 5 : minY; + BufferedImage imageToSerialize = processDiagram; + if (minX >= 0 && minY >= 0) { + imageToSerialize = processDiagram.getSubimage(minX - 5, minY - 5, canvasWidth - minX + 5, canvasHeight - minY + 5); + } + ImageIO.write(imageToSerialize, imageType, out); + + } catch (IOException e) { + throw new FlowableImageException("Error while generating process image", e); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException ignore) { + // Exception is silently ignored + } + } + return new ByteArrayInputStream(out.toByteArray()); + } + + /** + * Generates an image of what currently is drawn on the canvas. Throws an + * {@link FlowableImageException} when {@link #close()} is already called. + */ + public BufferedImage generateBufferedImage(String imageType) { + if (closed) { + throw new FlowableImageException("ProcessDiagramGenerator already closed"); + } + + // Try to remove white space + minX = (minX <= 5) ? 5 : minX; + minY = (minY <= 5) ? 5 : minY; + BufferedImage imageToSerialize = processDiagram; + if (minX >= 0 && minY >= 0) { + imageToSerialize = processDiagram.getSubimage(minX - 5, minY - 5, canvasWidth - minX + 5, canvasHeight - minY + 5); + } + return imageToSerialize; + } + + /** + * Closes the canvas which dissallows further drawing and releases graphical resources. + */ + public void close() { + g.dispose(); + closed = true; + } + + public void drawNoneStartEvent(GraphicInfo graphicInfo) { + drawStartEvent(graphicInfo, null, 1.0); + } + + public void drawTimerStartEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawStartEvent(graphicInfo, TIMER_IMAGE, scaleFactor); + } + + public void drawSignalStartEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawStartEvent(graphicInfo, SIGNAL_CATCH_IMAGE, scaleFactor); + } + + public void drawMessageStartEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawStartEvent(graphicInfo, MESSAGE_CATCH_IMAGE, scaleFactor); + } + + public void drawStartEvent(GraphicInfo graphicInfo, BufferedImage image, double scaleFactor) { + Paint originalPaint = g.getPaint(); + g.setPaint(EVENT_COLOR); + Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()); + g.fill(circle); + g.setPaint(EVENT_BORDER_COLOR); + g.draw(circle); + g.setPaint(originalPaint); + if (image != null) { + // calculate coordinates to center image + int imageX = (int) Math.round(graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (image.getWidth() / 2 * scaleFactor)); + int imageY = (int) Math.round(graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (image.getHeight() / 2 * scaleFactor)); + g.drawImage(image, imageX, imageY, (int) (image.getWidth() / scaleFactor), (int) (image.getHeight() / scaleFactor), null); + } + + } + + public void drawNoneEndEvent(GraphicInfo graphicInfo, double scaleFactor) { + Paint originalPaint = g.getPaint(); + Stroke originalStroke = g.getStroke(); + g.setPaint(EVENT_COLOR); + Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()); + g.fill(circle); + g.setPaint(EVENT_BORDER_COLOR); + if (scaleFactor == 1.0) { + g.setStroke(END_EVENT_STROKE); + } else { + g.setStroke(new BasicStroke(2.0f)); + } + g.draw(circle); + g.setStroke(originalStroke); + g.setPaint(originalPaint); + } + + public void drawErrorEndEvent(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawErrorEndEvent(graphicInfo, scaleFactor); + if (scaleFactor == 1.0) { + drawLabel(name, graphicInfo); + } + } + + public void drawErrorEndEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawNoneEndEvent(graphicInfo, scaleFactor); + g.drawImage(ERROR_THROW_IMAGE, (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 4)), (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 4)), + (int) (ERROR_THROW_IMAGE.getWidth() / scaleFactor), (int) (ERROR_THROW_IMAGE.getHeight() / scaleFactor), null); + } + + public void drawErrorStartEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawNoneStartEvent(graphicInfo); + g.drawImage(ERROR_CATCH_IMAGE, (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 4)), (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 4)), + (int) (ERROR_CATCH_IMAGE.getWidth() / scaleFactor), (int) (ERROR_CATCH_IMAGE.getHeight() / scaleFactor), null); + } + + public void drawCatchingEvent(GraphicInfo graphicInfo, boolean isInterrupting, BufferedImage image, String eventType, double scaleFactor) { + + // event circles + Ellipse2D outerCircle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()); + int innerCircleSize = (int) (4 / scaleFactor); + if (innerCircleSize == 0) { + innerCircleSize = 1; + } + int innerCircleX = (int) graphicInfo.getX() + innerCircleSize; + int innerCircleY = (int) graphicInfo.getY() + innerCircleSize; + int innerCircleWidth = (int) graphicInfo.getWidth() - (2 * innerCircleSize); + int innerCircleHeight = (int) graphicInfo.getHeight() - (2 * innerCircleSize); + Ellipse2D innerCircle = new Ellipse2D.Double(innerCircleX, innerCircleY, innerCircleWidth, innerCircleHeight); + + Paint originalPaint = g.getPaint(); + Stroke originalStroke = g.getStroke(); + g.setPaint(EVENT_COLOR); + g.fill(outerCircle); + + g.setPaint(EVENT_BORDER_COLOR); + if (isInterrupting == false) { + g.setStroke(NON_INTERRUPTING_EVENT_STROKE); + } + g.draw(outerCircle); + g.setStroke(originalStroke); + g.setPaint(originalPaint); + g.draw(innerCircle); + + if (image != null) { + // calculate coordinates to center image + int imageX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (image.getWidth() / 2 * scaleFactor)); + int imageY = (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (image.getHeight() / 2 * scaleFactor)); + if (scaleFactor == 1.0 && "timer".equals(eventType)) { + // move image one pixel to center timer image + imageX++; + imageY++; + } + g.drawImage(image, imageX, imageY, (int) (image.getWidth() / scaleFactor), (int) (image.getHeight() / scaleFactor), null); + } + } + + public void drawCatchingCompensateEvent(String name, GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingCompensateEvent(graphicInfo, isInterrupting, scaleFactor); + drawLabel(name, graphicInfo); + } + + public void drawCatchingCompensateEvent(GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, COMPENSATE_CATCH_IMAGE, "compensate", scaleFactor); + } + + public void drawCatchingTimerEvent(String name, GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingTimerEvent(graphicInfo, isInterrupting, scaleFactor); + drawLabel(name, graphicInfo); + } + + public void drawCatchingTimerEvent(GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, TIMER_IMAGE, "timer", scaleFactor); + } + + public void drawCatchingErrorEvent(String name, GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingErrorEvent(graphicInfo, isInterrupting, scaleFactor); + drawLabel(name, graphicInfo); + } + + public void drawCatchingErrorEvent(GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, ERROR_CATCH_IMAGE, "error", scaleFactor); + } + + public void drawCatchingSignalEvent(String name, GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingSignalEvent(graphicInfo, isInterrupting, scaleFactor); + drawLabel(name, graphicInfo); + } + + public void drawCatchingSignalEvent(GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, SIGNAL_CATCH_IMAGE, "signal", scaleFactor); + } + + public void drawCatchingMessageEvent(GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, MESSAGE_CATCH_IMAGE, "message", scaleFactor); + } + + public void drawCatchingMessageEvent(String name, GraphicInfo graphicInfo, boolean isInterrupting, double scaleFactor) { + drawCatchingEvent(graphicInfo, isInterrupting, MESSAGE_CATCH_IMAGE, "message", scaleFactor); + drawLabel(name, graphicInfo); + } + + public void drawThrowingCompensateEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawCatchingEvent(graphicInfo, true, COMPENSATE_THROW_IMAGE, "compensate", scaleFactor); + } + + public void drawThrowingSignalEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawCatchingEvent(graphicInfo, true, SIGNAL_THROW_IMAGE, "signal", scaleFactor); + } + + public void drawThrowingNoneEvent(GraphicInfo graphicInfo, double scaleFactor) { + drawCatchingEvent(graphicInfo, true, null, "none", scaleFactor); + } + + public void drawSequenceflow(int srcX, int srcY, int targetX, int targetY, boolean conditional, double scaleFactor) { + drawSequenceflow(srcX, srcY, targetX, targetY, conditional, false, scaleFactor); + } + + public void drawSequenceflow(int srcX, int srcY, int targetX, int targetY, boolean conditional, boolean highLighted, double scaleFactor) { + Paint originalPaint = g.getPaint(); + if (highLighted) { + g.setPaint(HIGHLIGHT_COLOR); + } + + Line2D.Double line = new Line2D.Double(srcX, srcY, targetX, targetY); + g.draw(line); + drawArrowHead(line, scaleFactor); + + if (conditional) { + drawConditionalSequenceFlowIndicator(line, scaleFactor); + } + + if (highLighted) { + g.setPaint(originalPaint); + } + } + + public void drawAssociation(int[] xPoints, int[] yPoints, AssociationDirection associationDirection, boolean highLighted, double scaleFactor) { + boolean conditional = false, isDefault = false; + drawConnection(xPoints, yPoints, conditional, isDefault, "association", associationDirection, highLighted, scaleFactor); + } + + public void drawSequenceflow(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, boolean highLighted, double scaleFactor) { + drawConnection(xPoints, yPoints, conditional, isDefault, "sequenceFlow", AssociationDirection.ONE, highLighted, scaleFactor); + } + + public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDirection, + boolean highLighted, double scaleFactor) { + + Paint originalPaint = g.getPaint(); + Stroke originalStroke = g.getStroke(); + + g.setPaint(CONNECTION_COLOR); + //if (connectionType.equals("association")) { + if ("association".equals(connectionType)) { + g.setStroke(ASSOCIATION_STROKE); + } else if (highLighted) { + g.setPaint(HIGHLIGHT_COLOR); + g.setStroke(HIGHLIGHT_FLOW_STROKE); + } + + for (int i = 1; i < xPoints.length; i++) { + Integer sourceX = xPoints[i - 1]; + Integer sourceY = yPoints[i - 1]; + Integer targetX = xPoints[i]; + Integer targetY = yPoints[i]; + Line2D.Double line = new Line2D.Double(sourceX, sourceY, targetX, targetY); + g.draw(line); + } + + if (isDefault) { + Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]); + drawDefaultSequenceFlowIndicator(line, scaleFactor); + } + + if (conditional) { + Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]); + drawConditionalSequenceFlowIndicator(line, scaleFactor); + } + + if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) { + Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2], yPoints[xPoints.length - 2], xPoints[xPoints.length - 1], yPoints[xPoints.length - 1]); + drawArrowHead(line, scaleFactor); + } + if (associationDirection.equals(AssociationDirection.BOTH)) { + Line2D.Double line = new Line2D.Double(xPoints[1], yPoints[1], xPoints[0], yPoints[0]); + drawArrowHead(line, scaleFactor); + } + g.setPaint(originalPaint); + g.setStroke(originalStroke); + } + + public void drawSequenceflowWithoutArrow(int srcX, int srcY, int targetX, int targetY, boolean conditional, double scaleFactor) { + drawSequenceflowWithoutArrow(srcX, srcY, targetX, targetY, conditional, false, scaleFactor); + } + + public void drawSequenceflowWithoutArrow(int srcX, int srcY, int targetX, int targetY, boolean conditional, boolean highLighted, double scaleFactor) { + Paint originalPaint = g.getPaint(); + if (highLighted) { + g.setPaint(HIGHLIGHT_COLOR); + } + + Line2D.Double line = new Line2D.Double(srcX, srcY, targetX, targetY); + g.draw(line); + + if (conditional) { + drawConditionalSequenceFlowIndicator(line, scaleFactor); + } + + if (highLighted) { + g.setPaint(originalPaint); + } + } + + public void drawArrowHead(Line2D.Double line, double scaleFactor) { + int doubleArrowWidth = (int) (2 * ARROW_WIDTH / scaleFactor); + if (doubleArrowWidth == 0) { + doubleArrowWidth = 2; + } + Polygon arrowHead = new Polygon(); + arrowHead.addPoint(0, 0); + int arrowHeadPoint = (int) (-ARROW_WIDTH / scaleFactor); + if (arrowHeadPoint == 0) { + arrowHeadPoint = -1; + } + arrowHead.addPoint(arrowHeadPoint, -doubleArrowWidth); + arrowHeadPoint = (int) (ARROW_WIDTH / scaleFactor); + if (arrowHeadPoint == 0) { + arrowHeadPoint = 1; + } + arrowHead.addPoint(arrowHeadPoint, -doubleArrowWidth); + + AffineTransform transformation = new AffineTransform(); + transformation.setToIdentity(); + double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1); + transformation.translate(line.x2, line.y2); + transformation.rotate((angle - Math.PI / 2d)); + + AffineTransform originalTransformation = g.getTransform(); + g.setTransform(transformation); + g.fill(arrowHead); + g.setTransform(originalTransformation); + } + + public void drawDefaultSequenceFlowIndicator(Line2D.Double line, double scaleFactor) { + double length = DEFAULT_INDICATOR_WIDTH / scaleFactor, halfOfLength = length / 2, f = 8; + Line2D.Double defaultIndicator = new Line2D.Double(-halfOfLength, 0, halfOfLength, 0); + + double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1); + double dx = f * Math.cos(angle), dy = f * Math.sin(angle), x1 = line.x1 + dx, y1 = line.y1 + dy; + + AffineTransform transformation = new AffineTransform(); + transformation.setToIdentity(); + transformation.translate(x1, y1); + transformation.rotate((angle - 3 * Math.PI / 4)); + + AffineTransform originalTransformation = g.getTransform(); + g.setTransform(transformation); + g.draw(defaultIndicator); + + g.setTransform(originalTransformation); + } + + public void drawConditionalSequenceFlowIndicator(Line2D.Double line, double scaleFactor) { + if (scaleFactor > 1.0) { + return; + } + int horizontal = (int) (CONDITIONAL_INDICATOR_WIDTH * 0.7); + int halfOfHorizontal = horizontal / 2; + int halfOfVertical = CONDITIONAL_INDICATOR_WIDTH / 2; + + Polygon conditionalIndicator = new Polygon(); + conditionalIndicator.addPoint(0, 0); + conditionalIndicator.addPoint(-halfOfHorizontal, halfOfVertical); + conditionalIndicator.addPoint(0, CONDITIONAL_INDICATOR_WIDTH); + conditionalIndicator.addPoint(halfOfHorizontal, halfOfVertical); + + AffineTransform transformation = new AffineTransform(); + transformation.setToIdentity(); + double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1); + transformation.translate(line.x1, line.y1); + transformation.rotate((angle - Math.PI / 2d)); + + AffineTransform originalTransformation = g.getTransform(); + g.setTransform(transformation); + g.draw(conditionalIndicator); + + Paint originalPaint = g.getPaint(); + g.setPaint(CONDITIONAL_INDICATOR_COLOR); + g.fill(conditionalIndicator); + + g.setPaint(originalPaint); + g.setTransform(originalTransformation); + } + + public void drawTask(BufferedImage icon, String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(name, graphicInfo); + g.drawImage(icon, (int) (graphicInfo.getX() + ICON_PADDING / scaleFactor), (int) (graphicInfo.getY() + ICON_PADDING / scaleFactor), (int) (icon.getWidth() / scaleFactor), + (int) (icon.getHeight() / scaleFactor), null); + } + + public void drawTask(String name, GraphicInfo graphicInfo) { + drawTask(name, graphicInfo, false); + } + + public void drawPoolOrLane(String name, GraphicInfo graphicInfo) { + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + g.drawRect(x, y, width, height); + + // Add the name as text, vertical + if (name != null && name.length() > 0) { + // Include some padding + int availableTextSpace = height - 6; + + // Create rotation for derived font + AffineTransform transformation = new AffineTransform(); + transformation.setToIdentity(); + transformation.rotate(270 * Math.PI / 180); + + Font currentFont = g.getFont(); + Font theDerivedFont = currentFont.deriveFont(transformation); + g.setFont(theDerivedFont); + + String truncated = fitTextToWidth(name, availableTextSpace); + int realWidth = fontMetrics.stringWidth(truncated); + + g.drawString(truncated, x + 2 + fontMetrics.getHeight(), 3 + y + availableTextSpace - (availableTextSpace - realWidth) / 2); + g.setFont(currentFont); + } + } + + protected void drawTask(String name, GraphicInfo graphicInfo, boolean thickBorder) { + Paint originalPaint = g.getPaint(); + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + // Create a new gradient paint for every task box, gradient depends on x and y and is not relative + g.setPaint(TASK_BOX_COLOR); + + int arcR = 6; + if (thickBorder) { + arcR = 3; + } + + // shape + RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcR, arcR); + g.fill(rect); + g.setPaint(TASK_BORDER_COLOR); + + if (thickBorder) { + Stroke originalStroke = g.getStroke(); + g.setStroke(THICK_TASK_BORDER_STROKE); + g.draw(rect); + g.setStroke(originalStroke); + } else { + g.draw(rect); + } + + g.setPaint(originalPaint); + // text + if (name != null && name.length() > 0) { + int boxWidth = width - (2 * TEXT_PADDING); + int boxHeight = height - 16 - ICON_PADDING - ICON_PADDING - MARKER_WIDTH - 2 - 2; + int boxX = x + width / 2 - boxWidth / 2; + int boxY = y + height / 2 - boxHeight / 2 + ICON_PADDING + ICON_PADDING - 2 - 2; + + drawMultilineCentredText(name, boxX, boxY, boxWidth, boxHeight); + } + } + + protected void drawMultilineCentredText(String text, int x, int y, int boxWidth, int boxHeight) { + drawMultilineText(text, x, y, boxWidth, boxHeight, true); + } + + protected void drawMultilineAnnotationText(String text, int x, int y, int boxWidth, int boxHeight) { + drawMultilineText(text, x, y, boxWidth, boxHeight, false); + } + + protected void drawMultilineText(String text, int x, int y, int boxWidth, int boxHeight, boolean centered) { + // Create an attributed string based in input text + AttributedString attributedString = new AttributedString(text); + attributedString.addAttribute(TextAttribute.FONT, g.getFont()); + attributedString.addAttribute(TextAttribute.FOREGROUND, Color.black); + + AttributedCharacterIterator characterIterator = attributedString.getIterator(); + + int currentHeight = 0; + // Prepare a list of lines of text we'll be drawing + List layouts = new ArrayList(); + String lastLine = null; + + LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator, g.getFontRenderContext()); + + TextLayout layout = null; + while (measurer.getPosition() < characterIterator.getEndIndex() && currentHeight <= boxHeight) { + + int previousPosition = measurer.getPosition(); + + // Request next layout + layout = measurer.nextLayout(boxWidth); + + int height = ((Float) (layout.getDescent() + layout.getAscent() + layout.getLeading())).intValue(); + + if (currentHeight + height > boxHeight) { + // The line we're about to add should NOT be added anymore, append three dots to previous one instead + // to indicate more text is truncated + if (!layouts.isEmpty()) { + layouts.remove(layouts.size() - 1); + + if (lastLine.length() >= 4) { + lastLine = lastLine.substring(0, lastLine.length() - 4) + "..."; + } + layouts.add(new TextLayout(lastLine, g.getFont(), g.getFontRenderContext())); + } + } else { + layouts.add(layout); + lastLine = text.substring(previousPosition, measurer.getPosition()); + currentHeight += height; + } + } + + int currentY = y + (centered ? ((boxHeight - currentHeight) / 2) : 0); + int currentX = 0; + + // Actually draw the lines + for (TextLayout textLayout : layouts) { + + currentY += textLayout.getAscent(); + currentX = x + (centered ? ((boxWidth - ((Double) textLayout.getBounds().getWidth()).intValue()) / 2) : 0); + + textLayout.draw(g, currentX, currentY); + currentY += textLayout.getDescent() + textLayout.getLeading(); + } + + } + + protected String fitTextToWidth(String original, int width) { + String text = original; + + // remove length for "..." + int maxWidth = width - 10; + + while (fontMetrics.stringWidth(text + "...") > maxWidth && text.length() > 0) { + text = text.substring(0, text.length() - 1); + } + + if (!text.equals(original)) { + text = text + "..."; + } + + return text; + } + + public void drawUserTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(USERTASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawScriptTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(SCRIPTTASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawServiceTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(SERVICETASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawReceiveTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(RECEIVETASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawSendTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(SENDTASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawManualTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(MANUALTASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawBusinessRuleTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(BUSINESS_RULE_TASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawCamelTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(CAMEL_TASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawMuleTask(String name, GraphicInfo graphicInfo, double scaleFactor) { + drawTask(MULE_TASK_IMAGE, name, graphicInfo, scaleFactor); + } + + public void drawExpandedSubProcess(String name, GraphicInfo graphicInfo, Boolean isTriggeredByEvent, double scaleFactor) { + RoundRectangle2D rect = new RoundRectangle2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight(), 8, 8); + + // Use different stroke (dashed) + if (isTriggeredByEvent) { + Stroke originalStroke = g.getStroke(); + g.setStroke(EVENT_SUBPROCESS_STROKE); + g.draw(rect); + g.setStroke(originalStroke); + } else { + Paint originalPaint = g.getPaint(); + g.setPaint(SUBPROCESS_BOX_COLOR); + g.fill(rect); + g.setPaint(SUBPROCESS_BORDER_COLOR); + g.draw(rect); + g.setPaint(originalPaint); + } + + if (scaleFactor == 1.0 && name != null && !name.isEmpty()) { + String text = fitTextToWidth(name, (int) graphicInfo.getWidth()); + g.drawString(text, (int) graphicInfo.getX() + 10, (int) graphicInfo.getY() + 15); + } + } + + public void drawCollapsedSubProcess(String name, GraphicInfo graphicInfo, Boolean isTriggeredByEvent) { + drawCollapsedTask(name, graphicInfo, false); + } + + public void drawCollapsedCallActivity(String name, GraphicInfo graphicInfo) { + drawCollapsedTask(name, graphicInfo, true); + } + + protected void drawCollapsedTask(String name, GraphicInfo graphicInfo, boolean thickBorder) { + // The collapsed marker is now visualized separately + drawTask(name, graphicInfo, thickBorder); + } + + public void drawCollapsedMarker(int x, int y, int width, int height) { + // rectangle + int rectangleWidth = MARKER_WIDTH; + int rectangleHeight = MARKER_WIDTH; + Rectangle rect = new Rectangle(x + (width - rectangleWidth) / 2, y + height - rectangleHeight - 3, rectangleWidth, rectangleHeight); + g.draw(rect); + + // plus inside rectangle + Line2D.Double line = new Line2D.Double(rect.getCenterX(), rect.getY() + 2, rect.getCenterX(), rect.getMaxY() - 2); + g.draw(line); + line = new Line2D.Double(rect.getMinX() + 2, rect.getCenterY(), rect.getMaxX() - 2, rect.getCenterY()); + g.draw(line); + } + + public void drawActivityMarkers(int x, int y, int width, int height, boolean multiInstanceSequential, boolean multiInstanceParallel, boolean collapsed) { + if (collapsed) { + if (!multiInstanceSequential && !multiInstanceParallel) { + drawCollapsedMarker(x, y, width, height); + } else { + drawCollapsedMarker(x - MARKER_WIDTH / 2 - 2, y, width, height); + if (multiInstanceSequential) { + drawMultiInstanceMarker(true, x + MARKER_WIDTH / 2 + 2, y, width, height); + } else { + drawMultiInstanceMarker(false, x + MARKER_WIDTH / 2 + 2, y, width, height); + } + } + } else { + if (multiInstanceSequential) { + drawMultiInstanceMarker(true, x, y, width, height); + } else if (multiInstanceParallel) { + drawMultiInstanceMarker(false, x, y, width, height); + } + } + } + + public void drawGateway(GraphicInfo graphicInfo) { + Polygon rhombus = new Polygon(); + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + rhombus.addPoint(x, y + (height / 2)); + rhombus.addPoint(x + (width / 2), y + height); + rhombus.addPoint(x + width, y + (height / 2)); + rhombus.addPoint(x + (width / 2), y); + g.draw(rhombus); + } + + public void drawParallelGateway(GraphicInfo graphicInfo, double scaleFactor) { + // rhombus + drawGateway(graphicInfo); + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + if (scaleFactor == 1.0) { + // plus inside rhombus + Stroke orginalStroke = g.getStroke(); + g.setStroke(GATEWAY_TYPE_STROKE); + Line2D.Double line = new Line2D.Double(x + 10, y + height / 2, x + width - 10, y + height / 2); // horizontal + g.draw(line); + line = new Line2D.Double(x + width / 2, y + height - 10, x + width / 2, y + 10); // vertical + g.draw(line); + g.setStroke(orginalStroke); + } + } + + public void drawExclusiveGateway(GraphicInfo graphicInfo, double scaleFactor) { + // rhombus + drawGateway(graphicInfo); + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + int quarterWidth = width / 4; + int quarterHeight = height / 4; + + if (scaleFactor == 1.0) { + // X inside rhombus + Stroke orginalStroke = g.getStroke(); + g.setStroke(GATEWAY_TYPE_STROKE); + Line2D.Double line = new Line2D.Double(x + quarterWidth + 3, y + quarterHeight + 3, x + 3 * quarterWidth - 3, y + 3 * quarterHeight - 3); + g.draw(line); + line = new Line2D.Double(x + quarterWidth + 3, y + 3 * quarterHeight - 3, x + 3 * quarterWidth - 3, y + quarterHeight + 3); + g.draw(line); + g.setStroke(orginalStroke); + } + } + + public void drawInclusiveGateway(GraphicInfo graphicInfo, double scaleFactor) { + // rhombus + drawGateway(graphicInfo); + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + int diameter = width / 2; + + if (scaleFactor == 1.0) { + // circle inside rhombus + Stroke orginalStroke = g.getStroke(); + g.setStroke(GATEWAY_TYPE_STROKE); + Ellipse2D.Double circle = new Ellipse2D.Double(((width - diameter) / 2) + x, ((height - diameter) / 2) + y, diameter, diameter); + g.draw(circle); + g.setStroke(orginalStroke); + } + } + + public void drawEventBasedGateway(GraphicInfo graphicInfo, double scaleFactor) { + // rhombus + drawGateway(graphicInfo); + + if (scaleFactor == 1.0) { + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + double scale = .6; + + GraphicInfo eventInfo = new GraphicInfo(); + eventInfo.setX(x + width * (1 - scale) / 2); + eventInfo.setY(y + height * (1 - scale) / 2); + eventInfo.setWidth(width * scale); + eventInfo.setHeight(height * scale); + drawCatchingEvent(eventInfo, true, null, "eventGateway", scaleFactor); + + double r = width / 6.; + + // create pentagon (coords with respect to center) + int topX = (int) (.95 * r); // top right corner + int topY = (int) (-.31 * r); + int bottomX = (int) (.59 * r); // bottom right corner + int bottomY = (int) (.81 * r); + + int[] xPoints = new int[]{0, topX, bottomX, -bottomX, -topX}; + int[] yPoints = new int[]{-(int) r, topY, bottomY, bottomY, topY}; + Polygon pentagon = new Polygon(xPoints, yPoints, 5); + pentagon.translate(x + width / 2, y + width / 2); + + // draw + g.drawPolygon(pentagon); + } + } + + public void drawMultiInstanceMarker(boolean sequential, int x, int y, int width, int height) { + int rectangleWidth = MARKER_WIDTH; + int rectangleHeight = MARKER_WIDTH; + int lineX = x + (width - rectangleWidth) / 2; + int lineY = y + height - rectangleHeight - 3; + + Stroke orginalStroke = g.getStroke(); + g.setStroke(MULTI_INSTANCE_STROKE); + + if (sequential) { + g.draw(new Line2D.Double(lineX, lineY, lineX + rectangleWidth, lineY)); + g.draw(new Line2D.Double(lineX, lineY + rectangleHeight / 2, lineX + rectangleWidth, lineY + rectangleHeight / 2)); + g.draw(new Line2D.Double(lineX, lineY + rectangleHeight, lineX + rectangleWidth, lineY + rectangleHeight)); + } else { + g.draw(new Line2D.Double(lineX, lineY, lineX, lineY + rectangleHeight)); + g.draw(new Line2D.Double(lineX + rectangleWidth / 2, lineY, lineX + rectangleWidth / 2, lineY + rectangleHeight)); + g.draw(new Line2D.Double(lineX + rectangleWidth, lineY, lineX + rectangleWidth, lineY + rectangleHeight)); + } + + g.setStroke(orginalStroke); + } + + public void drawHighLight(int x, int y, int width, int height) { + Paint originalPaint = g.getPaint(); + Stroke originalStroke = g.getStroke(); + + g.setPaint(HIGHLIGHT_COLOR); + g.setStroke(THICK_TASK_BORDER_STROKE); + + // 长方形弧度修改 + //RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); + RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 0, 0); + g.draw(rect); + + g.setPaint(originalPaint); + g.setStroke(originalStroke); + } + + + /** + * Desc: 绘制正在执行中的节点红色高亮显示 + * + * @param x + * @param y + * @param width + * @param height + * @author Fuxs + */ + public void drawRunningActivitiHighLight(int x, int y, int width, int height) { + Paint originalPaint = g.getPaint(); + Stroke originalStroke = g.getStroke(); + + g.setPaint(RUNNING_HIGHLIGHT_COLOR); + g.setStroke(THICK_TASK_BORDER_STROKE); + // 修改长方形弧度 + //RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20); + RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 0, 0); + g.draw(rect); + + g.setPaint(originalPaint); + g.setStroke(originalStroke); + } + + public void drawTextAnnotation(String text, GraphicInfo graphicInfo) { + int x = (int) graphicInfo.getX(); + int y = (int) graphicInfo.getY(); + int width = (int) graphicInfo.getWidth(); + int height = (int) graphicInfo.getHeight(); + + Font originalFont = g.getFont(); + Stroke originalStroke = g.getStroke(); + + g.setFont(ANNOTATION_FONT); + + Path2D path = new Path2D.Double(); + x += .5; + int lineLength = 18; + path.moveTo(x + lineLength, y); + path.lineTo(x, y); + path.lineTo(x, y + height); + path.lineTo(x + lineLength, y + height); + + path.lineTo(x + lineLength, y + height - 1); + path.lineTo(x + 1, y + height - 1); + path.lineTo(x + 1, y + 1); + path.lineTo(x + lineLength, y + 1); + path.closePath(); + + g.draw(path); + + int boxWidth = width - (2 * ANNOTATION_TEXT_PADDING); + int boxHeight = height - (2 * ANNOTATION_TEXT_PADDING); + int boxX = x + width / 2 - boxWidth / 2; + int boxY = y + height / 2 - boxHeight / 2; + + if (text != null && text.isEmpty() == false) { + drawMultilineAnnotationText(text, boxX, boxY, boxWidth, boxHeight); + } + + // restore originals + g.setFont(originalFont); + g.setStroke(originalStroke); + } + + public void drawLabel(String text, GraphicInfo graphicInfo) { + drawLabel(text, graphicInfo, true); + } + + /** + * 绘制流程线名称 + * Desc: + * + * @param text + * @param graphicInfo + * @param centered + * @author Fuxs + */ + public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) { + float interline = 1.0f; + + // text + if (text != null && text.length() > 0) { + Paint originalPaint = g.getPaint(); + Font originalFont = g.getFont(); + + g.setPaint(LABEL_COLOR); + g.setFont(LABEL_FONT); + + int wrapWidth = 100; + int textY = (int) (graphicInfo.getY() + graphicInfo.getHeight()); + + AttributedString as = new AttributedString(text); + as.addAttribute(TextAttribute.FOREGROUND, g.getPaint()); + as.addAttribute(TextAttribute.FONT, g.getFont()); + AttributedCharacterIterator aci = as.getIterator(); + FontRenderContext frc = new FontRenderContext(null, true, false); + LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); + + while (lbm.getPosition() < text.length()) { + TextLayout tl = lbm.nextLayout(wrapWidth); + textY += tl.getAscent(); + Rectangle2D bb = tl.getBounds(); + double tX = graphicInfo.getX(); + if (centered) { + tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2); + } + tl.draw(g, (float) tX, textY); + textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent(); + } + + // restore originals + g.setFont(originalFont); + g.setPaint(originalPaint); + } + } + + /** + * This method makes coordinates of connection flow better. + * + * @param sourceShapeType + * @param targetShapeType + * @param sourceGraphicInfo + * @param targetGraphicInfo + * @param graphicInfoList + */ + public List connectionPerfectionizer(SHAPE_TYPE sourceShapeType, SHAPE_TYPE targetShapeType, GraphicInfo sourceGraphicInfo, GraphicInfo targetGraphicInfo, + List graphicInfoList) { + Shape shapeFirst = createShape(sourceShapeType, sourceGraphicInfo); + Shape shapeLast = createShape(targetShapeType, targetGraphicInfo); + + if (graphicInfoList != null && graphicInfoList.size() > 0) { + GraphicInfo graphicInfoFirst = graphicInfoList.get(0); + GraphicInfo graphicInfoLast = graphicInfoList.get(graphicInfoList.size() - 1); + if (shapeFirst != null) { + graphicInfoFirst.setX(shapeFirst.getBounds2D().getCenterX()); + graphicInfoFirst.setY(shapeFirst.getBounds2D().getCenterY()); + } + if (shapeLast != null) { + graphicInfoLast.setX(shapeLast.getBounds2D().getCenterX()); + graphicInfoLast.setY(shapeLast.getBounds2D().getCenterY()); + } + + Point p = null; + + if (shapeFirst != null) { + Line2D.Double lineFirst = new Line2D.Double(graphicInfoFirst.getX(), graphicInfoFirst.getY(), graphicInfoList.get(1).getX(), graphicInfoList.get(1).getY()); + p = getIntersection(shapeFirst, lineFirst); + if (p != null) { + graphicInfoFirst.setX(p.getX()); + graphicInfoFirst.setY(p.getY()); + } + } + + if (shapeLast != null) { + Line2D.Double lineLast = new Line2D.Double(graphicInfoLast.getX(), graphicInfoLast.getY(), graphicInfoList.get(graphicInfoList.size() - 2).getX(), + graphicInfoList.get(graphicInfoList.size() - 2).getY()); + p = getIntersection(shapeLast, lineLast); + if (p != null) { + graphicInfoLast.setX(p.getX()); + graphicInfoLast.setY(p.getY()); + } + } + } + + return graphicInfoList; + } + + /** + * This method creates shape by type and coordinates. + * + * @param shapeType + * @param graphicInfo + * @return Shape + */ + private static Shape createShape(SHAPE_TYPE shapeType, GraphicInfo graphicInfo) { + if (SHAPE_TYPE.Rectangle.equals(shapeType)) { + // source is rectangle + return new Rectangle2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()); + } else if (SHAPE_TYPE.Rhombus.equals(shapeType)) { + // source is rhombus + Path2D.Double rhombus = new Path2D.Double(); + rhombus.moveTo(graphicInfo.getX(), graphicInfo.getY() + graphicInfo.getHeight() / 2); + rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2, graphicInfo.getY() + graphicInfo.getHeight()); + rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth(), graphicInfo.getY() + graphicInfo.getHeight() / 2); + rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2, graphicInfo.getY()); + rhombus.lineTo(graphicInfo.getX(), graphicInfo.getY() + graphicInfo.getHeight() / 2); + rhombus.closePath(); + return rhombus; + } else if (SHAPE_TYPE.Ellipse.equals(shapeType)) { + // source is ellipse + return new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()); + } else { + // unknown source element, just do not correct coordinates + } + return null; + } + + /** + * This method returns intersection point of shape border and line. + * + * @param shape + * @param line + * @return Point + */ + private static Point getIntersection(Shape shape, Line2D.Double line) { + if (shape instanceof Ellipse2D) { + return getEllipseIntersection(shape, line); + } else if (shape instanceof Rectangle2D || shape instanceof Path2D) { + return getShapeIntersection(shape, line); + } else { + // something strange + return null; + } + } + + /** + * This method calculates ellipse intersection with line + * + * @param shape Bounds of this shape used to calculate parameters of inscribed into this bounds ellipse. + * @param line + * @return Intersection point + */ + private static Point getEllipseIntersection(Shape shape, Line2D.Double line) { + double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1); + double x = shape.getBounds2D().getWidth() / 2 * Math.cos(angle) + shape.getBounds2D().getCenterX(); + double y = shape.getBounds2D().getHeight() / 2 * Math.sin(angle) + shape.getBounds2D().getCenterY(); + Point p = new Point(); + p.setLocation(x, y); + return p; + } + + /** + * This method calculates shape intersection with line. + * + * @param shape + * @param line + * @return Intersection point + */ + private static Point getShapeIntersection(Shape shape, Line2D.Double line) { + PathIterator it = shape.getPathIterator(null); + double[] coords = new double[6]; + double[] pos = new double[2]; + Line2D.Double l = new Line2D.Double(); + while (!it.isDone()) { + int type = it.currentSegment(coords); + switch (type) { + case PathIterator.SEG_MOVETO: + pos[0] = coords[0]; + pos[1] = coords[1]; + break; + case PathIterator.SEG_LINETO: + l = new Line2D.Double(pos[0], pos[1], coords[0], coords[1]); + if (line.intersectsLine(l)) { + return getLinesIntersection(line, l); + } + pos[0] = coords[0]; + pos[1] = coords[1]; + break; + case PathIterator.SEG_CLOSE: + break; + default: + // whatever + } + it.next(); + } + return null; + } + + /** + * This method calculates intersections of two lines. + * + * @param a Line 1 + * @param b Line 2 + * @return Intersection point + */ + private static Point getLinesIntersection(Line2D a, Line2D b) { + double d = (a.getX1() - a.getX2()) * (b.getY2() - b.getY1()) - (a.getY1() - a.getY2()) * (b.getX2() - b.getX1()); + double da = (a.getX1() - b.getX1()) * (b.getY2() - b.getY1()) - (a.getY1() - b.getY1()) * (b.getX2() - b.getX1()); + // double db = (a.getX1()-a.getX2())*(a.getY1()-b.getY1()) - (a.getY1()-a.getY2())*(a.getX1()-b.getX1()); + double ta = da / d; + // double tb = db/d; + Point p = new Point(); + p.setLocation(a.getX1() + ta * (a.getX2() - a.getX1()), a.getY1() + ta * (a.getY2() - a.getY1())); + return p; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramGenerator.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramGenerator.java new file mode 100644 index 0000000..12576c6 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/flowimg/img/CustomProcessDiagramGenerator.java @@ -0,0 +1,1003 @@ +package com.skyeye.activiti.flowimg.img; + +import org.flowable.bpmn.model.Process; +import org.flowable.bpmn.model.*; +import org.flowable.image.ProcessDiagramGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.util.*; + +/** + * @ClassName: CustomProcessDiagramGenerator + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 1:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class CustomProcessDiagramGenerator implements ProcessDiagramGenerator { + private static final Logger LOG = LoggerFactory.getLogger(CustomProcessDiagramGenerator.class); + + + protected Map, ActivityDrawInstruction> activityDrawInstructions = new HashMap, ActivityDrawInstruction>(); + protected Map, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap, ArtifactDrawInstruction>(); + + public CustomProcessDiagramGenerator() { + this(1.0); + } + + // The instructions on how to draw a certain construct is + // created statically and stored in a map for performance. + public CustomProcessDiagramGenerator(final double scaleFactor) { + // start event + activityDrawInstructions.put(StartEvent.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + StartEvent startEvent = (StartEvent) flowNode; + if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) { + EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0); + if (eventDefinition instanceof TimerEventDefinition) { + processDiagramCanvas.drawTimerStartEvent(graphicInfo, scaleFactor); + } else if (eventDefinition instanceof ErrorEventDefinition) { + processDiagramCanvas.drawErrorStartEvent(graphicInfo, scaleFactor); + } else if (eventDefinition instanceof SignalEventDefinition) { + processDiagramCanvas.drawSignalStartEvent(graphicInfo, scaleFactor); + } else if (eventDefinition instanceof MessageEventDefinition) { + processDiagramCanvas.drawMessageStartEvent(graphicInfo, scaleFactor); + } else { + processDiagramCanvas.drawNoneStartEvent(graphicInfo); + } + } else { + processDiagramCanvas.drawNoneStartEvent(graphicInfo); + } + } + }); + + // signal catch + activityDrawInstructions.put(IntermediateCatchEvent.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode; + if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent + .getEventDefinitions().isEmpty()) { + if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) { + processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, true, + scaleFactor); + } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) { + processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, true, scaleFactor); + } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) { + processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, true, + scaleFactor); + } + } + } + }); + + // signal throw + activityDrawInstructions.put(ThrowEvent.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + ThrowEvent throwEvent = (ThrowEvent) flowNode; + if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) { + if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) { + processDiagramCanvas.drawThrowingSignalEvent(graphicInfo, scaleFactor); + } else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) { + processDiagramCanvas.drawThrowingCompensateEvent(graphicInfo, scaleFactor); + } else { + processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor); + } + } else { + processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor); + } + } + }); + + // end event + activityDrawInstructions.put(EndEvent.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + EndEvent endEvent = (EndEvent) flowNode; + if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) { + if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) { + processDiagramCanvas.drawErrorEndEvent(flowNode.getName(), graphicInfo, scaleFactor); + } else { + processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor); + } + } else { + processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor); + } + } + }); + + // task + activityDrawInstructions.put(Task.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawTask(flowNode.getName(), graphicInfo); + } + }); + + // user task + activityDrawInstructions.put(UserTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawUserTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // script task + activityDrawInstructions.put(ScriptTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawScriptTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // service task + activityDrawInstructions.put(ServiceTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + ServiceTask serviceTask = (ServiceTask) flowNode; + if ("camel".equalsIgnoreCase(serviceTask.getType())) { + processDiagramCanvas.drawCamelTask(serviceTask.getName(), graphicInfo, scaleFactor); + } else if ("mule".equalsIgnoreCase(serviceTask.getType())) { + processDiagramCanvas.drawMuleTask(serviceTask.getName(), graphicInfo, scaleFactor); + } else { + processDiagramCanvas.drawServiceTask(serviceTask.getName(), graphicInfo, scaleFactor); + } + } + }); + + // receive task + activityDrawInstructions.put(ReceiveTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawReceiveTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // send task + activityDrawInstructions.put(SendTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawSendTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // manual task + activityDrawInstructions.put(ManualTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawManualTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // businessRuleTask task + activityDrawInstructions.put(BusinessRuleTask.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawBusinessRuleTask(flowNode.getName(), graphicInfo, scaleFactor); + } + }); + + // exclusive gateway + activityDrawInstructions.put(ExclusiveGateway.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawExclusiveGateway(graphicInfo, scaleFactor); + } + }); + + // inclusive gateway + activityDrawInstructions.put(InclusiveGateway.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawInclusiveGateway(graphicInfo, scaleFactor); + } + }); + + // parallel gateway + activityDrawInstructions.put(ParallelGateway.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawParallelGateway(graphicInfo, scaleFactor); + } + }); + + // event based gateway + activityDrawInstructions.put(EventGateway.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawEventBasedGateway(graphicInfo, scaleFactor); + } + }); + + // Boundary timer + activityDrawInstructions.put(BoundaryEvent.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode; + if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) { + if (boundaryEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) { + + processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, boundaryEvent + .isCancelActivity(), scaleFactor); + + } else if (boundaryEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) { + + processDiagramCanvas.drawCatchingErrorEvent(graphicInfo, boundaryEvent.isCancelActivity(), + scaleFactor); + + } else if (boundaryEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) { + processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, boundaryEvent + .isCancelActivity(), scaleFactor); + + } else if (boundaryEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) { + processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, boundaryEvent + .isCancelActivity(), scaleFactor); + + } else if (boundaryEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) { + processDiagramCanvas.drawCatchingCompensateEvent(graphicInfo, boundaryEvent.isCancelActivity(), + scaleFactor); + } + } + + } + }); + + // subprocess + activityDrawInstructions.put(SubProcess.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { + processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false); + } else { + processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor); + } + } + }); + + // Event subprocess + activityDrawInstructions.put(EventSubProcess.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) { + processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, true); + } else { + processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, true, scaleFactor); + } + } + }); + + // call activity + activityDrawInstructions.put(CallActivity.class, new ActivityDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + processDiagramCanvas.drawCollapsedCallActivity(flowNode.getName(), graphicInfo); + } + }); + + // text annotation + artifactDrawInstructions.put(TextAnnotation.class, new ArtifactDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId()); + TextAnnotation textAnnotation = (TextAnnotation) artifact; + processDiagramCanvas.drawTextAnnotation(textAnnotation.getText(), graphicInfo); + } + }); + + // association + artifactDrawInstructions.put(Association.class, new ArtifactDrawInstruction() { + + @Override + public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) { + Association association = (Association) artifact; + String sourceRef = association.getSourceRef(); + String targetRef = association.getTargetRef(); + + // source and target can be instance of FlowElement or Artifact + BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef); + BaseElement targetElement = bpmnModel.getFlowElement(targetRef); + if (sourceElement == null) { + sourceElement = bpmnModel.getArtifact(sourceRef); + } + if (targetElement == null) { + targetElement = bpmnModel.getArtifact(targetRef); + } + List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId()); + graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, + targetElement, graphicInfoList); + int[] xPoints = new int[graphicInfoList.size()]; + int[] yPoints = new int[graphicInfoList.size()]; + for (int i = 1; i < graphicInfoList.size(); i++) { + GraphicInfo graphicInfo = graphicInfoList.get(i); + GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1); + + if (i == 1) { + xPoints[0] = (int) previousGraphicInfo.getX(); + yPoints[0] = (int) previousGraphicInfo.getY(); + } + xPoints[i] = (int) graphicInfo.getX(); + yPoints[i] = (int) graphicInfo.getY(); + } + + AssociationDirection associationDirection = association.getAssociationDirection(); + processDiagramCanvas.drawAssociation(xPoints, yPoints, associationDirection, false, scaleFactor); + } + }); + } + + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List highLightedFlows, String activityFontName, String labelFontName, ClassLoader customClassLoader, + double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + + return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, new ArrayList(), + highLightedFlows, activityFontName, labelFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI).generateImage( + imageType); + } + + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List highLightedFlows, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, 1.0, drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, + scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI); + } + + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, + double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), + scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, + String labelFontName, ClassLoader customClassLoader, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), + activityFontName, labelFontName, customClassLoader, 1.0, drawSequenceFlowNameWithNoLabelDI); + } + + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, + String labelFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + + return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), + activityFontName, labelFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + public InputStream generatePngDiagram(BpmnModel bpmnModel) { + + return generatePngDiagram(bpmnModel, 1.0, true); + } + + @Override + public InputStream generatePngDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), + scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generateJpgDiagram(BpmnModel bpmnModel) { + return generateDiagram(bpmnModel, "jpg", Collections.emptyList(), Collections.emptyList(), true); + + } + + @Override + public InputStream generateJpgDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, "jpg", Collections.emptyList(), Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI); + } + + + public BufferedImage generateImage(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List highLightedFlows, String activityFontName, String labelFontName, ClassLoader customClassLoader, + double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + + return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, new ArrayList(), + highLightedFlows, activityFontName, labelFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI) + .generateBufferedImage(imageType); + } + + public BufferedImage generateImage(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + + return generateImage(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, + scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + + protected CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, + List highLightedActivities, List runningActivitiIdList, List highLightedFlows, + String activityFontName, String labelFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + + CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, + activityFontName, labelFontName, customClassLoader); + + // Draw pool shape, if process is participant in collaboration + for (Pool pool : bpmnModel.getPools()) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId()); + processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo); + } + + // Draw lanes + for (Process process : bpmnModel.getProcesses()) { + for (Lane lane : process.getLanes()) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId()); + processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo); + } + } + + // Draw activities and their sequence-flows + /** + * 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理 + */ + for (FlowNode flowNode : bpmnModel.getProcesses().get(0).findFlowElementsOfType(FlowNode.class)) { + drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, runningActivitiIdList, + highLightedFlows, scaleFactor); + } + + // Draw artifacts + for (Process process : bpmnModel.getProcesses()) { + for (Artifact artifact : process.getArtifacts()) { + drawArtifact(processDiagramCanvas, bpmnModel, artifact); + } + } + + return processDiagramCanvas; + } + + /** + * Desc: 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理 + * + * @param processDiagramCanvas + * @param bpmnModel + * @param flowNode + * @param highLightedActivities + * @param highLightedFlows + * @param scaleFactor + * @author Fuxs + */ + protected void drawActivity(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode, + List highLightedActivities, List runningActivitiIdList, List highLightedFlows, + double scaleFactor) { + ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass()); + if (drawInstruction != null) { + drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode); + // Gather info on the multi instance marker + boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false; + if (flowNode instanceof Activity) { + Activity activity = (Activity) flowNode; + MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics(); + if (multiInstanceLoopCharacteristics != null) { + multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential(); + multiInstanceParallel = !multiInstanceSequential; + } + } + + // Gather info on the collapsed marker + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + if (flowNode instanceof SubProcess) { + collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded(); + } else if (flowNode instanceof CallActivity) { + collapsed = true; + } + + if (scaleFactor == 1.0) { + // Actually draw the markers + processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), + (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, + multiInstanceParallel, collapsed); + } + // 绘制需要突出强调的活动 + if (highLightedActivities.contains(flowNode.getId())) { + //如果节点为当前正在处理中的节点,则红色高亮显示 + if (runningActivitiIdList.contains(flowNode.getId())) { + LOG.debug("[绘制]-当前正在处理中的节点-红色高亮显示节点[" + flowNode.getId() + "-" + flowNode.getName() + "]"); + drawRunningActivitiHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); + } else { + LOG.debug("[绘制]-高亮显示节点[" + flowNode.getId() + "-" + flowNode.getName() + "]"); + drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId())); + } + } + } + // 绘制当前节点的流程线 + for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) { + boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId())); + String defaultFlow = null; + if (flowNode instanceof Activity) { + defaultFlow = ((Activity) flowNode).getDefaultFlow(); + } else if (flowNode instanceof Gateway) { + defaultFlow = ((Gateway) flowNode).getDefaultFlow(); + } + + boolean isDefault = false; + if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) { + isDefault = true; + } + boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway); + + String sourceRef = sequenceFlow.getSourceRef(); + String targetRef = sequenceFlow.getTargetRef(); + FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef); + FlowElement targetElement = bpmnModel.getFlowElement(targetRef); + List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId()); + if (graphicInfoList != null && graphicInfoList.size() > 0) { + graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, + targetElement, graphicInfoList); + int[] xPoints = new int[graphicInfoList.size()]; + int[] yPoints = new int[graphicInfoList.size()]; + for (int i = 1; i < graphicInfoList.size(); i++) { + GraphicInfo graphicInfo = graphicInfoList.get(i); + GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1); + if (i == 1) { + xPoints[0] = (int) previousGraphicInfo.getX(); + yPoints[0] = (int) previousGraphicInfo.getY(); + } + xPoints[i] = (int) graphicInfo.getX(); + yPoints[i] = (int) graphicInfo.getY(); + + } + + processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, + highLighted, scaleFactor); + //绘制流程线名称 + GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId()); +// if (labelGraphicInfo != null) { + GraphicInfo lineCenter = getLineCenter(graphicInfoList); + processDiagramCanvas.drawLabel(sequenceFlow.getName(), lineCenter, true); +// } + } + } + + // Nested elements + if (flowNode instanceof FlowElementsContainer) { + for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) { + if (nestedFlowElement instanceof FlowNode) { + drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, highLightedActivities, + runningActivitiIdList, highLightedFlows, scaleFactor); + } + } + } + } + + /** + * This method makes coordinates of connection flow better. + * + * @param processDiagramCanvas + * @param bpmnModel + * @param sourceElement + * @param targetElement + * @param graphicInfoList + * @return + */ + protected static List connectionPerfectionizer(CustomProcessDiagramCanvas processDiagramCanvas, + BpmnModel bpmnModel, BaseElement sourceElement, BaseElement targetElement, + List graphicInfoList) { + GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId()); + GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId()); + + CustomProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement); + CustomProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement); + + return processDiagramCanvas.connectionPerfectionizer(sourceShapeType, targetShapeType, sourceGraphicInfo, + targetGraphicInfo, graphicInfoList); + } + + /** + * This method returns shape type of base element.
+ * Each element can be presented as rectangle, rhombus, or ellipse. + * + * @param baseElement + * @return CustomProcessDiagramCanvas.SHAPE_TYPE + */ + protected static CustomProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) { + if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) { + return CustomProcessDiagramCanvas.SHAPE_TYPE.Rectangle; + } else if (baseElement instanceof Gateway) { + return CustomProcessDiagramCanvas.SHAPE_TYPE.Rhombus; + } else if (baseElement instanceof Event) { + return CustomProcessDiagramCanvas.SHAPE_TYPE.Ellipse; + } else { + // unknown source element, just do not correct coordinates + } + return null; + } + + protected static GraphicInfo getLineCenter(List graphicInfoList) { + GraphicInfo gi = new GraphicInfo(); + + int[] xPoints = new int[graphicInfoList.size()]; + int[] yPoints = new int[graphicInfoList.size()]; + + double length = 0; + double[] lengths = new double[graphicInfoList.size()]; + lengths[0] = 0; + double m; + for (int i = 1; i < graphicInfoList.size(); i++) { + GraphicInfo graphicInfo = graphicInfoList.get(i); + GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1); + + if (i == 1) { + xPoints[0] = (int) previousGraphicInfo.getX(); + yPoints[0] = (int) previousGraphicInfo.getY(); + } + xPoints[i] = (int) graphicInfo.getX(); + yPoints[i] = (int) graphicInfo.getY(); + + length += Math.sqrt(Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(), 2) + Math.pow( + (int) graphicInfo.getY() - (int) previousGraphicInfo.getY(), 2)); + lengths[i] = length; + } + m = length / 2; + int p1 = 0, p2 = 1; + for (int i = 1; i < lengths.length; i++) { + double len = lengths[i]; + p1 = i - 1; + p2 = i; + if (len > m) { + break; + } + } + + GraphicInfo graphicInfo1 = graphicInfoList.get(p1); + GraphicInfo graphicInfo2 = graphicInfoList.get(p2); + + double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX(); + double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY(); + double OB = lengths[p2] - lengths[p1]; + double ob = m - lengths[p1]; + double ab = AB * ob / OB; + double oa = OA * ob / OB; + + double mx = graphicInfo1.getX() + ab; + double my = graphicInfo1.getY() + oa; + + gi.setX(mx); + gi.setY(my); + return gi; + } + + protected void drawArtifact(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, + Artifact artifact) { + + ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass()); + if (drawInstruction != null) { + drawInstruction.draw(processDiagramCanvas, bpmnModel, artifact); + } + } + + private static void drawHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { + processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo + .getWidth(), (int) graphicInfo.getHeight()); + + } + + /** + * Desc:绘制正在执行中的节点红色高亮显示 + * + * @param processDiagramCanvas + * @param graphicInfo + * @author Fuxs + */ + private static void drawRunningActivitiHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) { + processDiagramCanvas.drawRunningActivitiHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo + .getWidth(), (int) graphicInfo.getHeight()); + + } + + protected static CustomProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType, + String activityFontName, String labelFontName, ClassLoader customClassLoader) { + // 我们需要计算最大值以了解图像的整体大小 + double minX = Double.MAX_VALUE; + double maxX = 0; + double minY = Double.MAX_VALUE; + double maxY = 0; + + for (Pool pool : bpmnModel.getPools()) { + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId()); + minX = graphicInfo.getX(); + maxX = graphicInfo.getX() + graphicInfo.getWidth(); + minY = graphicInfo.getY(); + maxY = graphicInfo.getY() + graphicInfo.getHeight(); + } + + List flowNodes = gatherAllFlowNodes(bpmnModel); + for (FlowNode flowNode : flowNodes) { + + GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); + + // 宽度 + if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) { + maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth(); + } + if (flowNodeGraphicInfo.getX() < minX) { + minX = flowNodeGraphicInfo.getX(); + } + // 高度 + if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) { + maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight(); + } + if (flowNodeGraphicInfo.getY() < minY) { + minY = flowNodeGraphicInfo.getY(); + } + + for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) { + List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId()); + if (graphicInfoList != null) { + for (GraphicInfo graphicInfo : graphicInfoList) { + // width + if (graphicInfo.getX() > maxX) { + maxX = graphicInfo.getX(); + } + if (graphicInfo.getX() < minX) { + minX = graphicInfo.getX(); + } + // height + if (graphicInfo.getY() > maxY) { + maxY = graphicInfo.getY(); + } + if (graphicInfo.getY() < minY) { + minY = graphicInfo.getY(); + } + } + } + } + } + + List artifacts = gatherAllArtifacts(bpmnModel); + for (Artifact artifact : artifacts) { + + GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId()); + + if (artifactGraphicInfo != null) { + // 宽度 + if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) { + maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth(); + } + if (artifactGraphicInfo.getX() < minX) { + minX = artifactGraphicInfo.getX(); + } + // 高度 + if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) { + maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight(); + } + if (artifactGraphicInfo.getY() < minY) { + minY = artifactGraphicInfo.getY(); + } + } + + List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId()); + if (graphicInfoList != null) { + for (GraphicInfo graphicInfo : graphicInfoList) { + // 宽度 + if (graphicInfo.getX() > maxX) { + maxX = graphicInfo.getX(); + } + if (graphicInfo.getX() < minX) { + minX = graphicInfo.getX(); + } + // 高度 + if (graphicInfo.getY() > maxY) { + maxY = graphicInfo.getY(); + } + if (graphicInfo.getY() < minY) { + minY = graphicInfo.getY(); + } + } + } + } + + int nrOfLanes = 0; + for (Process process : bpmnModel.getProcesses()) { + for (Lane l : process.getLanes()) { + + nrOfLanes++; + + GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(l.getId()); + // 宽度 + if (graphicInfo.getX() + graphicInfo.getWidth() > maxX) { + maxX = graphicInfo.getX() + graphicInfo.getWidth(); + } + if (graphicInfo.getX() < minX) { + minX = graphicInfo.getX(); + } + // 高度 + if (graphicInfo.getY() + graphicInfo.getHeight() > maxY) { + maxY = graphicInfo.getY() + graphicInfo.getHeight(); + } + if (graphicInfo.getY() < minY) { + minY = graphicInfo.getY(); + } + } + } + + // Special case, see http://jira.codehaus.org/browse/ACT-1431 + if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) { + // Nothing to show + minX = 0; + minY = 0; + } + + return new CustomProcessDiagramCanvas((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY, imageType, + activityFontName, labelFontName, customClassLoader); + } + + protected static List gatherAllArtifacts(BpmnModel bpmnModel) { + List artifacts = new ArrayList(); + for (Process process : bpmnModel.getProcesses()) { + artifacts.addAll(process.getArtifacts()); + } + return artifacts; + } + + protected static List gatherAllFlowNodes(BpmnModel bpmnModel) { + List flowNodes = new ArrayList(); + for (Process process : bpmnModel.getProcesses()) { + flowNodes.addAll(gatherAllFlowNodes(process)); + } + return flowNodes; + } + + protected static List gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) { + List flowNodes = new ArrayList(); + for (FlowElement flowElement : flowElementsContainer.getFlowElements()) { + if (flowElement instanceof FlowNode) { + flowNodes.add((FlowNode) flowElement); + } + if (flowElement instanceof FlowElementsContainer) { + flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement)); + } + } + return flowNodes; + } + + public Map, ActivityDrawInstruction> getActivityDrawInstructions() { + return activityDrawInstructions; + } + + public void setActivityDrawInstructions( + Map, ActivityDrawInstruction> activityDrawInstructions) { + this.activityDrawInstructions = activityDrawInstructions; + } + + public Map, ArtifactDrawInstruction> getArtifactDrawInstructions() { + return artifactDrawInstructions; + } + + public void setArtifactDrawInstructions( + Map, ArtifactDrawInstruction> artifactDrawInstructions) { + this.artifactDrawInstructions = artifactDrawInstructions; + } + + protected interface ActivityDrawInstruction { + + void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode); + } + + protected interface ArtifactDrawInstruction { + + void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact); + } + + + /** + * Desc: 自定义生成Diagram方法,添加对正在执行中的节点红色高亮显示 + * + * @param bpmnModel + * @param imageType + * @param highLightedActivities + * @param runningActivitiIdList + * @param highLightedFlows + * @param activityFontName + * @param labelFontName + * @param annotationFontName + * @param customClassLoader + * @param scaleFactor + * @return + * @author Fuxs + */ + public InputStream generateDiagramCustom(BpmnModel bpmnModel, String imageType, List highLightedActivities, + List runningActivitiIdList, List highLightedFlows, String activityFontName, + String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor) { + return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, runningActivitiIdList, + highLightedFlows, activityFontName, labelFontName, customClassLoader, scaleFactor, true).generateImage( + imageType); + } + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, + String labelFontName, String annotationFontName, ClassLoader customClassLoader, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), + activityFontName, labelFontName, customClassLoader, 1.0, drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, + String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(), + activityFontName, labelFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generatePngDiagram(BpmnModel bpmnModel, boolean drawSequenceFlowNameWithNoLabelDI) { + return generateDiagram(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI); + } + + @Override + public InputStream generateDiagram(BpmnModel bpmnModel, + String imageType, + List highLightedActivities, + List highLightedFlows, + String activityFontName, + String labelFontName, + String annotationFontName, + ClassLoader customClassLoader, + double scaleFactor, + boolean drawSequenceFlowNameWithNoLabelDI) { + return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, new ArrayList(), + highLightedFlows, activityFontName, labelFontName, customClassLoader, scaleFactor + , drawSequenceFlowNameWithNoLabelDI).generateImage( + imageType); + } + + @Override + public BufferedImage generatePngImage(BpmnModel bpmnModel, double scaleFactor) { + return generateImage(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), + scaleFactor, true); + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java new file mode 100644 index 0000000..70864c8 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.listener; + +import com.alibaba.fastjson.JSON; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; + +/** + * @ClassName: MultiInstanceloopListener + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/14 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class MultiInstanceloopListener implements ExecutionListener { + + @Override + public void notify(DelegateExecution execution) { + System.out.println(JSON.toJSONString(execution)); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/ActivityMapper.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/ActivityMapper.java new file mode 100644 index 0000000..317c80a --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/ActivityMapper.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.mapper; + +import org.apache.ibatis.annotations.Param; + +/** + * 自定义activiti mapper接口 + */ +public interface ActivityMapper { + + void updateProcessDefinitionName(@Param("name") String name, @Param("processDefinitionId") String processDefinitionId); + + void deleteHisActivityInstanceByTaskId(@Param("taskId") String taskId); + + void deleteHisTaskInstanceByTaskId(@Param("taskId") String taskId); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReModelDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReModelDao.java new file mode 100644 index 0000000..859044c --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReModelDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.mapper; + +import org.apache.ibatis.annotations.Param; +import org.flowable.engine.impl.persistence.entity.ModelEntityImpl; + +import java.util.List; + +/** + * @ClassName: FlowModelDao + * @Description: 原生工作流模型数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/5 12:15 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FlowReModelDao { + + List getModelByIds(@Param("ids") List ids); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReProcdefDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReProcdefDao.java new file mode 100644 index 0000000..6cc2b9d --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowReProcdefDao.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.mapper; + +import org.apache.ibatis.annotations.Param; +import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl; +import org.flowable.engine.repository.ProcessDefinition; + +import java.util.List; + +/** + * @ClassName: FlowReProcdefDao + * @Description: 原生工作流模型发布后的流程定义 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/5 12:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FlowReProcdefDao { + + List getProcdefByDeploymentIds(@Param("deploymentIds") List deploymentIds); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowableTaskDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowableTaskDao.java new file mode 100644 index 0000000..348e12b --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/FlowableTaskDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.mapper; + +import com.skyeye.common.entity.search.CommonPageInfo; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FlowableTaskDao + * @Description: 任务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/25 23:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FlowableTaskDao { + + /** + * 查询待办任务 + * + * @param pageInfo 参数 + * @return + */ + List> getApplyingTasks(CommonPageInfo pageInfo); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/HistoryActivityInstanceMapper.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/HistoryActivityInstanceMapper.java new file mode 100644 index 0000000..4b4a6c9 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/mapper/HistoryActivityInstanceMapper.java @@ -0,0 +1,17 @@ +package com.skyeye.activiti.mapper; + +import org.apache.ibatis.annotations.Param; + +/** + * @ClassName: HistoryActivityInstanceMapper + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/18 0:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface HistoryActivityInstanceMapper { + + int delete(@Param("id") String id); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiModelService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiModelService.java new file mode 100644 index 0000000..87fdec2 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiModelService.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.flowable.entity.FlowableSubData; +import org.flowable.task.api.Task; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActivitiModelService + * @Description: 工作流模型操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 21:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActivitiModelService { + + String insertNewActivitiModel(String modelName, String modelKey); + + void setActivitiModelList(List> actFlowList); + + void editActivitiModelToDeploy(InputObject inputObject, OutputObject outputObject); + + void deleteActivitiModelById(String modelId); + + void deleteReleasedActivitiModelById(InputObject inputObject, OutputObject outputObject); + + void editApprovalActivitiTaskListByUserId(InputObject inputObject, OutputObject outputObject); + + /** + * 获取指定任务节点的变换信息 + * + * @param approvedId 审批人id + * @param approvedName 审批人名字 + * @param opinion 审批意见 + * @param flag 该节点是否审批通过,true:通过,false:不通过 + * @param task 任务 + * @param type + * @return + */ + List> getUpLeaveList(String approvedId, String approvedName, String opinion, Boolean flag, Task task, int type); + + String startProcess(FlowableSubData flowableSubData, ActFlowMation actFlowMation); + + /** + * 流程图高亮显示 + * + * @param processInstanceId + */ + void queryProHighLighted(String processInstanceId); + + void editModelByModelId(String modelId, String modelName, String modelKey); +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiProcessService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiProcessService.java new file mode 100644 index 0000000..3cd3c5b --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiProcessService.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.activiti.entity.NextTaskInfo; + +import java.util.Map; + +/** + * @ClassName: ActivitiProcessService + * @Description: 工作流流程相关操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 21:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActivitiProcessService { + + void updateProcessToHangUp(InputObject inputObject, OutputObject outputObject); + + void updateProcessToActivation(InputObject inputObject, OutputObject outputObject); + + void editProcessInstanceWithDraw(InputObject inputObject, OutputObject outputObject); + + void editProcessInstancePicToRefresh(InputObject inputObject, OutputObject outputObject); + + void nextPrcessApprover(InputObject inputObject, OutputObject outputObject); + + /** + * 获取下一个用户任务信息 + * + * @param taskId 任务Id信息 + * @param map 表单数据 + * @return 下一个用户任务用户组信息 + */ + NextTaskInfo getNextTaskInfo(String taskId, Map map); + + void nextPrcessApproverByProcessDefinitionKey(InputObject inputObject, OutputObject outputObject); + + void startProcess(InputObject inputObject, OutputObject outputObject); + + void revokeProcess(InputObject inputObject, OutputObject outputObject); + + void queryProcessInstance(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java new file mode 100644 index 0000000..05ba73a --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.flowable.bpmn.model.UserTask; +import org.flowable.task.api.Task; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActivitiTaskService + * @Description: 工作流用户任务相关 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActivitiTaskService { + + void queryUserAgencyTasksListByUserId(InputObject inputObject, OutputObject outputObject); + + void queryStartProcessNotSubByUserId(InputObject inputObject, OutputObject outputObject); + + void queryMyHistoryTaskByUserId(InputObject inputObject, OutputObject outputObject); + + void queryApprovalTasksHistoryByProcessInstanceId(InputObject inputObject, OutputObject outputObject); + + void queryAllComplateProcessList(InputObject inputObject, OutputObject outputObject); + + void queryAllConductProcessList(InputObject inputObject, OutputObject outputObject); + + void querySubFormMationByTaskId(InputObject inputObject, OutputObject outputObject); + + List getTaskAssignee(String processInstanceId); + + /** + * 获取当前任务节点填写的表单数据 + * + * @param taskId 任务id + * @return 当前任务节点填写的表单数据 + */ + Map getCurrentTaskParamsByTaskId(String taskId); + + void editActivitiModelToRun(InputObject inputObject, OutputObject outputObject); + + /** + * 获取该指定节点下所有的子节点还有多少个 + * + * @param parentTaskId 节点id + * @return 剩余的子节点数量 + */ + long getSubTaskCount(String parentTaskId); + + void setNextUserTaskApproval(String processInstanceId, String approverId); + + /** + * 根据taskId获取UserTask对象 + * + * @param taskId 任务id + * @return UserTask对象 + */ + UserTask getCurrentUserTaskByTaskId(String taskId); + + /** + * 根据任务节点id判断该节点是否为会签节点 + * + * @param taskId 任务节点id + * @return true:是会签节点;false:不是会签节点 + */ + boolean isMultiInstance(String taskId, Map map); + + void delegateTask(InputObject inputObject, OutputObject outputObject); + + void transferTask(InputObject inputObject, OutputObject outputObject); + + void beforeAddSignTask(InputObject inputObject, OutputObject outputObject); + + void afterAddSignTask(InputObject inputObject, OutputObject outputObject); + + void jointlySignTaskDetail(InputObject inputObject, OutputObject outputObject); + + void jointlySignAddSignTask(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiUserService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiUserService.java new file mode 100644 index 0000000..7be29d8 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/ActivitiUserService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ActivitiUserService + * @Description: 工作流用户相关内容 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActivitiUserService { + + void queryUserListToActiviti(InputObject inputObject, OutputObject outputObject); + + void queryUserGroupListToActiviti(InputObject inputObject, OutputObject outputObject); + + void insertSyncUserListMationToAct(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiModelServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiModelServiceImpl.java new file mode 100644 index 0000000..5405a4e --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiModelServiceImpl.java @@ -0,0 +1,451 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.skyeye.activiti.flowimg.FlowImgService; +import com.skyeye.activiti.mapper.ActivityMapper; +import com.skyeye.activiti.mapper.FlowReModelDao; +import com.skyeye.activiti.mapper.FlowReProcdefDao; +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.flowable.entity.FlowableSubData; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.userprocess.service.ActUserProcessService; +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.converter.BpmnXMLConverter; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.editor.constants.ModelDataJsonConstants; +import org.flowable.editor.language.json.converter.BpmnJsonConverter; +import org.flowable.engine.ProcessEngine; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.impl.persistence.entity.ModelEntityImpl; +import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl; +import org.flowable.engine.repository.Deployment; +import org.flowable.engine.repository.Model; +import org.flowable.engine.repository.ModelQuery; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; +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.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ActivitiModelServiceImpl + * @Description: 工作流模型操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/17 20:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActivitiModelServiceImpl implements ActivitiModelService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ActivitiModelServiceImpl.class); + + @Autowired + private ProcessEngine processEngine; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private RuntimeService runtimeService; + + @Autowired + public JedisClientService jedisClient; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private ActivityMapper activityMapper; + + @Autowired + private ActivitiTaskService activitiTaskService; + + @Autowired + private FlowImgService flowImgService; + + @Autowired + private FlowReModelDao flowReModelDao; + + @Autowired + private FlowReProcdefDao flowReProcdefDao; + + @Value("${skyeye.author}") + private String author; + + @Autowired + private ActUserProcessService actUserProcessService; + + /** + * 新建一个空模型 + * + * @param modelName 模型名称 + * @param modelKey 流程id + * @return + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public String insertNewActivitiModel(String modelName, String modelKey) { + RepositoryService repositoryService = processEngine.getRepositoryService(); + // 初始化一个空模型 + Model model = repositoryService.newModel(); + // 设置一些默认信息 + ObjectNode modelNode = getMateInfo(modelName); + + model.setName(modelName); + model.setKey(ToolUtil.getSurFaceId()); + model.setMetaInfo(modelNode.toString()); + + ObjectNode editorNode = objectMapper.createObjectNode(); + editorNode.put("id", "canvas"); + editorNode.put("resourceId", "canvas"); + + ObjectNode processProperties = getProcessProperties(modelName, modelKey, null); + editorNode.put("properties", processProperties); + + ObjectNode stencilSetNode = objectMapper.createObjectNode(); + stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); + editorNode.put("stencilset", stencilSetNode); + + repositoryService.saveModel(model); + try { + repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes("utf-8")); + } catch (UnsupportedEncodingException e) { + throw new CustomException(e); + } + return model.getId(); + } + + private ObjectNode getProcessProperties(String modelName, String modelKey, ObjectNode processProperties) { + if (processProperties == null) { + processProperties = objectMapper.createObjectNode(); + } + processProperties.put("process_author", author); + processProperties.put("process_id", modelKey); + processProperties.put("name", modelName); + return processProperties; + } + + private ObjectNode getMateInfo(String modelName) { + ObjectNode modelNode = objectMapper.createObjectNode(); + modelNode.put(ModelDataJsonConstants.MODEL_NAME, modelName); + modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, StringUtils.EMPTY); + modelNode.put(ModelDataJsonConstants.MODEL_REVISION, CommonNumConstants.NUM_ONE); + return modelNode; + } + + /** + * 设置流程模型信息 + * + * @param actFlowList + */ + @Override + public void setActivitiModelList(List> actFlowList) { + // 查询模型 + List modelIds = actFlowList.stream().map(bean -> bean.get("modelId").toString()).collect(Collectors.toList()); + List modelList = flowReModelDao.getModelByIds(modelIds); + Map modelMap = modelList.stream().collect(Collectors.toMap(bean -> bean.getId(), bean -> bean)); + // 查询发布流程 + List deploymentIds = modelList.stream().filter(bean -> !ToolUtil.isBlank(bean.getDeploymentId())).map(bean -> bean.getDeploymentId()).collect(Collectors.toList()); + List procdefList = flowReProcdefDao.getProcdefByDeploymentIds(deploymentIds); + Map procdefMap = procdefList.stream().collect(Collectors.toMap(bean -> bean.getDeploymentId(), bean -> bean)); + + actFlowList.forEach(bean -> { + Model model = modelMap.get(bean.get("modelId").toString()); + bean.put("model", BeanUtil.beanToMap(model)); + ProcessDefinition processDefinition = procdefMap.get(model.getDeploymentId()); + bean.put("procdef", processDefinition != null ? BeanUtil.beanToMap(processDefinition) : new HashMap<>()); + }); + } + + /** + * 发布模型为流程定义 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editActivitiModelToDeploy(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String modelId = map.get("modelId").toString(); + // 获取模型 + Model modelData = repositoryService.getModel(modelId); + byte[] bytes = repositoryService.getModelEditorSource(modelData.getId()); + if (bytes == null) { + outputObject.setreturnMessage("模型数据为空,请先设计流程并成功保存,再进行发布。"); + return; + } + try { + JsonNode modelNode = new ObjectMapper().readTree(bytes); + LOGGER.info("modelNode = {}", modelNode.toString()); + BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode); + if (model.getProcesses().size() == 0) { + outputObject.setreturnMessage("数据模型不符要求,请至少设计一条主线流程。"); + return; + } + byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model); + + // 发布流程 + String processName = modelData.getName() + ".bpmn20.xml"; + Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy(); + + // 发布版本+1 + Integer version = modelData.getVersion(); + modelData.setVersion(StrUtil.isBlank(modelData.getDeploymentId()) ? version : version + 1); + modelData.setDeploymentId(deployment.getId()); + repositoryService.saveModel(modelData); + + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult(); + if (!StrUtil.isBlank(processName)) { + activityMapper.updateProcessDefinitionName(processName, processDefinition.getId()); + LOGGER.info("流程模型【{}】没有配置流程名称,默认使用流程模型名称作为流程名称", processName); + } + LOGGER.info("流程【{}】成功发布", processName); + } catch (Exception ee) { + throw new CustomException(ee); + } + } + + @Override + public String startProcess(FlowableSubData flowableSubData, ActFlowMation actFlowMation) { + if (!judgeProcessKeyIsLive(actFlowMation)) { + throw new CustomException("任务发起失败,不存在该流程模型."); + } + LOGGER.info("approvalId is : " + flowableSubData.getApprovalId()); + // 业务对象 + Map varables = new HashMap<>(); + // 默认设置审批人为会签人 + varables.put(ActivitiConstants.ASSIGNEE_USER_LIST, Arrays.asList(flowableSubData.getApprovalId())); + LOGGER.info("startProcessInstanceByKey start."); + // 启动流程---流程图id,业务表id + ProcessInstance process = runtimeService.startProcessInstanceByKey(actFlowMation.getModelKey(), varables); + String processInstanceId = process.getProcessInstanceId(); + + queryProHighLighted(processInstanceId); + // 存储用户启动的流程 + actUserProcessService.saveActUserProcess(processInstanceId, actFlowMation.getId(), flowableSubData.getObjectId(), flowableSubData.getObjectKey(), + flowableSubData.getAppId()); + + // 设置第一个userTask任务的审批人 + activitiTaskService.setNextUserTaskApproval(processInstanceId, flowableSubData.getApprovalId()); + LOGGER.info("start process success, processInstanceId is: {}", processInstanceId); + return processInstanceId; + } + + /** + * 判断该key的流程是否还存在 + * + * @param actFlowMation skyeye的工作流模型 + * @return + */ + private boolean judgeProcessKeyIsLive(ActFlowMation actFlowMation) { + List processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(actFlowMation.getModelKey()).list(); + if (processDefinition != null) { + List deploymentIds = processDefinition.stream().map(p -> p.getDeploymentId()).collect(Collectors.toList()); + List beans = repositoryService.createModelQuery().latestVersion().orderByLastUpdateTime().desc().list(); + beans = beans.stream().filter(bean -> deploymentIds.contains(bean.getDeploymentId())).collect(Collectors.toList()); + if (beans != null && !beans.isEmpty()) { + return true; + } + } + return false; + } + + /** + * 获取指定任务节点的审批信息 + * + * @param approvedId 审批人id + * @param approvedName 审批人名字 + * @param opinion 审批意见 + * @param flag 该节点是否审批通过,true:通过,false:不通过,null: 委派/转办历史 + * @param task 任务 + * @return + */ + @Override + public List> getUpLeaveList(String approvedId, String approvedName, String opinion, Boolean flag, Task task, int type) { + Map leaveOpinion = new HashMap<>(); + // 审批人id + leaveOpinion.put("opId", approvedId); + // 审批人姓名 + leaveOpinion.put("opName", approvedName); + // 操作节点 + leaveOpinion.put("title", task.getName()); + // 审批意见 + leaveOpinion.put("opinion", opinion); + // 审批时间 + leaveOpinion.put("createTime", DateUtil.getTimeAndToString()); + leaveOpinion.put("flag", flag); + leaveOpinion.put("type", type); + // 任务id + leaveOpinion.put("taskId", task.getId()); + // 获取该任务所有的流程变量 + Object o = runtimeService.getVariable(task.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES); + List> leaveList = new ArrayList<>(); + if (o != null) { + leaveList = (List>) o; + } + leaveList.add(leaveOpinion); + return leaveList; + } + + /** + * 流程图高亮显示 + * + * @param processInstanceId + */ + @Override + public void queryProHighLighted(String processInstanceId) { + byte[] b = flowImgService.generateImageByProcInstId(processInstanceId); + ByteArrayInputStream imageStream = new ByteArrayInputStream(b); + FileOutputStream fos = null; + try { + BufferedImage bi = ImageIO.read(imageStream); + FileUtil.createDirs(tPath + "upload/activiti/"); + + File file = new File(tPath + "upload/activiti/" + processInstanceId + ".png"); + if (!file.exists()) { + file.createNewFile(); + } + fos = new FileOutputStream(file); + ImageIO.write(bi, "png", fos); + } catch (Exception ee) { + throw new CustomException(ee); + } finally { + FileUtil.close(fos); + FileUtil.close(imageStream); + } + } + + /** + * 删除模型 + * + * @param modelId 模型id + */ + @Override + public void deleteActivitiModelById(String modelId) { + try { + ModelQuery modelQuery = repositoryService.createModelQuery().modelId(modelId); + Model model = modelQuery.singleResult(); + String deploymentId = model.getDeploymentId(); + // 已发布的模型需要删除流程定义和流程发布表 + if (StrUtil.isNotBlank(deploymentId)) { + repositoryService.deleteDeployment(deploymentId); + } + // 删除流程模型表 + repositoryService.deleteModel(modelId); + } catch (Exception e) { + throw new CustomException("删除失败"); + } + } + + /** + * 取消发布 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteReleasedActivitiModelById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String deploymentId = map.get("deploymentId").toString(); + try { + repositoryService.deleteDeployment(deploymentId, true); + } catch (Exception e) { + outputObject.setreturnMessage("存在正在进行的流程,无法取消发布。"); + } + } + + /** + * 导出model的xml文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editApprovalActivitiTaskListByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String modelId = map.get("modelId").toString(); + Model modelData = repositoryService.getModel(modelId); + BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); + try { + JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); + BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode); + BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); + byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); + ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); + String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml"; + PutObject.getResponse().setHeader("REQUESTMATION", "DOWNLOAD"); + PutObject.getResponse().setHeader("Content-Disposition", "attachment;filename=" + filename); + // 1.设置文件ContentType类型,这样设置,会自动判断下载文件类型 + PutObject.getResponse().setContentType("multipart/form-data"); + BufferedOutputStream out1 = new BufferedOutputStream(PutObject.getResponse().getOutputStream()); + int len = 0; + while ((len = in.read()) != -1) { + out1.write(len); + out1.flush(); + } + } catch (IOException ee) { + throw new CustomException(ee); + } + } + + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editModelByModelId(String modelId, String modelName, String modelKey) { + Model model = repositoryService.getModel(modelId); + + if (model != null) { + model.setName(modelName); + model.setVersion(model.getVersion() + 1); + repositoryService.saveModel(model); + + try { + // 获取模型配置信息并重新设置模型key + ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(new String(repositoryService.getModelEditorSource(model.getId()), "utf-8")); + ObjectNode processProperties = (ObjectNode) editorJsonNode.get("properties"); + processProperties = getProcessProperties(modelName, modelKey, processProperties); + editorJsonNode.set("properties", processProperties); + + repositoryService.addModelEditorSource(model.getId(), editorJsonNode.toString().getBytes("utf-8")); + } catch (Exception e) { + LOGGER.error("Error get model JSON", e); + throw new FlowableException("Error get model JSON", e); + } + } + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiProcessServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiProcessServiceImpl.java new file mode 100644 index 0000000..3c3bddf --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiProcessServiceImpl.java @@ -0,0 +1,468 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.google.common.base.Joiner; +import com.skyeye.activiti.cmd.nextusertask.FindNextUserTaskNodeCmd; +import com.skyeye.activiti.cmd.rollback.RollbackCmd; +import com.skyeye.activiti.entity.NextTaskInfo; +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.activiti.service.ActivitiProcessService; +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.entity.ActGroupUser; +import com.skyeye.eve.flowable.classenum.FormSubType; +import com.skyeye.eve.flowable.entity.FlowableSubData; +import com.skyeye.eve.service.ActFlowService; +import com.skyeye.eve.service.ActGroupUserService; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.exception.CustomException; +import com.skyeye.userprocess.entity.ActUserProcess; +import com.skyeye.userprocess.service.ActUserProcessService; +import net.sf.json.JSONObject; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.UserTask; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.repository.Model; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.task.api.Task; +import org.nutz.trans.Trans; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ActivitiProcessServiceImpl + * @Description: 工作流流程相关操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 21:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActivitiProcessServiceImpl implements ActivitiProcessService { + + private static Logger LOGGER = LoggerFactory.getLogger(ActivitiProcessServiceImpl.class); + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private TaskService taskService; + + @Autowired + private ActivitiModelService activitiModelService; + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private IAuthUserService iAuthUserService; + + @Autowired + private ActivitiTaskService activitiTaskService; + + @Autowired + private ManagementService managementService; + + @Autowired + private ActFlowService actFlowService; + + @Autowired + private ActivitiService activitiService; + + @Autowired + private ActUserProcessService actUserProcessService; + + @Autowired + private ActGroupUserService actGroupUserService; + + /** + * 流程挂起 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void updateProcessToHangUp(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String processInstanceId = map.get("processInstanceId").toString(); + // 根据一个流程实例的id挂起该流程实例 + runtimeService.suspendProcessInstanceById(processInstanceId); + } + + /** + * 流程激活 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void updateProcessToActivation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String processInstanceId = map.get("processInstanceId").toString(); + // 根据一个流程实例的id激活该流程实例 + runtimeService.activateProcessInstanceById(processInstanceId); + } + + /** + * 流程撤回(撤回审批过的流程) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editProcessInstanceWithDraw(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + String processInstanceId = map.get("processInstanceId").toString(); + String hisTaskId = map.get("hisTaskId").toString(); + // 根据流程id查询代办任务中流程信息 + Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); + if (task == null) { + outputObject.setreturnMessage("流程未启动或已执行完成,无法撤回"); + return; + } + // 撤回 + managementService.executeCommand(new RollbackCmd(hisTaskId, userId)); + // 绘制图像 + activitiModelService.queryProHighLighted(processInstanceId); + } + + /** + * 刷新流程图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editProcessInstancePicToRefresh(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 绘制图像 + activitiModelService.queryProHighLighted(map.get("processInstanceId").toString()); + } + + /** + * 获取流程下一个节点的审批人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void nextPrcessApprover(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String taskId = params.get("taskId").toString(); + String processInstanceId = params.get("processInstanceId").toString(); + // 获取表单数据用于排他网关的参数校验 + Map map = getFormVariable(processInstanceId, params); + NextTaskInfo nextTaskInfo = this.getNextTaskInfo(taskId, map); + if (nextTaskInfo != null && nextTaskInfo.getUserTask() != null) { + // 1.获取下个节点的所有可选审批人 + List> user = this.getNextTaskApprove(nextTaskInfo.getUserTask()); + outputObject.setBeans(user); + // 2.获取节点信息 + Map nodeMation = new HashMap<>(); + nodeMation.put("nodeName", nextTaskInfo.getUserTask().getName()); + nodeMation.put("nodeType", ActivitiConstants.USER_TASK); + outputObject.setBean(nodeMation); + } + } + + /** + * 获取表单数据用于排他网关的参数校验 + * + * @param processInstanceId 流程id + * @param inputParams 入参 + * @return + */ + private Map getFormVariable(String processInstanceId, Map inputParams) { + Map variable = new HashMap<>(); + Map params = activitiTaskService.getCurrentTaskParamsByTaskId(processInstanceId); + for (String key : params.keySet()) { + if (params.get(key) == null) { + continue; + } + String str = params.get(key).toString(); + if (ToolUtil.isJson(str)) { + Map formItemMation = JSONObject.fromObject(str); + variable.put(key, formItemMation.containsKey("value") ? formItemMation.get("value") : StringUtils.EMPTY); + } + } + // 审批结果 + if (!ToolUtil.isBlank(inputParams.get("flag").toString())) { + variable.put("flag", inputParams.get("flag")); + } + return variable; + } + + private List> getNextTaskApprove(UserTask userTask) { + List> user = new ArrayList<>(); + // 1.候选组人员获取 + List groupIds = userTask.getCandidateGroups(); + if (CollectionUtils.isNotEmpty(groupIds)) { + List actGroupUserList = actGroupUserService.queryActGroupUser(groupIds); + actGroupUserList.forEach(bean -> { + user.add(bean.getUserMation()); + }); + } + // 2.候选人员获取 + List userIds = userTask.getCandidateUsers(); + if (CollectionUtils.isNotEmpty(userIds)) { + userIds.forEach(userId -> { + Map userMation = iAuthUserService.queryDataMationById(userId); + user.add(userMation); + }); + } + // 3.代理人获取 + String assignee = userTask.getAssignee(); + if (assignee != null) { + Map userMation = iAuthUserService.queryDataMationById(assignee); + user.add(userMation); + } + user.removeAll(Collections.singleton(null)); + return user; + } + + /** + * 获取下一个用户任务信息 + * + * @param taskId 任务Id信息 + * @param map 表单数据 + * @return 下一个用户任务用户组信息 + */ + @Override + public NextTaskInfo getNextTaskInfo(String taskId, Map map) { + try { + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + if (StringUtils.isNotEmpty(task.getParentTaskId())) { + // 如果是加签节点 + task = getRealTask(task); + } + String executionId = task.getExecutionId(); + if (StringUtils.isNotEmpty(executionId)) { + ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(executionId).singleResult(); + BpmnModel bpmnModel = repositoryService.getBpmnModel(execution.getProcessDefinitionId()); + Trans.begin(); + NextTaskInfo nextTaskInfo = new NextTaskInfo(); + nextTaskInfo.setUserTask(managementService.executeCommand(new FindNextUserTaskNodeCmd(execution, bpmnModel, map))); + return nextTaskInfo; + } + } catch (Exception ee) { + LOGGER.warn("getNextTaskInfo error, because {}", ee); + } finally { + Trans.clear(true); + } + return null; + } + + private Task getRealTask(Task task) { + String parentTaskId = task.getParentTaskId(); + long subTaskCount = activitiTaskService.getSubTaskCount(parentTaskId); + if ((subTaskCount - 1) == 0) { + // 说明是最后一个后加签子任务 + Task parentTask = taskService.createTaskQuery().taskId(parentTaskId).singleResult(); + if (ActivitiConstants.AFTER_ADDSIGN.equals(parentTask.getScopeType())) { + return parentTask; + } + } + return task; + } + + /** + * 启动流程时获取流程下一个用户节点的审批人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void nextPrcessApproverByProcessDefinitionKey(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String actKey = params.get("actKey").toString(); + // 获取业务数据 + String businessDataStr = params.get("businessData").toString(); + Map businessData = null; + if (!ToolUtil.isBlank(businessDataStr)) { + businessData = JSONObject.fromObject(businessDataStr); + } + ActFlowMation actFlowMation = actFlowService.getActFlow(actKey); + if (actFlowMation == null) { + outputObject.setreturnMessage("流程不存在或未启动."); + return; + } + List> user = this.nextPrcessApproverByProcessDefinitionKey(actFlowMation.getModelKey()); + outputObject.setBeans(user); + } + + public List> nextPrcessApproverByProcessDefinitionKey(String processDefinitionKey) { + List> user = new ArrayList<>(); + List processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey).list(); + if (processDefinition != null) { + List beans = repositoryService.createModelQuery().latestVersion().orderByLastUpdateTime().desc().list(); + List deploymentIds = beans.stream().map(p -> p.getDeploymentId()).collect(Collectors.toList()); + processDefinition = processDefinition.stream().filter(bean -> deploymentIds.contains(bean.getDeploymentId())).collect(Collectors.toList()); + if (processDefinition != null && !processDefinition.isEmpty()) { + user = getUserTaskList(processDefinition.get(0)); + } + } + return user; + } + + public List> getUserTaskList(ProcessDefinition processDefinition) { + String deploymentId = processDefinition.getDeploymentId(); + // 实现读写bpmn文件信息 + InputStream bpmnIs = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName()); + SAXReader saxReader = new SAXReader(); + // 获取流程图文件中的userTask节点的所有属性 + Document document = null; + try { + document = saxReader.read(bpmnIs); + } catch (DocumentException ee) { + throw new CustomException(ee); + } + Element rootElement = document.getRootElement(); + Element process = rootElement.element("process"); + List userTaskList = process.elements("userTask"); + + List> list = new ArrayList<>(); + // 获取第一个用户任务节点 + if (CollectionUtil.isNotEmpty(userTaskList)) { + Element element = userTaskList.get(0); + String assignee = element.attributeValue(ActivitiConstants.ASSIGNEE_USER); + String candidateUsers = element.attributeValue("candidateUsers"); + String candidateGroups = element.attributeValue("candidateGroups"); + + if (!ToolUtil.isBlank(candidateGroups)) { + List actGroupUserList = actGroupUserService.queryActGroupUser(Arrays.asList(candidateGroups.split(CommonCharConstants.COMMA_MARK))); + actGroupUserList.forEach(bean -> { + list.add(bean.getUserMation()); + }); + } + // 2.候选人员获取 + if (!ToolUtil.isBlank(candidateUsers)) { + Arrays.asList(candidateUsers.split(CommonCharConstants.COMMA_MARK)).forEach(userId -> { + Map userMation = iAuthUserService.queryDataMationById(userId); + list.add(userMation); + }); + } + // 3.代理人获取 + if (!ToolUtil.isBlank(assignee)) { + Map userMation = iAuthUserService.queryDataMationById(assignee); + list.add(userMation); + } + } + // 使用 Stream API 进行过滤、排序并最终收集到 ArrayList 中 + List> resultList = list.stream() + .filter(Objects::nonNull) // 确保 item 不是 null + .map(item -> item.entrySet().stream() + .filter(entry -> entry != null && entry.getKey() != null && + entry.getValue() != null && !"".equals(entry.getValue())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (existing, replacement) -> existing, // 解决重复键的问题 + LinkedHashMap::new)) // 保持插入顺序 + ) + .filter(Objects::nonNull) // 确保转换后的 map 不是 null + .sorted(Comparator.comparing(p -> String.valueOf(p.get("id")), Comparator.nullsLast(Comparator.naturalOrder()))) + .collect(Collectors.collectingAndThen( + Collectors.toCollection(ArrayList::new), + ArrayList::new + )); + return resultList; + } + + /** + * 启动流程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void startProcess(InputObject inputObject, OutputObject outputObject) { + FlowableSubData flowableSubData = inputObject.getParams(FlowableSubData.class); + Integer formSubType = flowableSubData.getFormSubType(); + if (!formSubType.equals(FormSubType.SUB_FLOWABLE.getKey())) { + return; + } + // 根据业务数据和className获取配置的工作流key,如果actModel没有配置,则无法提交审批 + ActFlowMation actFlowMation = actFlowService.getActFlow(flowableSubData.getObjectKey()); + if (actFlowMation != null) { + LOGGER.info("actFlow mation is: " + JSONUtil.toJsonStr(actFlowMation)); + // 提交审批 + String processInstanceId = activitiModelService.startProcess(flowableSubData, actFlowMation); + Map result = new HashMap<>(); + result.put("processInstanceId", processInstanceId); + outputObject.setBean(result); + } else { + throw new CustomException("该功能暂未配置工作流,请联系管理员进行配置。"); + } + } + + /** + * 撤销流程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void revokeProcess(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String processInstanceId = params.get("processInstanceId").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + activitiService.revokeByProcessInstanceId(processInstanceId, userId); + } + + /** + * 根据流程实例id获取流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryProcessInstance(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String processInstanceId = params.get("processInstanceId").toString(); + // 获取流程信息 + ActUserProcess userProcess = actUserProcessService.selectByProcessInstanceId(processInstanceId); + + // 任务信息 + Map task = new HashMap<>(); + // 任务-当前审批人 + List assignee = activitiTaskService.getTaskAssignee(processInstanceId); + task.put("taskCurrentAssignee", assignee); + if (CollectionUtil.isNotEmpty(assignee)) { + task.put("taskCurrentAssigneeMation", iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(assignee))); + } + userProcess.setTask(task); + + outputObject.setBean(userProcess); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiService.java new file mode 100644 index 0000000..ab03dd7 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiService.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.util.FileUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.userprocess.entity.ActUserProcess; +import com.skyeye.userprocess.service.ActUserProcessService; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.task.api.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * 流程撤回所需工具类 + * + * @author 卫志强 + */ +@Component +public class ActivitiService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private HistoryService historyService; + + @Autowired + private TaskService taskService; + + @Autowired + private ActUserProcessService actUserProcessService; + + /** + * 撤销已经申请的流程 + * + * @param processInstanceId + * @param userId + */ + public void revokeByProcessInstanceId(String processInstanceId, String userId) { + ActUserProcess userProcess = actUserProcessService.selectByProcessInstanceId(processInstanceId); + if (ObjectUtil.isEmpty(userProcess)) { + throw new CustomException("流程信息不存在."); + } + Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); + if (task == null) { + throw new CustomException("该流程未启动或者已结束."); + } + String deleteFilePath = String.format("%supload/activiti/%s.png", tPath, processInstanceId); + FileUtil.deleteFile(deleteFilePath); + Object o = runtimeService.getVariable(processInstanceId, ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES); + boolean edit = true; + if (o != null) { + //获取历史审核信息 + List> leaveList = (List>) o; + for (Map leave : leaveList) { + if (!userId.equals(leave.get("opId").toString())) { + edit = false;//不可编辑 + break; + } + } + } + if (!edit) { + throw new CustomException("流程已有审批,不能撤回."); + } + // 可以编辑 + runtimeService.deleteProcessInstance(processInstanceId, "用户撤销"); + // 删除流程历史信息 + historyService.deleteHistoricProcessInstance(processInstanceId); + // 删除数据库流程信息 + actUserProcessService.deleteByProcessInstanceId(processInstanceId); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java new file mode 100644 index 0000000..0d3abf4 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java @@ -0,0 +1,985 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.activiti.classenum.ProcessInstanceWeatherEnd; +import com.skyeye.activiti.cmd.multiinstanceexecution.*; +import com.skyeye.activiti.entity.NextTaskInfo; +import com.skyeye.activiti.mapper.FlowableTaskDao; +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.activiti.service.ActivitiProcessService; +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.exception.CustomException; +import com.skyeye.userprocess.dao.ActUserProcessDao; +import com.skyeye.userprocess.entity.ActUserProcess; +import com.skyeye.userprocess.service.ActUserProcessService; +import net.sf.json.JSONArray; +import org.apache.commons.lang.StringUtils; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.UserTask; +import org.flowable.engine.*; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.engine.history.HistoricProcessInstanceQuery; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.DelegationState; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.api.history.HistoricTaskInstanceQuery; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl; +import org.flowable.variable.api.history.HistoricVariableInstance; +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 java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ActivitiTaskServiceImpl + * @Description: 工作流用户任务相关 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActivitiTaskServiceImpl implements ActivitiTaskService { + + private static Logger LOGGER = LoggerFactory.getLogger(ActivitiTaskServiceImpl.class); + + @Autowired + private TaskService taskService; + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private ActUserProcessDao actUserProcessInstanceIdDao; + + @Autowired + private HistoryService historyService; + + @Autowired + private ActivitiModelService activitiModelService; + + @Autowired + protected RepositoryService repositoryService; + + @Autowired + private IAuthUserService iAuthUserService; + + @Autowired + protected ManagementService managementService; + + @Autowired + private FlowableTaskDao flowableTaskDao; + + @Autowired + private ActivitiProcessService activitiProcessService; + + @Autowired + private ActUserProcessService actUserProcessService; + + /** + * 获取用户待办任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserAgencyTasksListByUserId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + queryAgencyTask(outputObject, pageInfo); + } + + private void queryAgencyTask(OutputObject outputObject, CommonPageInfo pageInfo) { + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = flowableTaskDao.getApplyingTasks(pageInfo); + if (CollectionUtil.isEmpty(beans)) { + return; + } + List processInstanceIds = beans.stream() + .map(bean -> bean.get("processInstanceId").toString()).distinct().collect(Collectors.toList()); + // 获取流程创建信息 + Map actUserProcessMap = actUserProcessService.selectByProcessInstanceId(processInstanceIds); + // 获取运行中的流程信息 + Set processInstanceIdsSet = new HashSet<>(processInstanceIds); + List processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdsSet).list(); + Map processInstanceMap = processInstanceList.stream() + .collect(Collectors.toMap(ProcessInstance::getProcessInstanceId, bean -> bean)); + List runProcessInstanceIds = processInstanceList.stream().map(ProcessInstance::getProcessInstanceId).collect(Collectors.toList()); + // 获取运行中的任务 + Map> taskMap = null; + if (CollectionUtil.isNotEmpty(runProcessInstanceIds)) { + List tasks = taskService.createTaskQuery().processInstanceIdIn(runProcessInstanceIds).list(); + taskMap = tasks.stream().filter(bean -> StrUtil.isNotEmpty(bean.getAssignee())) + .collect(Collectors.groupingBy(Task::getProcessInstanceId)); + } + + for (Map task : beans) { + String processInstanceId = task.get("processInstanceId").toString(); + + ActUserProcess userProcess = actUserProcessMap.get(processInstanceId); + task.put("processMation", userProcess); + + if (processInstanceMap.containsKey(processInstanceId)) { + task.put("suspended", processInstanceMap.get(processInstanceId).isSuspended()); + } + + if (CollectionUtil.isNotEmpty(taskMap) && CollectionUtil.isNotEmpty(taskMap.get(processInstanceId))) { + List assigneeList = taskMap.get(processInstanceId).stream().map(Task::getAssignee).collect(Collectors.toList()); + List> assigneeUser = iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(assigneeList)); + task.put("assigneeList", assigneeUser); + } + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取我启动的流程 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStartProcessNotSubByUserId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = actUserProcessInstanceIdDao.queryStartProcessNotSubByUserId(pageInfo); + if (CollectionUtil.isEmpty(beans)) { + return; + } + List processInstanceIds = beans.stream() + .map(bean -> bean.get("processInstanceId").toString()).collect(Collectors.toList()); + // 获取流程创建信息 + Map actUserProcessMap = actUserProcessService.selectByProcessInstanceId(processInstanceIds); + // 获取运行中的流程信息 + Set processInstanceIdsSet = new HashSet<>(processInstanceIds); + List processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdsSet).list(); + List runProcessInstanceIds = processInstanceList.stream().map(ProcessInstance::getProcessInstanceId).collect(Collectors.toList()); + Map processInstanceMap = processInstanceList.stream() + .collect(Collectors.toMap(ProcessInstance::getProcessInstanceId, bean -> bean)); + // 获取运行中的任务 + Map> taskMap = null; + if (CollectionUtil.isNotEmpty(runProcessInstanceIds)) { + List tasks = taskService.createTaskQuery().processInstanceIdIn(runProcessInstanceIds).list(); + taskMap = tasks.stream().filter(bean -> StrUtil.isNotEmpty(bean.getAssignee())) + .collect(Collectors.groupingBy(Task::getProcessInstanceId)); + } + + for (Map bean : beans) { + String processInstanceId = bean.get("processInstanceId").toString(); + ActUserProcess userProcess = actUserProcessMap.get(processInstanceId); + bean.put("processMation", userProcess); + bean.put("weatherEnd", ProcessInstanceWeatherEnd.ENDED.getKey()); + + if (runProcessInstanceIds.contains(processInstanceId)) { + bean.put("weatherEnd", ProcessInstanceWeatherEnd.NOT_FINISHED.getKey()); + } + + if (processInstanceMap.containsKey(processInstanceId)) { + bean.put("suspended", processInstanceMap.get(processInstanceId).isSuspended()); + } + + if (CollectionUtil.isNotEmpty(taskMap) && CollectionUtil.isNotEmpty(taskMap.get(processInstanceId))) { + List assigneeList = taskMap.get(processInstanceId).stream().map(Task::getAssignee).collect(Collectors.toList()); + List> assigneeUser = iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(assigneeList)); + bean.put("assigneeList", assigneeUser); + } + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取我的历史任务--历史表中存在并非是单一类型的数据,就拿历史任务表来说,里边既有已经结束的任务,也有还没有结束的任务。 + * 如果要单独查询结束了的任务,就可以调用finished()方法,查询的就是已经结束的任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyHistoryTaskByUserId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + // 构造查询条件 + HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId); + if (StrUtil.isNotEmpty(pageInfo.getKeyword())) { + query = query.processInstanceId(pageInfo.getKeyword()); + } + // 获取我的已办历史 + List hisTaskList = query.orderByTaskCreateTime().desc() + .finished().listPage((pageInfo.getPage() - 1) * pageInfo.getLimit(), pageInfo.getLimit()); + if (CollectionUtil.isEmpty(hisTaskList)) { + return; + } + List processInstanceIds = hisTaskList.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toList()); + + // 获取流程创建信息 + Map actUserProcessMap = actUserProcessService.selectByProcessInstanceId(processInstanceIds); + // 获取运行中的流程信息 + Set processInstanceIdsSet = new HashSet<>(processInstanceIds); + List processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdsSet).list(); + List runProcessInstanceIds = processInstanceList.stream().map(ProcessInstance::getProcessInstanceId).collect(Collectors.toList()); + // 获取运行中的任务 + Map> taskMap = null; + if (CollectionUtil.isNotEmpty(runProcessInstanceIds)) { + List tasks = taskService.createTaskQuery().processInstanceIdIn(runProcessInstanceIds).list(); + taskMap = tasks.stream().filter(bean -> StrUtil.isNotEmpty(bean.getAssignee())) + .collect(Collectors.groupingBy(Task::getProcessInstanceId)); + } + + List> beans = new ArrayList<>(); + for (HistoricTaskInstance hisTask : hisTaskList) { + Map hisModel = new HashMap<>(); + hisModel.put("hisTask", hisTask); + hisModel.put("weatherEnd", ProcessInstanceWeatherEnd.ENDED.getKey()); + + ActUserProcess userProcess = actUserProcessMap.get(hisTask.getProcessInstanceId()); + hisModel.put("processMation", userProcess); + + if (runProcessInstanceIds.contains(hisTask.getProcessInstanceId())) { + hisModel.put("weatherEnd", ProcessInstanceWeatherEnd.NOT_FINISHED.getKey()); + } + if (CollectionUtil.isNotEmpty(taskMap) && CollectionUtil.isNotEmpty(taskMap.get(hisTask.getProcessInstanceId()))) { + List assigneeList = taskMap.get(hisTask.getProcessInstanceId()).stream().map(Task::getAssignee).collect(Collectors.toList()); + List> assigneeUser = iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(assigneeList)); + hisModel.put("assigneeList", assigneeUser); + } + beans.add(hisModel); + } + outputObject.setBeans(beans); + outputObject.settotal(query.count()); + } + + /** + * 获取历史审批列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryApprovalTasksHistoryByProcessInstanceId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String processInstanceId = map.get("processInstanceId").toString(); + ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + // 保证运行ing + List> leaveList = null; + if (instance != null) { + Object o = runtimeService.getVariable(processInstanceId, ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES); + if (o != null) { + /* 获取历史审核信息 */ + leaveList = (List>) o; + } + } else { + leaveList = new ArrayList<>(); + List list = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list(); + for (HistoricVariableInstance historicDetail : list) { + if (ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES.equals(historicDetail.getVariableName())) { + leaveList.clear(); + leaveList.addAll((List>) historicDetail.getValue()); + } + } + } + if (leaveList == null) { + leaveList = new ArrayList<>(); + } + //根据时间排序 + Collections.sort(leaveList, new Comparator>() { + @Override + public int compare(Map p1, Map p2) { + String a = p1.get("createTime").toString(); + String b = p2.get("createTime").toString(); + if (DateUtil.compare(a, b)) { + return 1; + } + return -1; + } + }); + for (Map leave : leaveList) { + leave.put("flagName", (boolean) leave.get("flag") ? "通过" : "拒绝"); + leave.put("opinion", ToolUtil.isBlank(leave.get("opinion").toString()) ? "暂无审批意见" : leave.get("opinion").toString()); + } + outputObject.setBeans(leaveList); + outputObject.settotal(leaveList.size()); + } + + /** + * 获取所有已完成的流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllComplateProcessList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + // 构造查询条件 + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + if (StrUtil.isNotEmpty(pageInfo.getKeyword())) { + query = query.processInstanceId(pageInfo.getKeyword()); + } + // 获取我的已办历史 + List processInstances = query.orderByProcessInstanceEndTime().desc() + .finished().listPage((pageInfo.getPage() - 1) * pageInfo.getLimit(), pageInfo.getLimit()); + if (CollectionUtil.isEmpty(processInstances)) { + return; + } + List processInstanceIds = processInstances.stream().map(HistoricProcessInstance::getId).collect(Collectors.toList()); + // 获取流程创建信息 + Map actUserProcessMap = actUserProcessService.selectByProcessInstanceId(processInstanceIds); + + List> beans = new ArrayList<>(); + for (HistoricProcessInstance bean : processInstances) { + Map hisModel = new HashMap<>(); + hisModel.put("historicProcessInstance", bean); + + ActUserProcess userProcess = actUserProcessMap.get(bean.getId()); + hisModel.put("processMation", userProcess); + beans.add(hisModel); + } + outputObject.setBeans(beans); + outputObject.settotal(query.count()); + } + + /** + * 获取所有待办的流程信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllConductProcessList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + queryAgencyTask(outputObject, pageInfo); + } + + /** + * 根据taskId获取表单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySubFormMationByTaskId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String taskId = map.get("taskId").toString(); + String processInstanceId = map.get("processInstanceId").toString(); + // 获取任务自定义id和名称 + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + map.put("taskKey", task.getTaskDefinitionKey()); + map.put("taskKeyName", task.getName()); + // 是否委派,如果是委派,则不需要选择下一个节点的审批人 + map.put("delegation", task.getDelegationState() != null && DelegationState.PENDING == task.getDelegationState()); + // 是否是多实例 + Boolean isMultiInstance = isMultiInstance(task.getId(), map); + map.put("isMultiInstance", isMultiInstance); + // 获取提交时候的信息 + Map variable = getCurrentTaskParamsByTaskId(processInstanceId); + if (!isMultiInstance) { + // 因为获取下一个节点可能会遇到网关节点,所以默认设置审批结果为true + variable.put("flag", 1); + NextTaskInfo nextTaskInfo = activitiProcessService.getNextTaskInfo(taskId, variable); + if (nextTaskInfo != null && nextTaskInfo.getUserTask() != null) { + map.put("nextTask", true); + } + } + // 获取流程关联页面类型 + ActUserProcess userProcess = actUserProcessService.selectByProcessInstanceId(processInstanceId); + map.put("pageTypes", userProcess.getPageTypes()); + map.put("title", userProcess.getTitle()); + + List> beans = getParamsToDSFormShow(variable); + outputObject.setBean(map); + outputObject.setBeans(beans); + } + + @Override + public List getTaskAssignee(String processInstanceId) { + List tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list(); + if (CollectionUtil.isEmpty(tasks)) { + return CollectionUtil.newArrayList(); + } + return tasks.stream().filter(bean -> StrUtil.isNotEmpty(bean.getAssignee())) + .map(Task::getAssignee).distinct().collect(Collectors.toList()); + } + + /** + * 获取当前任务节点填写的表单数据 + * + * @param processInstanceId 流程id + * @return 当前任务节点填写的表单数据 + */ + @Override + public Map getCurrentTaskParamsByTaskId(String processInstanceId) { + Map variable = (Map) runtimeService.getVariable(processInstanceId, + ActivitiConstants.PROCESSINSTANCEID_TASK_VARABLES); + return variable == null ? new HashMap<>() : variable; + } + + /** + * 将工作流数据转为form表单类型的数据并作展示 + * + * @return + */ + private List> getParamsToDSFormShow(Map params) { + List> beans = new ArrayList<>(); + // 遍历数据存入list集合 + for (String key : params.keySet()) { + if (params.get(key) == null) { + continue; + } + String str = params.get(key).toString(); + if (ToolUtil.isJson(str)) { + beans.add((Map) params.get(key)); + } + } + // 升序排序 + beans = beans.stream() + .sorted(Comparator.comparing(bean -> Integer.parseInt(bean.get("orderBy").toString()))).collect(Collectors.toList()); + return beans; + } + + /** + * 提交审批结果 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editActivitiModelToRun(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String processInstanceId = map.get("processInstanceId").toString(); + ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + // 是否挂起 + if (instance.isSuspended()) { + outputObject.setreturnMessage("该流程已被挂起,无法操作。"); + return; + } + Map user = inputObject.getLogParams(); + String taskId = map.get("taskId").toString();//当前任务节点 + TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult(); + if (taskEntity != null) { + // 是否委派 + boolean delegation = taskEntity.getDelegationState() != null && DelegationState.PENDING == taskEntity.getDelegationState(); + // 获取审批结果 + boolean flag = getApprovedResult(map.get("flag").toString()); + // 处理加签父任务 + String parentTaskId = taskEntity.getParentTaskId(); + Task task; + if (StringUtils.isNotBlank(parentTaskId)) { + task = taskService.createTaskQuery().taskId(parentTaskId).singleResult(); + } else { + task = taskService.createTaskQuery().taskId(taskId).singleResult(); + } + if (delegation) { + // 完成任务委托 + Map bean = new HashMap<>(); + String opinion = String.format(Locale.ROOT, "【委派审批建议】:%s", map.get("opinion").toString()); + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), opinion, flag, task, ActivitiConstants.LeaveType.TASK_DELEGATE_RESULT.getType()); + runtimeService.setVariable(processInstanceId, ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + taskService.resolveTask(taskId, bean); + } else { + // 多实例会签任务处理 + boolean pendingType = handleMultiInstance(taskId, user, flag, map.get("opinion").toString()); + if (pendingType) { + // 审批结果设定 + approvalResult(map, processInstanceId, user, taskId, task, flag); + } + // 处理加签父任务 + handleSignTask(taskEntity, map.get("approverId").toString(), processInstanceId); + } + } else { + outputObject.setreturnMessage("没有此任务,请确认!"); + } + } + + private boolean handleMultiInstance(String taskId, Map user, boolean flag, String opinion) { + return managementService.executeCommand(new HandlerMultiInstanceExecutionCmd(taskId, user, flag, opinion)); + } + + private void handleSignTask(TaskEntity taskEntity, String approverId, String processInstanceId) { + String parentTaskId = taskEntity.getParentTaskId(); + if (StringUtils.isNotBlank(parentTaskId)) { + long subTaskCount = getSubTaskCount(parentTaskId); + if (subTaskCount == 0) { + Task task = taskService.createTaskQuery().taskId(parentTaskId).singleResult(); + // 处理前后加签的任务 + taskService.resolveTask(parentTaskId); + if (ActivitiConstants.AFTER_ADDSIGN.equals(task.getScopeType())) { + // 如果是后加签,完成父任务 + taskService.complete(parentTaskId); + // 绘制图像 + activitiModelService.queryProHighLighted(processInstanceId); + // 设置下个节点的审批人 + setNextUserTaskApproval(processInstanceId, approverId); + } + } + } + } + + @Override + public long getSubTaskCount(String parentTaskId) { + String tableName = managementService.getTableName(TaskEntity.class); + String sql = "select count(1) from " + tableName + " where PARENT_TASK_ID_ = #{parentTaskId}"; + long subTaskCount = + taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count(); + return subTaskCount; + } + + private void approvalResult(Map map, String processInstanceId, Map user, + String taskId, Task task, boolean flag) { + // 判断节点是否已经拒绝过一次了 + Map bean = setWhetherNeedEnd(taskId, flag); + // 获取指定任务节点的审批信息 + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), map.get("opinion").toString(), flag, task, ActivitiConstants.LeaveType.APPROVAL_COMMENTS.getType()); + runtimeService.setVariable(processInstanceId, ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + // 校验参数 + bean.put("flag", map.get("flag")); + taskService.complete(taskId, bean); + LOGGER.info("complete success, processInstanceId is {}.", processInstanceId); + // 绘制图像 + activitiModelService.queryProHighLighted(processInstanceId); + + executeParentTask(processInstanceId, task, user.get("id").toString()); + + // 设置下个节点的审批人 + setNextUserTaskApproval(processInstanceId, map.get("approverId").toString()); + } + + private void executeParentTask(String processInstanceId, Task task, String userId) { + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + org.flowable.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + UserTask userTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + Object behavior = userTask.getBehavior(); + if (behavior instanceof ParallelMultiInstanceBehavior) { + // 并行会签 + } else if (behavior instanceof SequentialMultiInstanceBehavior) { + // 串行会签,判断完成会签任务后,是否还有从属任务,如果有,则一起完成 + Task currentTask = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult(); + if (ObjectUtil.isNotEmpty(currentTask)) { + taskService.setAssignee(currentTask.getId(), userId); + taskService.complete(currentTask.getId()); + // 绘制图像 + activitiModelService.queryProHighLighted(processInstanceId); + } + } + } + + @Override + public void setNextUserTaskApproval(String processInstanceId, String approverId) { + if (!ToolUtil.isBlank(approverId)) { + Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult(); + LOGGER.info("set processInstanceId: " + processInstanceId + ", taskId: " + task.getId() + ", approverId is: " + approverId); + taskService.setAssignee(task.getId(), approverId); + } + } + + /** + * 获取审批人的审批结果,并转成boolean类型 + * + * @param flag 审批结果 + * @return + */ + private boolean getApprovedResult(String flag) { + // 是否通过 + if ("1".equals(flag)) { + // 通过 + return true; + } else if ("2".equals(flag)) { + // 不通过 + return false; + } else { + throw new CustomException("approve result 'flag' value is wrong"); + } + } + + /** + * 判断节点是否已经拒绝过一次了,如果是,则结束流程 + * + * @param taskId + * @param flag + */ + private Map setWhetherNeedEnd(String taskId, boolean flag) { + Map bean = new HashMap<>(); + Map variables = taskService.getVariables(taskId); + // 判断节点是否已经拒绝过一次了 + Object needend = variables.get("needend"); + if (needend != null && (boolean) needend && (!flag)) { + // 结束 + bean.put("needfinish", -1); + } else { + if (flag) { + // 审批通过,则下一个节点 + bean.put("needfinish", 1); + } else { + // 审批不通过 + bean.put("needfinish", 0); + } + } + return bean; + } + + @Override + public UserTask getCurrentUserTaskByTaskId(String taskId) { + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + + org.flowable.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + // 当前节点 + UserTask currentUserTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + return currentUserTask; + } + + @Override + public boolean isMultiInstance(String taskId, Map map) { + UserTask currentTaskNode = this.getCurrentUserTaskByTaskId(taskId); + // 1.判断工作流模型中的这个节点是否是会签节点 + if (currentTaskNode.getLoopCharacteristics() != null) { + Map result = managementService.executeCommand(new GetMultiInstanceExecutionMation(taskId)); + map.putAll(result); + return true; + } + return false; + } + + /** + * 委派 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void delegateTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 任务id + String taskId = map.get("taskId").toString(); + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + if (task != null) { + // 被委托人id + String principalUserId = map.get("principalUserId").toString(); + Map principalUser = iAuthUserService.queryDataMationById(principalUserId); + // 1.添加审批意见 + String opinion = String.format(Locale.ROOT, "【委派】任务委派给【%s_%s】", principalUser.get("jobNumber").toString(), + principalUser.get("userName").toString()); + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), opinion, true, task, ActivitiConstants.LeaveType.TASK_DELEGATE.getType()); + runtimeService.setVariable(task.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + // 2.设置委派人 + taskService.delegateTask(taskId, principalUserId); + } else { + outputObject.setreturnMessage("没有运行时的任务实例,请确认!"); + } + } + + /** + * 转办 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void transferTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 任务id + String taskId = map.get("taskId").toString(); + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + if (task != null) { + // 被转办人id + String transferredPersonId = map.get("transferredPersonId").toString(); + Map transferredPersonUser = iAuthUserService.queryDataMationById(transferredPersonId); + // 1.添加审批意见 + String opinion = String.format(Locale.ROOT, "【转办】任务转派给【%s_%s】", transferredPersonUser.get("jobNumber").toString(), + transferredPersonUser.get("userName").toString()); + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), opinion, true, task, ActivitiConstants.LeaveType.TASK_TRANSFER.getType()); + runtimeService.setVariable(task.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + // 2.设置转派人 + taskService.setAssignee(taskId, transferredPersonId); + } else { + outputObject.setreturnMessage("没有运行时的任务实例,请确认!"); + } + } + + /** + * 前加签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void beforeAddSignTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 任务id + String taskId = map.get("taskId").toString(); + this.addSignTask(taskId, user, false, map.get("chooseUserMation").toString(), outputObject); + } + + /** + * 后加签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void afterAddSignTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 任务id + String taskId = map.get("taskId").toString(); + this.addSignTask(taskId, user, true, map.get("chooseUserMation").toString(), outputObject); + } + + /** + * 获取会签节点的数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void jointlySignTaskDetail(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String taskId = map.get("taskId").toString(); + UserTask currentTaskNode = this.getCurrentUserTaskByTaskId(taskId); + Map result = new HashMap<>(); + // 多实例节点 + if (currentTaskNode.getLoopCharacteristics() != null) { + // true:串行多实例节点,false:并行多实例节点 + Boolean isSequential = currentTaskNode.getLoopCharacteristics().isSequential(); + result.put("isSequential", isSequential); + List> assigneeList = managementService.executeCommand(new FindMultiInstanceExecutionUserCmd(taskId, isSequential)); + result.put("assigneeList", assigneeList); + } + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 会签加减签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void jointlySignAddSignTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 任务id + String taskId = map.get("taskId").toString(); + List> addSignUser = JSONArray.fromObject(map.get("chooseUserMation").toString()); + // 1.获取回显的没有修改过的数据(同时过滤掉不能删除的数据) + List> echoList = addSignUser.stream() + .filter(bean -> (bean.containsKey("noDelete") && !(Boolean) bean.get("noDelete")) || !bean.containsKey("noDelete")) + .filter(bean -> bean.containsKey("echo") && !(Boolean) bean.get("echo")).collect(Collectors.toList()); + List echoUserIds = echoList.stream().map(p -> p.get("id").toString()).collect(Collectors.toList()); + // 2.获取新增的数据 + List> newAddList = addSignUser.stream() + .filter(bean -> !bean.containsKey("echo")).collect(Collectors.toList()); + // 3.获取现有的会签人 + UserTask currentTaskNode = this.getCurrentUserTaskByTaskId(taskId); + List> assigneeList = managementService.executeCommand( + new FindMultiInstanceExecutionUserCmd(taskId, currentTaskNode.getLoopCharacteristics().isSequential())); + // 3.1过滤掉不能删除的对象 + assigneeList = assigneeList.stream().filter( + bean -> (bean.containsKey("noDelete") && !(Boolean) bean.get("noDelete")) || !bean.containsKey("noDelete")) + .collect(Collectors.toList()); + // 4.获取被删掉的会签人(现有的会签人-回显的没有修改过的数据) + List> newDeleteList = assigneeList.stream() + .filter(item -> !echoUserIds.contains(item.get("id").toString())).collect(Collectors.toList()); + + String opinion = "【会签】:
"; + // 删除会签人 + List newDeleteUserIds = newDeleteList.stream().map(p -> p.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(newDeleteUserIds)) { + managementService.executeCommand(new DeleteMultiInstanceExecutionCmd(taskId, newDeleteUserIds)); + opinion += "删除了"; + for (Map bean : newDeleteList) { + opinion += String.format(Locale.ROOT, "【%s】", bean.get("name").toString()); + } + opinion += "的会签。
"; + } + + // 新增会签人 + List newAddUserIds = newAddList.stream().map(p -> p.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(newAddUserIds)) { + managementService.executeCommand(new AddMultiInstanceExecutionCmd(taskId, newAddList, addSignUser)); + managementService.executeCommand(new NewMultiInstanceExecutionSetAssignee(taskId, newAddUserIds)); + opinion += "新增了"; + for (Map bean : newAddList) { + opinion += String.format(Locale.ROOT, "【%s】", bean.get("name").toString()); + ; + } + opinion += "的会签。"; + } + + // 添加加签操作历史 + Map user = inputObject.getLogParams(); + Task taskInfo = taskService.createTaskQuery().taskId(taskId).singleResult(); + List> leaveList = activitiModelService.getUpLeaveList(user.get("id").toString(), + user.get("userName").toString(), opinion, true, taskInfo, ActivitiConstants.LeaveType.JOINTLY_SIGN_TASK.getType()); + runtimeService.setVariable(taskInfo.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + } + + /** + * 任务加签 + * + * @param taskId 任务id + * @param userMation 操作人用户信息 + * @param flag true向后加签 false向前加签 + * @param addSignUserJsonStr 加签用户的json串 + * @param outputObject 出参以及提示信息的返回值对象 + */ + public String addSignTask(String taskId, Map userMation, Boolean flag, String addSignUserJsonStr, OutputObject outputObject) { + TaskEntityImpl taskEntity = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult(); + // 1.把当前的节点设置为空 + if (taskEntity != null) { + String userId = userMation.get("id").toString(); + taskEntity.setOwner(userId); + taskEntity.setAssignee(null); + taskEntity.setCountEnabled(true); + if (flag) { + taskEntity.setScopeType(ActivitiConstants.AFTER_ADDSIGN); + } else { + taskEntity.setScopeType(ActivitiConstants.BEFORE_ADDSIGN); + } + // 1.2 设置任务为空执行者 + taskService.saveTask(taskEntity); + // 2.添加加签数据 + this.createSignSubTasks(addSignUserJsonStr, taskEntity, userMation); + return taskEntity.getProcessInstanceId(); + } else { + outputObject.setreturnMessage("不存在任务实例,请确认!"); + } + return StringUtils.EMPTY; + } + + /** + * 创建加签子任务 + * + * @param addSignUserJsonStr 加签参数 + * @param taskEntity 父任务 + * @param userMation 操作人用户信息 + */ + private void createSignSubTasks(String addSignUserJsonStr, TaskEntity taskEntity, Map userMation) { + List> addSignUser = JSONArray.fromObject(addSignUserJsonStr); + if (CollectionUtil.isNotEmpty(addSignUser)) { + String userId = userMation.get("id").toString(); + String parentTaskId = taskEntity.getParentTaskId(); + if (StringUtils.isBlank(parentTaskId)) { + parentTaskId = taskEntity.getId(); + } + String finalParentTaskId = parentTaskId; + String userNames = ""; + // 1.创建被加签人的任务列表 + for (Map bean : addSignUser) { + String signUserId = bean.get("id").toString(); + if (StringUtils.isNotBlank(signUserId)) { + this.createSubTask(taskEntity, finalParentTaskId, signUserId); + userNames += bean.get("name").toString() + "; "; + } + } + String taskId = taskEntity.getId(); + if (StringUtils.isBlank(taskEntity.getParentTaskId())) { + // 2.创建加签人的任务并执行完毕 + Task task = this.createSubTask(taskEntity, finalParentTaskId, userId); + taskId = task.getId(); + } + Task taskInfo = taskService.createTaskQuery().taskId(taskId).singleResult(); + // 添加加签操作历史 + String opinion = getAddSignTaskOpinion(taskEntity, userNames); + List> leaveList = activitiModelService.getUpLeaveList(userId, + userMation.get("userName").toString(), opinion, true, taskInfo, getAddSignTaskLeaveType(taskEntity)); + runtimeService.setVariable(taskInfo.getProcessInstanceId(), ActivitiConstants.PROCESSINSTANCEID_TASK_LEAVE_OPINION_LIST_VARABLES, leaveList); + if (null != taskInfo) { + taskService.complete(taskId); + } + } + } + + private String getAddSignTaskOpinion(TaskEntity taskEntity, String userNames) { + String opinion = ""; + if (ActivitiConstants.AFTER_ADDSIGN.equals(taskEntity.getScopeType())) { + // 后加签 + opinion = String.format(Locale.ROOT, "【加签】为【%s】进行后加签.", userNames); + } else if (ActivitiConstants.BEFORE_ADDSIGN.equals(taskEntity.getScopeType())) { + // 前加签 + opinion = String.format(Locale.ROOT, "【加签】为【%s】进行前加签.", userNames); + } + return opinion; + } + + private Integer getAddSignTaskLeaveType(TaskEntity taskEntity) { + Integer type = null; + if (ActivitiConstants.AFTER_ADDSIGN.equals(taskEntity.getScopeType())) { + // 后加签 + type = ActivitiConstants.LeaveType.AFTER_ADD_SIGN_TASK.getType(); + } else if (ActivitiConstants.BEFORE_ADDSIGN.equals(taskEntity.getScopeType())) { + // 前加签 + type = ActivitiConstants.LeaveType.BEFORE_ADD_SIGN_TASK.getType(); + } + return type; + } + + /** + * 创建子任务 + * + * @param ptask 创建子任务 + * @param assignee 子任务的执行人 + * @return + */ + protected TaskEntity createSubTask(TaskEntity ptask, String ptaskId, String assignee) { + TaskEntity task = null; + if (ptask != null) { + // 1.生成子任务 + task = (TaskEntity) taskService.newTask(ToolUtil.getSurFaceId()); + task.setCategory(ptask.getCategory()); + task.setDescription(ptask.getDescription()); + task.setTenantId(ptask.getTenantId()); + task.setAssignee(assignee); + task.setName(ptask.getName()); + task.setParentTaskId(ptaskId); + task.setProcessDefinitionId(ptask.getProcessDefinitionId()); + task.setProcessInstanceId(ptask.getProcessInstanceId()); + task.setTaskDefinitionKey(ptask.getTaskDefinitionKey()); + task.setTaskDefinitionId(ptask.getTaskDefinitionId()); + task.setPriority(ptask.getPriority()); + task.setCreateTime(new Date()); + taskService.saveTask(task); + } + return task; + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiUserServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiUserServiceImpl.java new file mode 100644 index 0000000..6048477 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/activiti/service/impl/ActivitiUserServiceImpl.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.activiti.service.ActivitiUserService; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.dao.ActGroupUserDao; +import com.skyeye.eve.entity.ActGroupUser; +import com.skyeye.eve.service.ActGroupUserService; +import com.skyeye.eve.service.ISysDictDataService; +import net.sf.json.JSONObject; +import org.flowable.engine.IdentityService; +import org.flowable.idm.api.Group; +import org.flowable.idm.api.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActivitiUserServiceImpl + * @Description: 工作流用户相关内容 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/2 20:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActivitiUserServiceImpl implements ActivitiUserService { + + @Autowired + protected ISysDictDataService iSysDictDataService; + + @Autowired + private ActGroupUserService actGroupUserService; + + @Autowired + private ActGroupUserDao actGroupUserDao; + + @Autowired + private IdentityService identityService; + + /** + * 获取人员选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserListToActiviti(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String reqObjStr = map.get("reqObj").toString(); + Map reqObj = JSONUtil.toBean(reqObjStr, null); + + // 获取参数信息 + List> conditions = JSONUtil.toList(reqObj.get("conditions").toString(), null); + + // 查询参数 + Map parmter = new HashMap<>(); + if (conditions.size() > 0) {//参数信息 + parmter.put(conditions.get(0).get("key").toString(), conditions.get(0).get("value")); + } + initPagingMation(reqObj, parmter); + + Page pages = PageHelper.startPage(Integer.parseInt(parmter.get("page").toString()), Integer.parseInt(parmter.get("limit").toString())); + List> beans = actGroupUserDao.queryUserListToActiviti(parmter); + long total = pages.getTotal(); + + // 表信息 + Map query = new HashMap<>(); + setCommonUserTableElement(query, reqObj.get("queryId").toString(), parmter.get("limit").toString()); + query.put("columnList", ActivitiConstants.getActivitiUserColumnList()); + query.put("columnMap", ActivitiConstants.getActivitiUserColumnMap()); + + // 分页信息 + Map pageInfo = getTablePageMation(total, parmter); + + outputObject.setCustomBean("query", query); + outputObject.setCustomBean("pageInfo", pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(total); + } + + /** + * 人员选择的表格公共部分 + * + * @param query table信息 + * @param queryId 表格id + * @param limit 每页多少条数据 + */ + private void setCommonUserTableElement(Map query, String queryId, String limit) { + query.put("id", queryId); + query.put("key", "id"); + query.put("tableName", "流程用户列表"); + query.put("pagesize", limit); + query.put("pagesInGrp", "5"); + query.put("widthType", "px"); + query.put("allowPaging", true); + query.put("enableMultiline", true); + query.put("isServerFilter", false); + query.put("enableMultiHeader", false); + query.put("simpleSearch", false); + query.put("startRow", 1); + } + + /** + * 初始化分页信息 + * + * @param reqObj 请求参数信息 + * @param parmter 查询参数 + */ + private void initPagingMation(Map reqObj, Map parmter) { + Map page = JSONObject.fromObject(reqObj.get("pageInfo").toString()); + if (CollectionUtil.isEmpty(page)) { + parmter.put("page", 1); + parmter.put("limit", 10); + } else { + parmter.put("page", page.get("pageNum")); + parmter.put("limit", page.get("pageSize")); + } + } + + /** + * 获取表格的分页信息 + * + * @param total 数据总条数 + * @param parmter 分页信息 + * @return + */ + private Map getTablePageMation(long total, Map parmter) { + Map pageInfo = new HashMap<>(); + String limit = parmter.get("limit").toString(); + pageInfo.put("pageNum", parmter.get("page")); + pageInfo.put("pageSize", parmter.get("limit")); + pageInfo.put("count", total); + long pageCount = total / Integer.parseInt(limit); + if (total % Integer.parseInt(limit) != 0) { + pageCount++; + } + pageInfo.put("pageCount", pageCount); + return pageInfo; + } + + /** + * 获取组人员选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserGroupListToActiviti(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String reqObjStr = map.get("reqObj").toString(); + Map reqObj = JSONUtil.toBean(reqObjStr, null); + String queryId = reqObj.get("queryId").toString(); + //获取参数信息 + List> conditions = JSONUtil.toList(reqObj.get("conditions").toString(), null); + + //查询参数 + Map parmter = new HashMap<>(); + for (Map condition : conditions) {//参数信息 + parmter.put(condition.get("key").toString(), condition.get("value")); + } + initPagingMation(reqObj, parmter); + + long total; + List> beans; + if ("id_group_list".equals(queryId)) { + // 分组 + beans = iSysDictDataService.queryDictDataListByDictTypeCode("ACT_GROUP"); + total = beans.size(); + } else { + // 人员 + Page pages = PageHelper.startPage(Integer.parseInt(parmter.get("page").toString()), Integer.parseInt(parmter.get("limit").toString())); + beans = actGroupUserDao.queryUserListToActivitiByGroup(parmter); + total = pages.getTotal(); + } + + // 表信息 + Map query = new HashMap<>(); + setCommonUserTableElement(query, reqObj.get("queryId").toString(), parmter.get("limit").toString()); + if ("id_group_list".equals(queryId)) {//分组 + query.put("columnList", ActivitiConstants.getActivitiGroupColumnList()); + query.put("columnMap", ActivitiConstants.getActivitiGroupColumnMap()); + } else {//人员 + query.put("columnList", ActivitiConstants.getActivitiUserColumnListByGroupId()); + query.put("columnMap", ActivitiConstants.getActivitiUserColumnMapByGroupId()); + } + + // 分页信息 + Map pageInfo = getTablePageMation(total, parmter); + + outputObject.setCustomBean("query", query); + outputObject.setCustomBean("pageInfo", pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(total); + } + + /** + * 用户以及用户组信息同步到act表中 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertSyncUserListMationToAct(InputObject inputObject, OutputObject outputObject) { + // 同步用户组信息 + List> groupList = iSysDictDataService.queryDictDataListByDictTypeCode("ACT_GROUP"); + for (Map bean : groupList) { + Group group = identityService.newGroup(bean.get("id").toString()); + group.setName(bean.get("name").toString()); + identityService.deleteGroup(group.getId()); + identityService.saveGroup(group); + } + // 同步用户信息 + List actGroupUsers = actGroupUserService.queryAllActGroupUser(); + for (ActGroupUser bean : actGroupUsers) { + Map userMation = bean.getUserMation(); + if (CollectionUtil.isEmpty(userMation)) { + continue; + } + User user = identityService.newUser(userMation.get("id").toString()); + user.setDisplayName(userMation.get("userName").toString()); + user.setFirstName(userMation.get("userName").toString()); + user.setLastName(userMation.get("userCode").toString()); + user.setEmail(userMation.get("email").toString()); + identityService.deleteUser(user.getId()); + identityService.saveUser(user); + // 同步用户和用户组的关系信息 + identityService.deleteMembership(bean.getUserId(), bean.getGroupId()); + identityService.createMembership(bean.getUserId(), bean.getGroupId()); + } + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/classenum/ActModelState.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/classenum/ActModelState.java new file mode 100644 index 0000000..e6d8da8 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/classenum/ActModelState.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ActModelState + * @Description: 工作流配置状态的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ActModelState implements SkyeyeEnumClass { + + NEW(1, "新建", false, false), + UP(2, "上线", false, false), + DOWN(3, "下线", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActFlowController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActFlowController.java new file mode 100644 index 0000000..949fba8 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActFlowController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.service.ActFlowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActFlowController + * @Description: 流程模型管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/4 22:51 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "流程模型管理", tags = "流程模型管理", modelName = "工作流模块") +public class ActFlowController { + + @Autowired + private ActFlowService actFlowService; + + /** + * 获取流程模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryActFlowList", value = "获取流程模型列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActFlowController/queryActFlowList") + public void queryActFlowList(InputObject inputObject, OutputObject outputObject) { + actFlowService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑流程模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeActFlowMation", value = "新增/编辑流程模型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ActFlowMation.class) + @RequestMapping("/post/ActFlowController/writeActFlowMation") + public void writeActFlowMation(InputObject inputObject, OutputObject outputObject) { + actFlowService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID获取流程模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryActFlowMationById", value = "根据ID获取流程模型信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ActFlowController/queryActFlowMationById") + public void queryActFlowMationById(InputObject inputObject, OutputObject outputObject) { + actFlowService.selectById(inputObject, outputObject); + } + + /** + * 根据ID删除流程模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteActFlowMationById", value = "根据ID删除流程模型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ActFlowController/deleteActFlowMationById") + public void deleteActFlowMationById(InputObject inputObject, OutputObject outputObject) { + actFlowService.deleteById(inputObject, outputObject); + } + + /** + * 根据适用对象获取流程模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryActFlowListByClassName", value = "根据适用对象获取流程模型列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "类的Refrence", required = "required")}) + @RequestMapping("/post/ActFlowController/queryActFlowListByClassName") + public void queryActFlowListByClassName(InputObject inputObject, OutputObject outputObject) { + actFlowService.queryList(inputObject, outputObject); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActGroupUserController.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActGroupUserController.java new file mode 100644 index 0000000..e5cc1af --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/controller/ActGroupUserController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.ActGroupUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ActGroupUserController + * @Description: 用户组关联用户管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/12 14:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用户组关联用户管理", tags = "用户组关联用户管理", modelName = "用户组关联用户管理") +public class ActGroupUserController { + + @Autowired + private ActGroupUserService actGroupService; + + /** + * 给用户组新增用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertActGroupUser", value = "给用户组新增用户", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "groupId", name = "groupId", value = "用户组id", required = "required"), + @ApiImplicitParam(id = "userIds", name = "userIds", value = "用户id,多个逗号隔开", required = "required")}) + @RequestMapping("/post/ActGroupUserController/insertActGroupUser") + public void insertActGroupUser(InputObject inputObject, OutputObject outputObject) { + actGroupService.insertActGroupUser(inputObject, outputObject); + } + + /** + * 移除用户组中的某个用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteActGroupUserById", value = "移除用户组中的某个用户", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ActGroupUserController/deleteActGroupUserById") + public void deleteActGroupUserById(InputObject inputObject, OutputObject outputObject) { + actGroupService.deleteById(inputObject, outputObject); + } + + /** + * 展示用户组的用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserInfoOnActGroup", value = "展示用户组的用户信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ActGroupUserController/queryUserInfoOnActGroup") + public void queryUserInfoOnActGroup(InputObject inputObject, OutputObject outputObject) { + actGroupService.queryPageList(inputObject, outputObject); + } + + /** + * 一键移除指定用户组下的所有用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAllActGroupUserByGroupId", value = "一键移除指定用户组下的所有用户", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "groupId", name = "groupId", value = "用户组id", required = "required")}) + @RequestMapping("/post/ActGroupUserController/deleteAllActGroupUserByGroupId") + public void deleteAllActGroupUserByGroupId(InputObject inputObject, OutputObject outputObject) { + actGroupService.deleteAllActGroupUserByGroupId(inputObject, outputObject); + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActFlowDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActFlowDao.java new file mode 100644 index 0000000..9f3f38d --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActFlowDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.ActFlowMation; + +/** + * @ClassName: ActFlowDao + * @Description: 流程模型管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/4 22:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActFlowDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActGroupUserDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActGroupUserDao.java new file mode 100644 index 0000000..7043dfb --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/dao/ActGroupUserDao.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.entity.ActGroupUser; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActGroupUserDao + * @Description: 用户组关联用户管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/3 22:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActGroupUserDao extends SkyeyeBaseMapper { + + List> queryUserListToActiviti(Map map); + + List> queryUserListToActivitiByGroup(Map parmter); + + List> queryUserInfoOnActGroup(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActFlowMation.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActFlowMation.java new file mode 100644 index 0000000..0659bae --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActFlowMation.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ActFlowMation + * @Description: 流程模型管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/4 22:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"modelKey"}) +@RedisCacheField(name = "act:flow", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "act_flow") +@ApiModel("流程配置实体类") +public class ActFlowMation extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "flow_name") + @ApiModelProperty(value = "流程模型名称", required = "required", fuzzyLike = true) + private String flowName; + + @TableField(value = "model_id", fill = FieldFill.INSERT) + @Property("模型id") + private String modelId; + + @TableField(value = "model_key") + @ApiModelProperty(value = "模型key", required = "required", fuzzyLike = true) + private String modelKey; + + @TableField(value = "apply_service_class_name") + @ApiModelProperty(value = "适用的服务类名") + private String applyServiceClassName; + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActGroupUser.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActGroupUser.java new file mode 100644 index 0000000..3e6d129 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/entity/ActGroupUser.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ActGroupUser + * @Description: 用户组关联用户的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/11 11:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"groupId", "userId"}) +@TableName(value = "act_group_user") +@ApiModel("用户组关联用户的实体类") +public class ActGroupUser extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "group_id") + @ApiModelProperty(value = "用户组id", required = "required") + private String groupId; + + @TableField(value = "user_id") + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @TableField(exist = false) + @Property(value = "用户信息") + private Map userMation; + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActFlowService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActFlowService.java new file mode 100644 index 0000000..a62a551 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActFlowService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.entity.ActFlowMation; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActFlowService + * @Description: 流程模型管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/4 22:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActFlowService extends SkyeyeBusinessService { + + Map actIdToFlowNameByIds(List ids); + + /** + * 根据服务类名获取流程模型信息 + * + * @param serviceClassName 服务类名 + * @return + */ + ActFlowMation getActFlow(String serviceClassName); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActGroupUserService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActGroupUserService.java new file mode 100644 index 0000000..39e8119 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/ActGroupUserService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.ActGroupUser; + +import java.util.List; + +/** + * @ClassName: ActGroupService + * @Description: 用户组关联用户管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/12 14:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActGroupUserService extends SkyeyeBusinessService { + + void insertActGroupUser(InputObject inputObject, OutputObject outputObject); + + void deleteAllActGroupUserByGroupId(InputObject inputObject, OutputObject outputObject); + + List queryAllActGroupUser(); + + List queryActGroupUser(List groupIds); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActFlowServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActFlowServiceImpl.java new file mode 100644 index 0000000..e69fe80 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActFlowServiceImpl.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.activiti.service.ActivitiModelService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.ActFlowDao; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.service.ActFlowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ActFlowServiceImpl + * @Description: 流程模型管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/4 22:53 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActFlowServiceImpl extends SkyeyeBusinessServiceImpl implements ActFlowService { + + @Autowired + private ActivitiModelService activitiModelService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置流程模型信息 + activitiModelService.setActivitiModelList(beans); + return beans; + } + + @Override + public void createPrepose(ActFlowMation entity) { + // 新增工作流模型信息 + String modelId = activitiModelService.insertNewActivitiModel(entity.getFlowName(), entity.getModelKey()); + entity.setModelId(modelId); + } + + @Override + public void updatePostpose(ActFlowMation entity, String userId) { + // 修改工作流模型信息 + activitiModelService.editModelByModelId(entity.getModelId(), entity.getFlowName(), entity.getModelKey()); + } + + @Override + public void deletePreExecution(String id) { + ActFlowMation actFlowMation = selectById(id); + // 删除模型信息 + activitiModelService.deleteActivitiModelById(actFlowMation.getModelId()); + } + + /** + * 根据id批量获取工作流模型信息 + * + * @param ids + * @return + */ + @Override + public Map actIdToFlowNameByIds(List ids) { + ids = ids.stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new HashMap<>(); + } + List actFlowMationList = selectByIds(ids.toArray(new String[]{})); + Map actFlowMationMap = actFlowMationList.stream().collect(Collectors.toMap(bean -> bean.getId(), bean -> bean)); + ids.forEach(id -> { + if (!actFlowMationMap.containsKey(id)) { + actFlowMationMap.put(id, new ActFlowMation()); + } + }); + return actFlowMationMap; + } + + /** + * 根据服务类名获取流程模型信息 + * + * @param serviceClassName 服务类名 + * @return + */ + @Override + public ActFlowMation getActFlow(String serviceClassName) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActFlowMation::getApplyServiceClassName), serviceClassName); + return getOne(queryWrapper, false); + } + + /** + * 根据适用对象获取流程模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + */ + @Override + public List> queryDataList(InputObject inputObject) { + String className = inputObject.getParams().get("className").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActFlowMation::getApplyServiceClassName), className); + List list = list(queryWrapper); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list), null); + // 设置流程模型信息 + activitiModelService.setActivitiModelList(beans); + return beans; + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActGroupUserServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActGroupUserServiceImpl.java new file mode 100644 index 0000000..547dd4b --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/eve/service/impl/ActGroupUserServiceImpl.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.ActGroupUserDao; +import com.skyeye.eve.entity.ActGroupUser; +import com.skyeye.eve.service.ActGroupUserService; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ActGroupUserServiceImpl + * @Description: 用户组关联用户管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/12 14:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户组关联用户管理", groupName = "用户组关联用户管理", manageShow = false) +public class ActGroupUserServiceImpl extends SkyeyeBusinessServiceImpl implements ActGroupUserService { + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + /** + * 给用户组新增用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertActGroupUser(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String groupId = map.get("groupId").toString(); + List userIds = Arrays.asList(map.get("userIds").toString().split(CommonCharConstants.COMMA_MARK)); + // 获取组内已有的用户 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActGroupUser::getGroupId), groupId); + List hasUserIds = list(queryWrapper).stream().map(ActGroupUser::getUserId).collect(Collectors.toList()); + + List list = new ArrayList<>(); + userIds.forEach(userId -> { + if (hasUserIds.indexOf(userId) == -1) { + ActGroupUser actGroupUser = new ActGroupUser(); + actGroupUser.setGroupId(groupId); + actGroupUser.setUserId(userId); + list.add(actGroupUser); + } + }); + String userId = inputObject.getLogParams().get("id").toString(); + createEntity(list, userId); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryUserInfoOnActGroup(commonPageInfo); + iCompanyService.setNameForMap(beans, "companyId", "companyName"); + iDepmentService.setNameForMap(beans, "departmentId", "departmentName"); + iCompanyJobService.setNameForMap(beans, "jobId", "jobName"); + return beans; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteAllActGroupUserByGroupId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String groupId = map.get("groupId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActGroupUser::getGroupId), groupId); + remove(queryWrapper); + } + + @Override + public List queryAllActGroupUser() { + List actGroupUsers = list(); + iAuthUserService.setDataMation(actGroupUsers, ActGroupUser::getUserId); + return actGroupUsers; + } + + @Override + public List queryActGroupUser(List groupIds) { + if (CollectionUtil.isEmpty(groupIds)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ActGroupUser::getGroupId), groupIds); + List actGroupUsers = list(queryWrapper); + iAuthUserService.setDataMation(actGroupUsers, ActGroupUser::getUserId); + return actGroupUsers; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/main/StencilsetRestResource.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/main/StencilsetRestResource.java new file mode 100644 index 0000000..ee3381b --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/main/StencilsetRestResource.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +/* 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. + */ + +package com.skyeye.flowable.main; + +import org.apache.commons.io.IOUtils; +import org.flowable.common.engine.api.FlowableException; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.io.InputStream; + +/** + * @ClassName: StencilsetRestResource + * @Description: 获取编辑器组件及配置项信息 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/17 20:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@RequestMapping(value = "/service") +public class StencilsetRestResource { + + @RequestMapping(value = "/editor/stencilset", method = RequestMethod.GET, produces = "application/json;charset=utf-8") + public String getStencilset() { + InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json"); + try { + return IOUtils.toString(stencilsetStream, "utf-8"); + } catch (Exception e) { + throw new FlowableException("Error while loading stencil set", e); + } + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelEditorJsonRestResource.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelEditorJsonRestResource.java new file mode 100644 index 0000000..a56d68c --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelEditorJsonRestResource.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +/* 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. + */ + +package com.skyeye.flowable.model; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.lang3.StringUtils; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.editor.constants.ModelDataJsonConstants; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.repository.Model; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ModelEditorJsonRestResource + * @Description: 根据modelId获取model的节点信息,编辑器根据返回的json进行绘图 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/17 20:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@RequestMapping(value = "/service") +public class ModelEditorJsonRestResource implements ModelDataJsonConstants { + + protected static final Logger LOGGER = LoggerFactory.getLogger(ModelEditorJsonRestResource.class); + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private ObjectMapper objectMapper; + + @RequestMapping(value = "/model/{modelId}/json", method = RequestMethod.GET, produces = "application/json") + public ObjectNode getEditorJson(@PathVariable String modelId) { + ObjectNode modelNode = null; + + Model model = repositoryService.getModel(modelId); + + if (model != null) { + try { + if (StringUtils.isNotEmpty(model.getMetaInfo())) { + modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); + } else { + modelNode = objectMapper.createObjectNode(); + modelNode.put(MODEL_NAME, model.getName()); + } + modelNode.put(MODEL_ID, model.getId()); + ObjectNode editorJsonNode = (ObjectNode) objectMapper + .readTree(new String(repositoryService.getModelEditorSource(model.getId()), "utf-8")); + modelNode.put("model", editorJsonNode); + + } catch (Exception e) { + LOGGER.error("Error creating model JSON", e); + throw new FlowableException("Error creating model JSON", e); + } + } + return modelNode; + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelSaveRestResource.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelSaveRestResource.java new file mode 100644 index 0000000..7ff69d9 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/flowable/model/ModelSaveRestResource.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +/* 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. + */ + +package com.skyeye.flowable.model; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.skyeye.common.util.XssUtil; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.image.PNGTranscoder; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.editor.constants.ModelDataJsonConstants; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.repository.Model; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * @ClassName: ModelSaveRestResource + * @Description: 编辑器制图之后,将节点信息以json的形式提交给这个Controller,然后由其进行持久化操作 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/17 20:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@RequestMapping(value = "/service") +public class ModelSaveRestResource implements ModelDataJsonConstants { + + protected static final Logger LOGGER = LoggerFactory.getLogger(ModelSaveRestResource.class); + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private ObjectMapper objectMapper; + + @RequestMapping(value = "/model/{modelId}/save", method = RequestMethod.PUT) + @ResponseStatus(value = HttpStatus.OK) + public void saveModel(@PathVariable String modelId, @RequestParam("name") String name, + @RequestParam("json_xml") String json_xml, @RequestParam("svg_xml") String svg_xml, + @RequestParam("description") String description) { + ByteArrayOutputStream outStream = null; + try { + + Model model = repositoryService.getModel(modelId); + + ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); + modelJson.put(MODEL_NAME, name); + modelJson.put(MODEL_DESCRIPTION, description); + model.setMetaInfo(modelJson.toString()); + model.setVersion(model.getVersion() + 1); + model.setName(name); + + repositoryService.saveModel(model); + + repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8")); + + svg_xml = XssUtil.restoreXSS(svg_xml); + InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8")); + TranscoderInput input = new TranscoderInput(svgStream); + + PNGTranscoder transcoder = new PNGTranscoder(); + // Setup output + outStream = new ByteArrayOutputStream(); + TranscoderOutput output = new TranscoderOutput(outStream); + + // Do the transformation + transcoder.transcode(input, output); + final byte[] result = outStream.toByteArray(); + repositoryService.addModelEditorSourceExtra(model.getId(), result); + + } catch (Exception e) { + LOGGER.error("Error saving model", e); + throw new FlowableException("Error saving model", e); + } finally { + if (outStream != null) { + try { + outStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/listener/ApprovalIsEndListener.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/listener/ApprovalIsEndListener.java new file mode 100644 index 0000000..b1abdae --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/listener/ApprovalIsEndListener.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.listener; + +import cn.hutool.core.util.ObjectUtil; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.exception.CustomException; +import com.skyeye.sdk.data.entity.ApprovalEnd; +import com.skyeye.sdk.data.service.IDataService; +import com.skyeye.userprocess.entity.ActUserProcess; +import com.skyeye.userprocess.service.ActUserProcessService; +import lombok.SneakyThrows; +import org.flowable.common.engine.api.delegate.Expression; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.JavaDelegate; + +/** + * @ClassName: ApprovalIsEndListener + * @Description: 工作流审批结束的监听类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/4 17:33 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class ApprovalIsEndListener implements JavaDelegate { + + /** + * 值为pass,则通过,为nopass,则不通过 + */ + private Expression state; + + private IDataService iDataService; + + private ActUserProcessService actUserProcessService; + + public ApprovalIsEndListener() { + iDataService = SpringUtils.getBean(IDataService.class); + actUserProcessService = SpringUtils.getBean(ActUserProcessService.class); + } + + @Override + @SneakyThrows(value = {Exception.class}) + public void execute(DelegateExecution execution) { + String processInstanceId = execution.getProcessInstanceId(); + // 审批结果 + String result = (String) state.getValue(execution); + + ActUserProcess actUserProcess = actUserProcessService.selectByProcessInstanceId(processInstanceId); + if (ObjectUtil.isEmpty(actUserProcess)) { + throw new CustomException("流程信息不存在."); + } + + // 调用审批结果处理的函数 + ApprovalEnd approvalEnd = new ApprovalEnd(); + approvalEnd.setProcessInstanceId(processInstanceId); + approvalEnd.setResult(result); + approvalEnd.setServiceClassName(actUserProcess.getObjectKey()); + approvalEnd.setAppId(actUserProcess.getAppId()); + iDataService.approvalEnd(approvalEnd); + } + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/dao/ActUserProcessDao.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/dao/ActUserProcessDao.java new file mode 100644 index 0000000..d5365c0 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/dao/ActUserProcessDao.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.userprocess.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.userprocess.entity.ActUserProcess; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActUserProcessDao + * @Description: 用户启动的流程管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/18 10:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActUserProcessDao extends SkyeyeBaseMapper { + + List> queryStartProcessNotSubByUserId(CommonPageInfo pageInfo); + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/entity/ActUserProcess.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/entity/ActUserProcess.java new file mode 100644 index 0000000..58ba969 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/entity/ActUserProcess.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.userprocess.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ActUserProcess + * @Description: 用户启动的流程实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/18 10:34 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "act_user_process", autoResultMap = true) +@ApiModel("用户启动的流程实体类") +public class ActUserProcess extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("process_instance_id") + @ApiModelProperty(value = "流程id", required = "required") + private String processInstanceId; + + @TableField("act_flow_id") + @ApiModelProperty(value = "工作流模型id", required = "required") + private String actFlowId; + + @TableField(exist = false) + @Property("工作流模型名称") + private String title; + + @TableField(exist = false) + @Property("流程配置页面类型") + private Integer pageTypes; + + @TableField("object_id") + @ApiModelProperty(value = "业务数据的id", required = "required") + private String objectId; + + @TableField("object_key") + @ApiModelProperty(value = "业务数据的serviceClassName", required = "required") + private String objectKey; + + @TableField("app_id") + @ApiModelProperty(value = "业务数据的id", required = "required") + private String appId; + + @TableField(exist = false) + @Property("任务信息") + private Map task; + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/ActUserProcessService.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/ActUserProcessService.java new file mode 100644 index 0000000..4da793a --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/ActUserProcessService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.userprocess.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.userprocess.entity.ActUserProcess; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ActUserProcessService + * @Description: 用户启动的流程管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/18 10:32 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ActUserProcessService extends SkyeyeBusinessService { + + void deleteByProcessInstanceId(String processInstanceId); + + void saveActUserProcess(String processInstanceId, String actFlowId, String objectId, String objectKey, String appId); + + ActUserProcess selectByProcessInstanceId(String processInstanceId); + + Map selectByProcessInstanceId(List processInstanceIds); + + +} diff --git a/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/impl/ActUserProcessServiceImpl.java b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/impl/ActUserProcessServiceImpl.java new file mode 100644 index 0000000..b39f9b2 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/java/com/skyeye/userprocess/service/impl/ActUserProcessServiceImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.userprocess.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.entity.ActFlowMation; +import com.skyeye.eve.service.ActFlowService; +import com.skyeye.userprocess.dao.ActUserProcessDao; +import com.skyeye.userprocess.entity.ActUserProcess; +import com.skyeye.userprocess.service.ActUserProcessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ActUserProcessServiceImpl + * @Description: 用户启动的流程管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/18 10:32 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ActUserProcessServiceImpl extends SkyeyeBusinessServiceImpl implements ActUserProcessService { + + @Autowired + private ActFlowService actFlowService; + + /** + * 根据流程实例id删除流程信息 + * + * @param processInstanceId 流程实例id + */ + @Override + public void deleteByProcessInstanceId(String processInstanceId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActUserProcess::getProcessInstanceId), processInstanceId); + remove(queryWrapper); + } + + /** + * 保存流程信息 + * + * @param processInstanceId 流程实例id + * @param actFlowId 流程模型id + * @param objectId 业务对象id + * @param objectKey 业务对象的key + */ + @Override + public void saveActUserProcess(String processInstanceId, String actFlowId, String objectId, String objectKey, String appId) { + ActUserProcess actUserProcess = new ActUserProcess(); + actUserProcess.setProcessInstanceId(processInstanceId); + actUserProcess.setActFlowId(actFlowId); + actUserProcess.setObjectId(objectId); + actUserProcess.setObjectKey(objectKey); + actUserProcess.setAppId(appId); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + createEntity(actUserProcess, userId); + } + + /** + * 根据流程实例id查询流程信息 + * + * @param processInstanceId 流程实例id + */ + @Override + public ActUserProcess selectByProcessInstanceId(String processInstanceId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ActUserProcess::getProcessInstanceId), processInstanceId); + ActUserProcess userProcess = getOne(queryWrapper); + if (userProcess == null) { + return new ActUserProcess(); + } + iAuthUserService.setName(userProcess, "createId", "createName"); + // 获取工作流模型信息 + Map actFlowMationMap = actFlowService.actIdToFlowNameByIds(Arrays.asList(userProcess.getActFlowId())); + if (CollectionUtil.isNotEmpty(actFlowMationMap)) { + ActFlowMation actFlowMation = actFlowMationMap.get(userProcess.getActFlowId()); + userProcess.setTitle(actFlowMation.getFlowName()); + } + return userProcess; + } + + @Override + public Map selectByProcessInstanceId(List processInstanceIds) { + if (CollectionUtil.isEmpty(processInstanceIds)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ActUserProcess::getProcessInstanceId), processInstanceIds); + List actUserProcessList = list(queryWrapper); + iAuthUserService.setName(actUserProcessList, "createId", "createName"); + // 获取工作流模型信息 + List actFlowIds = actUserProcessList.stream().map(ActUserProcess::getActFlowId).collect(Collectors.toList()); + Map actFlowMationMap = actFlowService.actIdToFlowNameByIds(actFlowIds); + actUserProcessList.forEach(actUserProcess -> { + ActFlowMation actFlowMation = actFlowMationMap.get(actUserProcess.getActFlowId()); + if (ObjectUtil.isNotEmpty(actFlowMation)) { + actUserProcess.setTitle(actFlowMation.getFlowName()); + } + }); + return actUserProcessList.stream().collect(Collectors.toMap(ActUserProcess::getProcessInstanceId, bean -> bean)); + } +} diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/activiti/ActGroupUserMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/activiti/ActGroupUserMapper.xml new file mode 100644 index 0000000..2414281 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/activiti/ActGroupUserMapper.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/ActivityMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/ActivityMapper.xml new file mode 100644 index 0000000..83a531a --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/ActivityMapper.xml @@ -0,0 +1,29 @@ + + + + + + UPDATE ACT_RE_PROCDEF + + NAME_ = #{name} + + WHERE ID_ = #{processDefinitionId} + + + + DELETE + FROM + ACT_HI_ACTINST + where + TASK_ID_ = #{taskId} + + + + DELETE + FROM + ACT_HI_TASKINST + where + ID_ = #{taskId} + + + diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReModelMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReModelMapper.xml new file mode 100644 index 0000000..deca6cb --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReModelMapper.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReProcdefMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReProcdefMapper.xml new file mode 100644 index 0000000..8904f32 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowReProcdefMapper.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowableTaskMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowableTaskMapper.xml new file mode 100644 index 0000000..3238353 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/FlowableTaskMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/HistoryActivityInstanceMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/HistoryActivityInstanceMapper.xml new file mode 100644 index 0000000..bb5f316 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/flowable/HistoryActivityInstanceMapper.xml @@ -0,0 +1,13 @@ + + + + + + DELETE + FROM + act_hi_actinst + where + id_ = #{id} + + + diff --git a/skyeye-flowable/flowable-main/src/main/resources/mapper/userprocess/ActUserProcessMapper.xml b/skyeye-flowable/flowable-main/src/main/resources/mapper/userprocess/ActUserProcessMapper.xml new file mode 100644 index 0000000..f5e580d --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/mapper/userprocess/ActUserProcessMapper.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/db2.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/db2.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/db2.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/h2.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/h2.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/hsql.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/hsql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/mssql.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/mssql.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/mssql.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/mysql.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/mysql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/oracle.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/oracle.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/oracle.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/postgres.properties b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/postgres.properties new file mode 100644 index 0000000..abe3f3d --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/org/flowable/db/properties/postgres.properties @@ -0,0 +1 @@ +blobType=BINARY diff --git a/skyeye-flowable/flowable-main/src/main/resources/reqmapping/mapping/activiti.xml b/skyeye-flowable/flowable-main/src/main/resources/reqmapping/mapping/activiti.xml new file mode 100644 index 0000000..efa2f52 --- /dev/null +++ b/skyeye-flowable/flowable-main/src/main/resources/reqmapping/mapping/activiti.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-web/.gitignore b/skyeye-flowable/flowable-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-flowable/flowable-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-web/pom.xml b/skyeye-flowable/flowable-web/pom.xml new file mode 100644 index 0000000..a9b0428 --- /dev/null +++ b/skyeye-flowable/flowable-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-flowable + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + flowable-web + + + 8 + 8 + + + + + + com.skyeye + flowable-main + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-flowable/flowable-web/src/main/java/com/SkyFlowableApplication.java b/skyeye-flowable/flowable-web/src/main/java/com/SkyFlowableApplication.java new file mode 100644 index 0000000..3deeb91 --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/java/com/SkyFlowableApplication.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.flowable.ui.modeler.properties.FlowableModelerAppProperties; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, + org.flowable.spring.boot.FlowableSecurityAutoConfiguration.class, + org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class +}) +@EnableConfigurationProperties({FlowableModelerAppProperties.class}) +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableDiscoveryClient +@EnableFeignClients +public class SkyFlowableApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyFlowableApplication.class, args); + } + +} diff --git a/skyeye-flowable/flowable-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-flowable/flowable-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..bc71a93 --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.exception.CustomException; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseConnection; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.DatabaseException; +import liquibase.resource.ClassLoaderResourceAccessor; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.flowable.ui.common.service.exception.InternalServerErrorException; +import org.flowable.ui.modeler.properties.FlowableModelerAppProperties; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +/** + * @ClassName: BaseDataSourceConfig + * @Description: 数据库配置类 basePackages:星号代表任意个包,比如可以扫描com.skyeye.aaa.dao,也可以扫描com.skyeye.aaa.bbb.dao + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 15:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@MapperScan(basePackages = { + "com.skyeye.*.dao", + "com.skyeye.eve.*.dao", + "com.skyeye.dao", + "com.skyeye.activiti.mapper"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_ADM_"; + + @Autowired + protected FlowableModelerAppProperties modelerAppProperties; + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (ToolUtil.isBlank(databaseType)) { + throw new CustomException("couldn't deduct database type"); + } + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + Properties properties = new Properties(); + properties.put("prefix", this.modelerAppProperties.getDataSourcePrefix()); + properties.put("blobType", "BLOB"); + properties.put("boolValue", "1"); + properties.load(this.getClass().getClassLoader().getResourceAsStream("org/flowable/db/properties/" + databaseType + ".properties")); + sqlSessionFactoryBean.setConfigurationProperties(properties); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + mapperLocations.add("classpath:/META-INF/modeler-mybatis-mappings/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Bean + public Liquibase liquibase(@Qualifier("baseDataSource") DataSource dataSource) { + LOGGER.info("Configuring Liquibase"); + Liquibase liquibase = null; + try { + DatabaseConnection connection = new JdbcConnection(dataSource.getConnection()); + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection); + database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName()); + database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName()); + + liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database); + liquibase.update("flowable"); + return liquibase; + } catch (Exception var9) { + throw new InternalServerErrorException("Error creating liquibase database", var9); + } finally { + this.closeDatabase(liquibase); + } + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (ToolUtil.isBlank(databaseType)) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + + private void closeDatabase(Liquibase liquibase) { + if (liquibase != null) { + Database database = liquibase.getDatabase(); + if (database != null) { + try { + database.close(); + } catch (DatabaseException var4) { + LOGGER.warn("Error closing database", var4); + } + } + } + } + +} diff --git a/skyeye-flowable/flowable-web/src/main/resources/banner.txt b/skyeye-flowable/flowable-web/src/main/resources/banner.txt new file mode 100644 index 0000000..07b76ca --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev flowable-web.jar >> /opt/service/project/nohup-flowable.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-flowable/flowable-web/src/main/resources/bootstrap.yml b/skyeye-flowable/flowable-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..1a7b2e2 --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/resources/bootstrap.yml @@ -0,0 +1,41 @@ + +server: + port: 8083 + +spring: + application: + name: skyeye-flowable-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # 总工程服务 + skyeye-pro: skyeye-pro-${spring.profiles.active} diff --git a/skyeye-flowable/flowable-web/src/main/resources/log4j.properties b/skyeye-flowable/flowable-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..8c5f422 --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-flowable/flowable-web/src/main/resources/stencilset.json b/skyeye-flowable/flowable-web/src/main/resources/stencilset.json new file mode 100644 index 0000000..a77a192 --- /dev/null +++ b/skyeye-flowable/flowable-web/src/main/resources/stencilset.json @@ -0,0 +1,2414 @@ +{ + "title": "BPMN 2.0标准工具", + "namespace": "http://b3mn.org/stencilset/bpmn2.0#", + "description": "BPMN process editor", + "propertyPackages": [ + { + "name": "process_idpackage", + "properties": [ + { + "id": "process_id", + "type": "String", + "title": "流程id", + "value": "process", + "description": "流程的特殊唯一的名称标识", + "popular": true, + "readOnly": true + } + ] + }, + { + "name": "overrideidpackage", + "properties": [ + { + "id": "overrideid", + "type": "String", + "title": "Id", + "value": "", + "description": "Unique identifier of the element.", + "popular": true + } + ] + }, + { + "name": "namepackage", + "properties": [ + { + "id": "name", + "type": "String", + "title": "名称", + "value": "", + "description": "元素名称", + "popular": true, + "refToView": "text_name", + "readOnly": true + } + ] + }, + { + "name": "documentationpackage", + "properties": [ + { + "id": "documentation", + "type": "Text", + "title": "描述", + "value": "", + "description": "元素描述", + "popular": true + } + ] + }, + { + "name": "process_authorpackage", + "properties": [ + { + "id": "process_author", + "type": "String", + "title": "流程作者", + "value": "", + "description": "流程定义者姓名", + "popular": true + } + ] + }, + { + "name": "process_versionpackage", + "properties": [ + { + "id": "process_version", + "type": "String", + "title": "流程版本", + "value": "", + "description": "标识文档版本", + "popular": true + } + ] + }, + { + "name": "process_namespacepackage", + "properties": [ + { + "id": "process_namespace", + "type": "String", + "title": "目标命名空间", + "value": "http://www.activiti.org/processdef", + "description": "工作流目标命名空间", + "popular": true + } + ] + }, + { + "name": "asynchronousdefinitionpackage", + "properties": [ + { + "id": "asynchronousdefinition", + "type": "Boolean", + "title": "异步", + "value": "false", + "description": "Define the activity as asynchronous.", + "popular": true + } + ] + }, + { + "name": "exclusivedefinitionpackage", + "properties": [ + { + "id": "exclusivedefinition", + "type": "Boolean", + "title": "单独", + "value": "false", + "description": "Define the activity as exclusive.", + "popular": true + } + ] + }, + { + "name": "executionlistenerspackage", + "properties": [ + { + "id": "executionlisteners", + "type": "multiplecomplex", + "title": "执行监听器", + "value": "", + "description": "Listeners for an activity, process, sequence flow, start and end event.", + "popular": true + } + ] + }, + { + "name": "tasklistenerspackage", + "properties": [ + { + "id": "tasklisteners", + "type": "multiplecomplex", + "title": "任务监听器", + "value": "", + "description": "Listeners for a user task", + "popular": true + } + ] + }, + { + "name": "eventlistenerspackage", + "properties": [ + { + "id": "eventlisteners", + "type": "multiplecomplex", + "title": "事件监听器", + "value": "", + "description": "Listeners for any event happening in the Activiti Engine. It's also possible to rethrow the event as a signal, message or error event", + "popular": true + } + ] + }, + { + "name": "usertaskassignmentpackage", + "properties": [ + { + "id": "usertaskassignment", + "type": "Complex", + "title": "代理", + "value": "", + "description": "Assignment definition for the user task", + "popular": true + } + ] + }, + { + "name": "formpropertiespackage", + "properties": [ + { + "id": "formproperties", + "type": "Complex", + "title": "动态表单属性", + "value": "", + "description": "Definition of the form with a list of form properties", + "popular": true + } + ] + }, + { + "name": "formkeydefinitionpackage", + "properties": [ + { + "id": "formkeydefinition", + "type": "String", + "title": "自定义表单", + "value": "", + "description": "用户任务表单编号", + "popular": true + } + ] + }, + { + "name": "duedatedefinitionpackage", + "properties": [ + { + "id": "duedatedefinition", + "type": "String", + "title": "到期日期", + "value": "", + "description": "用户任务到期时间", + "popular": true + } + ] + }, + { + "name": "prioritydefinitionpackage", + "properties": [ + { + "id": "prioritydefinition", + "type": "String", + "title": "优先级", + "value": "", + "description": "用户任务优先级", + "popular": true + } + ] + }, + { + "name": "duedatedefinitionpackage", + "properties": [ + { + "id": "duedatedefinition", + "type": "String", + "title": "到期日期", + "value": "", + "description": "Due date of the user task.", + "popular": true + } + ] + }, + { + "name": "servicetaskclasspackage", + "properties": [ + { + "id": "servicetaskclass", + "type": "String", + "title": "监听类", + "value": "", + "description": "Class that implements the service task logic.", + "popular": true + } + ] + }, + { + "name": "servicetaskexpressionpackage", + "properties": [ + { + "id": "servicetaskexpression", + "type": "String", + "title": "表达式", + "value": "", + "description": "Service task logic defined with an expression.", + "popular": true + } + ] + }, + { + "name": "servicetaskdelegateexpressionpackage", + "properties": [ + { + "id": "servicetaskdelegateexpression", + "type": "String", + "title": "委托表达式", + "value": "", + "description": "Service task logic defined with a delegate expression.", + "popular": true + } + ] + }, + { + "name": "servicetaskfieldspackage", + "properties": [ + { + "id": "servicetaskfields", + "type": "Complex", + "title": "字段", + "value": "", + "description": "Field extensions", + "popular": true + } + ] + }, + { + "name": "servicetaskresultvariablepackage", + "properties": [ + { + "id": "servicetaskresultvariable", + "type": "String", + "title": "Result variable name", + "value": "", + "description": "Process variable name to store the service task result.", + "popular": true + } + ] + }, + { + "name": "scriptformatpackage", + "properties": [ + { + "id": "scriptformat", + "type": "String", + "title": "脚本格式", + "value": "", + "description": "Script format of the script task.", + "popular": true + } + ] + }, + { + "name": "scripttextpackage", + "properties": [ + { + "id": "scripttext", + "type": "Text", + "title": "脚本", + "value": "", + "description": "Script text of the script task.", + "popular": true + } + ] + }, + { + "name": "ruletask_rulespackage", + "properties": [ + { + "id": "ruletask_rules", + "type": "String", + "title": "规则", + "value": "", + "description": "Rules of the rule task.", + "popular": true + } + ] + }, + { + "name": "ruletask_variables_inputpackage", + "properties": [ + { + "id": "ruletask_variables_input", + "type": "String", + "title": "输入变量", + "value": "", + "description": "Input variables of the rule task.", + "popular": true + } + ] + }, + { + "name": "ruletask_excludepackage", + "properties": [ + { + "id": "ruletask_exclude", + "type": "Boolean", + "title": "除外", + "value": "false", + "description": "Use the rules property as exclusion.", + "popular": true + } + ] + }, + { + "name": "ruletask_resultpackage", + "properties": [ + { + "id": "ruletask_result", + "type": "String", + "title": "返回变量", + "value": "", + "description": "Result variable of the rule task.", + "popular": true + } + ] + }, + { + "name": "mailtasktopackage", + "properties": [ + { + "id": "mailtaskto", + "type": "Text", + "title": "接收人", + "value": "", + "description": "The recipients if the e-mail. Multiple recipients are defined in a comma-separated list.", + "popular": true + } + ] + }, + { + "name": "mailtaskfrompackage", + "properties": [ + { + "id": "mailtaskfrom", + "type": "Text", + "title": "发件人", + "value": "", + "description": "The sender e-mail address. If not provided, the default configured from address is used.", + "popular": true + } + ] + }, + { + "name": "mailtasksubjectpackage", + "properties": [ + { + "id": "mailtasksubject", + "type": "Text", + "title": "主题", + "value": "", + "description": "The subject of the e-mail.", + "popular": true + } + ] + }, + { + "name": "mailtaskccpackage", + "properties": [ + { + "id": "mailtaskcc", + "type": "Text", + "title": "转发", + "value": "", + "description": "The cc's of the e-mail. Multiple recipients are defined in a comma-separated list", + "popular": true + } + ] + }, + { + "name": "mailtaskbccpackage", + "properties": [ + { + "id": "mailtaskbcc", + "type": "Text", + "title": "密送", + "value": "", + "description": "The bcc's of the e-mail. Multiple recipients are defined in a comma-separated list", + "popular": true + } + ] + }, + { + "name": "mailtasktextpackage", + "properties": [ + { + "id": "mailtasktext", + "type": "Text", + "title": "内容", + "value": "", + "description": "The content of the e-mail, in case one needs to send plain none-rich e-mails. Can be used in combination with html, for e-mail clients that don't support rich content. The client will then fall back to this text-only alternative.", + "popular": true + } + ] + }, + { + "name": "mailtaskhtmlpackage", + "properties": [ + { + "id": "mailtaskhtml", + "type": "Text", + "title": "Html", + "value": "", + "description": "A piece of HTML that is the content of the e-mail.", + "popular": true + } + ] + }, + { + "name": "mailtaskcharsetpackage", + "properties": [ + { + "id": "mailtaskcharset", + "type": "String", + "title": "Charset", + "value": "", + "description": "Allows to change the charset of the email, which is necessary for many non-English languages. ", + "popular": true + } + ] + }, + { + "name": "callactivitycalledelementpackage", + "properties": [ + { + "id": "callactivitycalledelement", + "type": "String", + "title": "被调用元素", + "value": "", + "description": "Process reference.", + "popular": true + } + ] + }, + { + "name": "callactivityinparameterspackage", + "properties": [ + { + "id": "callactivityinparameters", + "type": "Complex", + "title": "输入参数", + "value": "", + "description": "Definition of the input parameters", + "popular": true + } + ] + }, + { + "name": "callactivityoutparameterspackage", + "properties": [ + { + "id": "callactivityoutparameters", + "type": "Complex", + "title": "输出参数", + "value": "", + "description": "Definition of the output parameters", + "popular": true + } + ] + }, + { + "name": "cameltaskcamelcontextpackage", + "properties": [ + { + "id": "cameltaskcamelcontext", + "type": "String", + "title": "Camel内容", + "value": "", + "description": "An optional camel context definition, if left empty the default is used.", + "popular": true + } + ] + }, + { + "name": "muletaskendpointurlpackage", + "properties": [ + { + "id": "muletaskendpointurl", + "type": "String", + "title": "终端url", + "value": "", + "description": "A required endpoint url to sent the message to Mule.", + "popular": true + } + ] + }, + { + "name": "muletasklanguagepackage", + "properties": [ + { + "id": "muletasklanguage", + "type": "String", + "title": "语言", + "value": "", + "description": "A required definition for the language to resolve the payload expression, like juel.", + "popular": true + } + ] + }, + { + "name": "muletaskpayloadexpressionpackage", + "properties": [ + { + "id": "muletaskpayloadexpression", + "type": "String", + "title": "有效载荷表达式", + "value": "", + "description": "A required definition for the payload of the message sent to Mule.", + "popular": true + } + ] + }, + { + "name": "muletaskresultvariablepackage", + "properties": [ + { + "id": "muletaskresultvariable", + "type": "String", + "title": "返回变量", + "value": "", + "description": "An optional result variable for the payload returned.", + "popular": true + } + ] + }, + { + "name": "conditionsequenceflowpackage", + "properties": [ + { + "id": "conditionsequenceflow", + "type": "Complex", + "title": "流转条件", + "value": "", + "description": "The condition of the sequence flow", + "popular": true + } + ] + }, + { + "name": "defaultflowpackage", + "properties": [ + { + "id": "defaultflow", + "type": "Boolean", + "title": "默认流转", + "value": "false", + "description": "Define the sequence flow as default", + "popular": true, + "refToView": "default" + } + ] + }, + { + "name": "conditionalflowpackage", + "properties": [ + { + "id": "conditionalflow", + "type": "Boolean", + "title": "Conditional flow", + "value": "false", + "description": "Define the sequence flow with a condition", + "popular": true + } + ] + }, + { + "name": "timercycledefinitionpackage", + "properties": [ + { + "id": "timercycledefinition", + "type": "String", + "title": "循环时间(例:R3/PT10H)", + "value": "", + "description": "Define the timer with a ISO-8601 cycle.", + "popular": true + } + ] + }, + { + "name": "timerdatedefinitionpackage", + "properties": [ + { + "id": "timerdatedefinition", + "type": "String", + "title": "开始时间(ISO-8601)", + "value": "", + "description": "Define the timer with a ISO-8601 date definition.", + "popular": true + } + ] + }, + { + "name": "timerdurationdefinitionpackage", + "properties": [ + { + "id": "timerdurationdefinition", + "type": "String", + "title": "持续时间(例:PT5M)", + "value": "", + "description": "Define the timer with a ISO-8601 duration.", + "popular": true + } + ] + }, + { + "name": "timerenddatedefinitionpackage", + "properties": [ + { + "id": "timerenddatedefinition", + "type": "String", + "title": "结束时间(ISO-8601)", + "value": "", + "description": "Define the timer with a ISO-8601 duration.", + "popular": true + } + ] + }, + { + "name": "messagerefpackage", + "properties": [ + { + "id": "messageref", + "type": "String", + "title": "消息引用", + "value": "", + "description": "Define the message name.", + "popular": true + } + ] + }, + { + "name": "signalrefpackage", + "properties": [ + { + "id": "signalref", + "type": "String", + "title": "信号引用", + "value": "", + "description": "Define the signal name.", + "popular": true + } + ] + }, + { + "name": "errorrefpackage", + "properties": [ + { + "id": "errorref", + "type": "String", + "title": "错误引用", + "value": "", + "description": "Define the error name.", + "popular": true + } + ] + }, + { + "name": "cancelactivitypackage", + "properties": [ + { + "id": "cancelactivity", + "type": "Boolean", + "title": "取消活动", + "value": "true", + "description": "Should the activity be cancelled", + "popular": true, + "refToView": [ + "frame", + "frame2" + ] + } + ] + }, + { + "name": "initiatorpackage", + "properties": [ + { + "id": "initiator", + "type": "String", + "title": "发起人", + "value": "", + "description": "Initiator of the process.", + "popular": true + } + ] + }, + { + "name": "textpackage", + "properties": [ + { + "id": "text", + "type": "String", + "title": "Text", + "value": "", + "description": "The text of the text annotation.", + "popular": true, + "refToView": "text" + } + ] + }, + { + "name": "multiinstance_typepackage", + "properties": [ + { + "id": "multiinstance_type", + "type": "kisbpm-multiinstance", + "title": "多实例类型", + "value": "None", + "description": "Repeated activity execution (parallel or sequential) can be displayed through different loop types", + "popular": true, + "refToView": "multiinstance" + } + ] + }, + { + "name": "multiinstance_cardinalitypackage", + "properties": [ + { + "id": "multiinstance_cardinality", + "type": "String", + "title": "基数(多实例)", + "value": "", + "description": "Define the cardinality of multi instance.", + "popular": true + } + ] + }, + { + "name": "multiinstance_collectionpackage", + "properties": [ + { + "id": "multiinstance_collection", + "type": "String", + "title": "集合(多实例)", + "value": "", + "description": "Define the collection for the multi instance.", + "popular": true + } + ] + }, + { + "name": "multiinstance_variablepackage", + "properties": [ + { + "id": "multiinstance_variable", + "type": "String", + "title": "元素变量(多实例)", + "value": "", + "description": "Define the element variable for the multi instance.", + "popular": true + } + ] + }, + { + "name": "multiinstance_conditionpackage", + "properties": [ + { + "id": "multiinstance_condition", + "type": "String", + "title": "完成条件(多实例)", + "value": "", + "description": "Define the completion condition for the multi instance.", + "popular": true + } + ] + }, + { + "name": "isforcompensationpackage", + "properties": [ + { + "id": "isforcompensation", + "type": "Boolean", + "title": "是否为补偿", + "value": "false", + "description": "一个标志,标识是否这个活动的目的是为了补偿.", + "popular": true, + "refToView": "compensation" + } + ] + }, + { + "name": "sequencefloworderpackage", + "properties": [ + { + "id": "sequencefloworder", + "type": "Complex", + "title": "流动顺序", + "value": "", + "description": "Order outgoing sequence flows.", + "popular": true + } + ] + }, + { + "name": "signaldefinitionspackage", + "properties": [ + { + "id": "signaldefinitions", + "type": "multiplecomplex", + "title": "信号定义", + "value": "", + "description": "Signal definitions", + "popular": true + } + ] + }, + { + "name": "messagedefinitionspackage", + "properties": [ + { + "id": "messagedefinitions", + "type": "multiplecomplex", + "title": "消息定义", + "value": "", + "description": "Message definitions", + "popular": true + } + ] + }, + { + "name": "istransactionpackage", + "properties": [ + { + "id": "istransaction", + "type": "Boolean", + "title": "是否事务处理子过程", + "value": "false", + "description": "A flag that identifies whether this sub process is of type transaction.", + "popular": true, + "refToView": "border" + } + ] + }, + { + "name": "terminateAllpackage", + "properties": [ + { + "id": "terminateAll", + "type": "Boolean", + "title": "终止全部", + "value": "false", + "description": "Enable to terminate the process instance", + "popular": true + } + ] + } + ], + "stencils": [ + { + "type": "node", + "id": "BPMNDiagram", + "title": "BPMN-Diagram", + "description": "A BPMN 2.0 diagram.", + "view": "\n\n \n \n \n \n \t\n \n", + "icon": "diagram.png", + "groups": [ + "Diagram" + ], + "mayBeRoot": true, + "hide": true, + "propertyPackages": [ + "process_idpackage", + "namepackage", + "documentationpackage", + "process_authorpackage", + "process_versionpackage", + "process_namespacepackage", + "executionlistenerspackage", + "eventlistenerspackage", + "signaldefinitionspackage", + "messagedefinitionspackage" + ], + "hiddenPropertyPackages": [], + "roles": [] + }, + { + "type": "node", + "id": "StartNoneEvent", + "title": "事件", + "description": "A start event without a specific trigger", + "view": "\n\n \n \n \t\n \n \n \n\t\n \n", + "icon": "startevent/none.png", + "groups": [ + "启动事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "initiatorpackage", + "formkeydefinitionpackage", + "formpropertiespackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "Startevents_all", + "StartEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "StartTimerEvent", + "title": "定时事件", + "description": "A start event with a timer trigger", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", + "icon": "startevent/timer.png", + "groups": [ + "启动事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "timercycledefinitionpackage", + "timerdatedefinitionpackage", + "timerdurationdefinitionpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "Startevents_all", + "StartEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "StartSignalEvent", + "title": "信号事件", + "description": "A start event with a signal trigger", + "view": "\n\n \n \n \t\n \n \n\n \n \n \n\t\n \n", + "icon": "startevent/signal.png", + "groups": [ + "启动事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "signalrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "Startevents_all", + "StartEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "StartMessageEvent", + "title": "消息事件", + "description": "A start event with a message trigger", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", + "icon": "startevent/message.png", + "groups": [ + "启动事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "messagerefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "Startevents_all", + "StartEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "StartErrorEvent", + "title": "异常事件", + "description": "A start event that catches a thrown BPMN error", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", + "icon": "startevent/error.png", + "groups": [ + "启动事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "errorrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "Startevents_all", + "StartEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "UserTask", + "title": "用户活动", + "description": "分配给特定人的任务 ", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.user.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "usertaskassignmentpackage", + "formkeydefinitionpackage", + "duedatedefinitionpackage", + "prioritydefinitionpackage", + "formpropertiespackage", + "tasklistenerspackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "ServiceTask", + "title": "服务任务", + "description": "An automatic task with service logic", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.service.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "servicetaskclasspackage", + "servicetaskexpressionpackage", + "servicetaskdelegateexpressionpackage", + "servicetaskfieldspackage", + "servicetaskresultvariablepackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "ScriptTask", + "title": "脚本任务", + "description": "An automatic task with script logic", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.script.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "scriptformatpackage", + "scripttextpackage", + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "BusinessRule", + "title": "规则任务", + "description": "An automatic task with rule logic", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n \t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.business.rule.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "ruletask_rulespackage", + "ruletask_variables_inputpackage", + "ruletask_excludepackage", + "ruletask_resultpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "ReceiveTask", + "title": "接受任务", + "description": "An task that waits for a signal", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.receive.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "ManualTask", + "title": "手工任务", + "description": "An automatic task with no logic", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n \t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.manual.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "MailTask", + "title": "邮件任务", + "description": "An mail task", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.send.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "mailtasktopackage", + "mailtaskfrompackage", + "mailtasksubjectpackage", + "mailtaskccpackage", + "mailtaskbccpackage", + "mailtasktextpackage", + "mailtaskhtmlpackage", + "mailtaskcharsetpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "CamelTask", + "title": "Camel任务", + "description": "An task that sends a message to Camel", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.camel.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "cameltaskcamelcontextpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "MuleTask", + "title": "Mule任务", + "description": "An task that sends a message to Mule", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.mule.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage", + "muletaskendpointurlpackage", + "muletasklanguagepackage", + "muletaskpayloadexpressionpackage", + "muletaskresultvariablepackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "SendTask", + "title": "Send task", + "description": "An task that sends a message", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n\t\t\n\t\t\n \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/list/type.send.png", + "groups": [ + "活动列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "ActivitiesMorph", + "all" + ] + }, + { + "type": "node", + "id": "SubProcess", + "title": "子流程", + "description": "子流程范围", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n \n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\t\n\t\n \n", + "icon": "activity/expanded.subprocess.png", + "groups": [ + "结构列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "istransactionpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EventSubProcess", + "title": "事件子流程", + "description": "一个事件周期的子流程", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \n \n\t\n\t\n \t\n\t\t\n \t\n\t\n\t\n \n", + "icon": "activity/event.subprocess.png", + "groups": [ + "结构列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "all" + ] + }, + { + "type": "node", + "id": "CallActivity", + "title": "调用活动", + "description": "一个调用活动", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \t\n \n \n\t\n \n\t\n\t\t\n\t\t\n \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n \n", + "icon": "activity/task.png", + "groups": [ + "结构列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "executionlistenerspackage", + "callactivitycalledelementpackage", + "callactivityinparameterspackage", + "callactivityoutparameterspackage", + "multiinstance_typepackage", + "multiinstance_cardinalitypackage", + "multiinstance_collectionpackage", + "multiinstance_variablepackage", + "multiinstance_conditionpackage", + "isforcompensationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "Activity", + "sequence_start", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "ExclusiveGateway", + "title": "互斥网关", + "description": "一个选择的网关", + "view": "\n\n \n \n \n \t\t\t\t\t\n \n \n \n \n \n \n \n\t\n\t\n\t\n \n\n", + "icon": "gateway/exclusive.databased.png", + "groups": [ + "网关列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "sequencefloworderpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "GatewaysMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "ParallelGateway", + "title": "并行网关", + "description": "一个并行的网关", + "view": "\n\n \n \n \n \n \n \n \n \n\t\n\t\n \n\n", + "icon": "gateway/parallel.png", + "groups": [ + "网关列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "sequencefloworderpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "GatewaysMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "InclusiveGateway", + "title": "包容性网关", + "description": "一个包容性网关", + "view": "\n\n \n \n \n \n\n \n \n \n\t\n\t\n \n\n", + "icon": "gateway/inclusive.png", + "groups": [ + "网关列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "sequencefloworderpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "GatewaysMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EventGateway", + "title": "事件网关", + "description": "一个事件网关", + "view": "\n\n \n \n \n \n \n \t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\n \t\n\t\n\n", + "icon": "gateway/eventbased.png", + "groups": [ + "网关列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "asynchronousdefinitionpackage", + "exclusivedefinitionpackage", + "sequencefloworderpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "GatewaysMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "BoundaryErrorEvent", + "title": "边界错误事件", + "description": "一个捕捉BPMN异常的边界事件", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n \n\t\n \n", + "icon": "catching/error.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "errorrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary" + ] + }, + { + "type": "node", + "id": "BoundaryTimerEvent", + "title": "定时边界事件", + "description": "一个定时触发的边界事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n \n \n \t\n\t\n \n", + "icon": "catching/timer.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "timercycledefinitionpackage", + "timerdatedefinitionpackage", + "timerdurationdefinitionpackage", + "timerenddatedefinitionpackage", + "cancelactivitypackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary" + ] + }, + { + "type": "node", + "id": "BoundarySignalEvent", + "title": "边界信号事件", + "description": "一个信号触发的边界事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n\t\n\t\n \n", + "icon": "catching/signal.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "signalrefpackage", + "cancelactivitypackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary" + ] + }, + { + "type": "node", + "id": "BoundaryMessageEvent", + "title": "边界消息事件", + "description": "一个边界消息事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \t\n \n \n \n\t\n\t\t\n\t\n\t\n\t\n \n", + "icon": "catching/message.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "messagerefpackage", + "cancelactivitypackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary" + ] + }, + { + "type": "node", + "id": "BoundaryCancelEvent", + "title": "边界取消事件", + "description": "一个边界取消事件", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n \n \n\t\n \n", + "icon": "catching/cancel.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary" + ] + }, + { + "type": "node", + "id": "BoundaryCompensationEvent", + "title": "边界修正事件", + "description": "一个边界修正事件", + "view": "\n\n \n \n \t\n \n \n \n\t\n \n \n \n \n \n\t\n \n", + "icon": "catching/compensation.png", + "groups": [ + "边界事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "BoundaryEventsMorph", + "IntermediateEventOnActivityBoundary", + "all" + ] + }, + { + "type": "node", + "id": "CatchTimerEvent", + "title": "中间定时器捕获事件", + "description": "定时器触发的中间捕获事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n \n \n \t\n\t\n \n", + "icon": "catching/timer.png", + "groups": [ + "中间捕获事件列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "timercycledefinitionpackage", + "timerdatedefinitionpackage", + "timerdurationdefinitionpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "sequence_end", + "CatchEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "CatchSignalEvent", + "title": "中间信号捕获事件", + "description": "信号触发的捕获事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \n \n \n\t\n\t\n \n", + "icon": "catching/signal.png", + "groups": [ + "中间捕获事件列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "signalrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "sequence_end", + "CatchEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "CatchMessageEvent", + "title": "中间消息捕获事件", + "description": "一个消息触发的中间捕获事件", + "view": "\n\n \n \n \t\n \n \n \n \n \t\n \n \t\n \n \n \n\t\n\t\t\n\t\n\t\n\t\n \n", + "icon": "catching/message.png", + "groups": [ + "中间捕获事件列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "messagerefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "sequence_start", + "sequence_end", + "CatchEventsMorph", + "all" + ] + }, + { + "type": "node", + "id": "ThrowNoneEvent", + "title": "中间抛出事件", + "description": "无触发器的中间抛出事件", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", + "icon": "throwing/none.png", + "groups": [ + "中间抛出事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ThrowEventsMorph", + "sequence_start", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "ThrowSignalEvent", + "title": "信号中间抛出事件", + "description": "一个信号触发的中间抛出事件", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", + "icon": "throwing/signal.png", + "groups": [ + "中间抛出事件" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "signalrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ThrowEventsMorph", + "sequence_start", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EndNoneEvent", + "title": "结束任务", + "description": "一个无触发器的结束任务", + "view": "\n\n \n \n \t\n \n \n \n\t\n \n", + "icon": "endevent/none.png", + "groups": [ + "结束任务列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "EndEventsMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EndErrorEvent", + "title": "结束错误任务", + "description": "An end event that throws an error event", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", + "icon": "endevent/error.png", + "groups": [ + "结束任务列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "errorrefpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "EndEventsMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EndCancelEvent", + "title": "结束取消任务", + "description": "A cancel end event", + "view": "\n\n \n \n \t\n \n \n \n \n \n\t\n \n", + "icon": "endevent/cancel.png", + "groups": [ + "结束任务列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "EndEventsMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "EndTerminateEvent", + "title": "终结任务", + "description": "A terminate end event", + "view": "\n\n \n \n \t\n \n \n \n \n \n\t\n \n", + "icon": "endevent/terminate.png", + "groups": [ + "结束任务列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "executionlistenerspackage", + "terminateAllpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "EndEventsMorph", + "sequence_end", + "all" + ] + }, + { + "type": "node", + "id": "Pool", + "title": "池", + "description": "A pool to stucture the process definition", + "view": "\n\n \n \n \t\n \t\n \t\n \t\n \t\n \n \n \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t \t\n \t\n \n \n\t\n\t\n\t\n\t\n \n \n \n", + "icon": "swimlane/pool.png", + "groups": [ + "泳道列表" + ], + "layout": [ + { + "type": "layout.bpmn2_0.pool" + } + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "process_idpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "canContainArtifacts", + "all" + ] + }, + { + "type": "node", + "id": "Lane", + "title": "泳道", + "description": "A lane to stucture the process definition", + "view": "\n\n \n \n \n \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n \t\t\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n \n\t\n \n", + "icon": "swimlane/lane.png", + "groups": [ + "泳道列表" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "PoolChild", + "canContainArtifacts", + "all" + ] + }, + { + "type": "edge", + "id": "SequenceFlow", + "title": "顺序流", + "description": "顺序流定义活动的执行顺序", + "view": "\r\n\r\n\t\r\n\t \t\r\n\t \t\t\r\n\t\t\t\r\n\t \t\r\n\t \t\r\n\t \t\t\r\n\t \t\r\n\t\r\n\t\r\n\t\t\r\n\t\t\r\n\t\r\n", + "icon": "connector/sequenceflow.png", + "groups": [ + "连接对象" + ], + "layout": [ + { + "type": "layout.bpmn2_0.sequenceflow" + } + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "conditionsequenceflowpackage", + "executionlistenerspackage", + "defaultflowpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ConnectingObjectsMorph", + "all" + ] + }, + { + "type": "edge", + "id": "MessageFlow", + "title": "消息流", + "description": "Message flow to connect elements in different pools.", + "view": "\r\n\r\n\t\r\n\t\t\r\n\t \t\t\r\n\t \t\t\r\n\t \t\r\n\r\n\t \t\r\n\t \t\t\r\n\t \t\r\n\t\r\n\t\r\n\t \r\n\t\t\r\n\t\r\n", + "icon": "connector/messageflow.png", + "groups": [ + "连接对象" + ], + "layout": [ + { + "type": "layout.bpmn2_0.sequenceflow" + } + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ConnectingObjectsMorph", + "all" + ] + }, + { + "type": "edge", + "id": "Association", + "title": "注释", + "description": "连接一个注释到指定元素", + "view": "\r\n\r\n\t\r\n\t \r\n\t\t\r\n\t\r\n", + "icon": "connector/association.undirected.png", + "groups": [ + "连接对象" + ], + "layout": [ + { + "type": "layout.bpmn2_0.sequenceflow" + } + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ConnectingObjectsMorph", + "all" + ] + }, + { + "type": "edge", + "id": "DataAssociation", + "title": "日期注释", + "description": "连接一个日期注释到指定元素", + "view": "\r\n\r\n\t\r\n\t \t\r\n\t \t\t\r\n\t \t\r\n\t\r\n\t\r\n\t \r\n\t\t\r\n\t\r\n", + "icon": "connector/association.unidirectional.png", + "groups": [ + "连接对象" + ], + "layout": [ + { + "type": "layout.bpmn2_0.sequenceflow" + } + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "ConnectingObjectsMorph", + "all" + ] + }, + { + "type": "node", + "id": "TextAnnotation", + "title": "文本注释", + "description": "连接一个文本注释到指定元素", + "view": "\n\n \n \n \t\n \n \n \n \n \n \n\t\n \n", + "icon": "artifact/text.annotation.png", + "groups": [ + "加工" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage", + "textpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "all" + ] + }, + { + "type": "node", + "id": "DataStore", + "title": "Data store", + "description": "Reference to a data store.", + "view": "\r\n\r\n\t\r\n\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\r\n\t\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t \t\r\n\t\t\r\n\t\t\t \r\n\t\r\n\r\n", + "icon": "dataobject/data.store.png", + "groups": [ + "Artifacts" + ], + "propertyPackages": [ + "overrideidpackage", + "namepackage", + "documentationpackage" + ], + "hiddenPropertyPackages": [], + "roles": [ + "all" + ] + } + ], + "rules": { + "cardinalityRules": [ + { + "role": "Startevents_all", + "incomingEdges": [ + { + "role": "SequenceFlow", + "maximum": 0 + } + ] + }, + { + "role": "Endevents_all", + "outgoingEdges": [ + { + "role": "SequenceFlow", + "maximum": 0 + } + ] + } + ], + "connectionRules": [ + { + "role": "SequenceFlow", + "connects": [ + { + "from": "sequence_start", + "to": [ + "sequence_end" + ] + } + ] + }, + { + "role": "Association", + "connects": [ + { + "from": "sequence_start", + "to": [ + "TextAnnotation" + ] + }, + { + "from": "sequence_end", + "to": [ + "TextAnnotation" + ] + }, + { + "from": "TextAnnotation", + "to": [ + "sequence_end" + ] + }, + { + "from": "BoundaryCompensationEvent", + "to": [ + "sequence_end" + ] + }, + { + "from": "TextAnnotation", + "to": [ + "sequence_start" + ] + }, + { + "from": "BoundaryCompensationEvent", + "to": [ + "sequence_start" + ] + } + ] + }, + { + "role": "DataAssociation", + "connects": [ + { + "from": "sequence_start", + "to": [ + "DataStore" + ] + }, + { + "from": "sequence_end", + "to": [ + "DataStore" + ] + }, + { + "from": "DataStore", + "to": [ + "sequence_end" + ] + }, + { + "from": "DataStore", + "to": [ + "sequence_start" + ] + } + ] + }, + { + "role": "IntermediateEventOnActivityBoundary", + "connects": [ + { + "from": "Activity", + "to": [ + "IntermediateEventOnActivityBoundary" + ] + } + ] + } + ], + "containmentRules": [ + { + "role": "BPMNDiagram", + "contains": [ + "all" + ] + }, + { + "role": "SubProcess", + "contains": [ + "sequence_start", + "sequence_end", + "from_task_event", + "to_task_event", + "EventSubProcess", + "TextAnnotation", + "DataStore" + ] + }, + { + "role": "EventSubProcess", + "contains": [ + "sequence_start", + "sequence_end", + "from_task_event", + "to_task_event", + "TextAnnotation", + "DataStore" + ] + }, + { + "role": "Pool", + "contains": [ + "Lane" + ] + }, + { + "role": "Lane", + "contains": [ + "sequence_start", + "sequence_end", + "EventSubProcess", + "TextAnnotation", + "DataStore" + ] + } + ], + "morphingRules": [ + { + "role": "ActivitiesMorph", + "baseMorphs": [ + "UserTask" + ], + "preserveBounds": true + }, + { + "role": "GatewaysMorph", + "baseMorphs": [ + "ExclusiveGateway" + ] + }, + { + "role": "StartEventsMorph", + "baseMorphs": [ + "StartNoneEvent" + ] + }, + { + "role": "EndEventsMorph", + "baseMorphs": [ + "StartNoneEvent" + ] + }, + { + "role": "CatchEventsMorph", + "baseMorphs": [ + "CatchTimerEvent" + ] + }, + { + "role": "ThrowEventsMorph", + "baseMorphs": [ + "ThrowNoneEvent" + ] + }, + { + "role": "BoundaryEventsMorph", + "baseMorphs": [ + "ThrowNoneEvent" + ] + }, + { + "role": "BoundaryCompensationEvent", + "baseMorphs": [ + "BoundaryCompensationEvent" + ] + }, + { + "role": "TextAnnotation", + "baseMorphs": [ + "TextAnnotation" + ] + }, + { + "role": "DataStore", + "baseMorphs": [ + "DataStore" + ] + } + ] + } +} diff --git a/skyeye-flowable/pom.xml b/skyeye-flowable/pom.xml new file mode 100644 index 0000000..52a42e3 --- /dev/null +++ b/skyeye-flowable/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-flowable + 1.0-SNAPSHOT + pom + + + flowable-common + flowable-web + flowable-main + flowable-entity + + + + 6.4.2 + + + + + + + org.flowable + flowable-spring-boot-starter + ${flowable.version} + + + + + org.flowable + flowable-json-converter + ${flowable.version} + + + org.flowable + flowable-bpmn-converter + ${flowable.version} + + + + + org.flowable + flowable-ui-modeler-rest + ${flowable.version} + + + + + \ No newline at end of file diff --git a/skyeye-ifs/.gitignore b/skyeye-ifs/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-ifs/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ifs/ifs-common/.gitignore b/skyeye-ifs/ifs-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-ifs/ifs-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ifs/ifs-common/pom.xml b/skyeye-ifs/ifs-common/pom.xml new file mode 100644 index 0000000..c329c4f --- /dev/null +++ b/skyeye-ifs/ifs-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-ifs + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ifs-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-ifs/ifs-pro/.gitignore b/skyeye-ifs/ifs-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-ifs/ifs-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ifs/ifs-pro/pom.xml b/skyeye-ifs/ifs-pro/pom.xml new file mode 100644 index 0000000..55d7479 --- /dev/null +++ b/skyeye-ifs/ifs-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-ifs + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ifs-pro + + + + + com.skyeye + ifs-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/controller/AccountController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/controller/AccountController.java new file mode 100644 index 0000000..0d23130 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/controller/AccountController.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.account.controller; + +import com.skyeye.account.entity.Account; +import com.skyeye.account.service.AccountService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AccountController + * @Description: 结算账户管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/6 9:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "账户管理", tags = "账户管理", modelName = "账户管理") +public class AccountController { + + @Autowired + private AccountService accountService; + + /** + * 查询账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "account001", value = "查询账户信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AccountController/queryAccountList") + public void queryAccountList(InputObject inputObject, OutputObject outputObject) { + accountService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAccount", value = "添加/编辑账户信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Account.class) + @RequestMapping("/post/AccountController/writeAccount") + public void writeAccount(InputObject inputObject, OutputObject outputObject) { + accountService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAccountById", value = "根据id查询账户信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AccountController/queryAccountById") + public void queryAccountById(InputObject inputObject, OutputObject outputObject) { + accountService.selectById(inputObject, outputObject); + } + + /** + * 根据id批量查询账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAccountListById", value = "根据id批量查询账户信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/AccountController/queryAccountListById") + public void queryAccountListById(InputObject inputObject, OutputObject outputObject) { + accountService.selectByIds(inputObject, outputObject); + } + + /** + * 根据id删除账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "account004", value = "根据id删除账户信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AccountController/deleteAccountById") + public void deleteAccountById(InputObject inputObject, OutputObject outputObject) { + accountService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有的账户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "account009", value = "获取所有的账户信息", method = "GET", allUse = "2") + @RequestMapping("/post/AccountController/queryAllAccountList") + public void queryAllAccountList(InputObject inputObject, OutputObject outputObject) { + accountService.queryAllAccountList(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/dao/AccountDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/dao/AccountDao.java new file mode 100644 index 0000000..ec0d271 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/dao/AccountDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.account.dao; + +import com.skyeye.account.entity.Account; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AccountDao + * @Description: 财务账户数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/24 21:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AccountDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/entity/Account.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/entity/Account.java new file mode 100644 index 0000000..e5d6301 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/entity/Account.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.account.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Account + * @Description: 账户信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.IFS_ACCOUNT_CACHE_KEY) +@TableName(value = "ifs_account", autoResultMap = true) +@ApiModel("账户信息实体类") +public class Account extends BaseGeneralInfo { + + @TableField(value = "serial_no") + @ApiModelProperty(value = "编号", required = "required") + private String serialNo; + + @TableField(value = "initial_amount", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "期初金额") + private String initialAmount; + + @TableField(value = "current_amount") + @Property(value = "当前金额") + private String currentAmount; + + @TableField(value = "is_default") + @ApiModelProperty(value = "是否默认,参考#IsDefaultEnum", required = "required,num") + private Integer isDefault; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/AccountService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/AccountService.java new file mode 100644 index 0000000..b402414 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/AccountService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.account.service; + +import com.skyeye.account.entity.Account; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AccountService + * @Description: 财务账户服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/11/24 21:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AccountService extends SkyeyeBusinessService { + + void queryAllAccountList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/impl/AccountServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/impl/AccountServiceImpl.java new file mode 100644 index 0000000..00a2b23 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/account/service/impl/AccountServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.account.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.account.dao.AccountDao; +import com.skyeye.account.entity.Account; +import com.skyeye.account.service.AccountService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AccountServiceImpl + * @Description: 账户信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "账户管理", groupName = "账户管理") +public class AccountServiceImpl extends SkyeyeBusinessServiceImpl implements AccountService { + + @Override + public void createPrepose(Account entity) { + entity.setCurrentAmount(entity.getInitialAmount()); + } + + @Override + public void updatePrepose(Account entity) { + entity.setInitialAmount(null); + } + + @Override + public void writePostpose(Account entity, String userId) { + if (entity.getIsDefault().equals(IsDefaultEnum.IS_DEFAULT.getKey())) { + // 如果将当前数据修改为默认数据,则需要修改之前的数据为非默认 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.ne(CommonConstants.ID, entity.getId()); + updateWrapper.eq(MybatisPlusUtil.toColumns(Account::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Account::getIsDefault), IsDefaultEnum.NOT_DEFAULT.getKey()); + update(updateWrapper); + } + } + + /** + * 获取账户信息展示为下拉框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllAccountList(InputObject inputObject, OutputObject outputObject) { + List> beans = queryAllDataForMap(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/controller/IfsSetOfBooksController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/controller/IfsSetOfBooksController.java new file mode 100644 index 0000000..201db72 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/controller/IfsSetOfBooksController.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.books.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.books.entity.SetOfBooks; +import com.skyeye.books.service.IfsSetOfBooksService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IfsSetOfBooksController + * @Description: 账套管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "账套管理", tags = "账套管理", modelName = "账套管理") +public class IfsSetOfBooksController { + + @Autowired + private IfsSetOfBooksService ifsSetOfBooksService; + + /** + * 获取账套列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifssetofbooks001", value = "获取账套列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/IfsSetOfBooksController/queryIfsSetOfBooksList") + public void queryIfsSetOfBooksList(InputObject inputObject, OutputObject outputObject) { + ifsSetOfBooksService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑账套信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeIfsSetOfBooks", value = "新增/编辑账套信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SetOfBooks.class) + @RequestMapping("/post/IfsSetOfBooksController/writeIfsSetOfBooks") + public void writeIfsSetOfBooks(InputObject inputObject, OutputObject outputObject) { + ifsSetOfBooksService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除账套信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifssetofbooks005", value = "删除账套信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/IfsSetOfBooksController/deleteIfsSetOfBooksById") + public void deleteIfsSetOfBooksById(InputObject inputObject, OutputObject outputObject) { + ifsSetOfBooksService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/dao/IfsSetOfBooksDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/dao/IfsSetOfBooksDao.java new file mode 100644 index 0000000..7ee0dc8 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/dao/IfsSetOfBooksDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.books.dao; + +import com.skyeye.books.entity.SetOfBooks; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: IfsSetOfBooksDao + * @Description: 账套管理数据层 + * @author: skyeye云系列 + * @date: 2021/11/21 14:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsSetOfBooksDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/entity/SetOfBooks.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/entity/SetOfBooks.java new file mode 100644 index 0000000..6f1d290 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/entity/SetOfBooks.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.books.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: SetOfBooks + * @Description: 账套信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "ifs:setOfBooks") +@TableName(value = "ifs_set_of_books", autoResultMap = true) +@ApiModel("账套信息实体类") +public class SetOfBooks extends BaseGeneralInfo { + + @TableField(value = "start_time") + @ApiModelProperty(value = "开始日期", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "结束日期", required = "required") + private String endTime; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/IfsSetOfBooksService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/IfsSetOfBooksService.java new file mode 100644 index 0000000..8594954 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/IfsSetOfBooksService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.books.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.books.entity.SetOfBooks; + +/** + * @ClassName: IfsSetOfBooksService + * @Description: 账套管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsSetOfBooksService extends SkyeyeBusinessService { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/impl/IfsSetOfBooksServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/impl/IfsSetOfBooksServiceImpl.java new file mode 100644 index 0000000..f47b1c0 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/books/service/impl/IfsSetOfBooksServiceImpl.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.books.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.books.dao.IfsSetOfBooksDao; +import com.skyeye.books.entity.SetOfBooks; +import com.skyeye.books.service.IfsSetOfBooksService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IfsSetOfBooksServiceImpl + * @Description: 账套管理服务类 + * @author: skyeye云系列 + * @date: 2021/11/21 14:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "账套管理", groupName = "账套管理") +public class IfsSetOfBooksServiceImpl extends SkyeyeBusinessServiceImpl implements IfsSetOfBooksService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + for (Map bean : beans) { + String startTime = bean.get("startTime").toString(); + String endTime = bean.get("endTime").toString(); + String currentTime = DateUtil.getYmdTimeAndToString(); + if (DateUtil.getDistanceDay(startTime, currentTime) >= 0 && DateUtil.getDistanceDay(currentTime, endTime) >= 0) { + // startTime <= 当前时间 <= endTime + bean.put("haveAccess", true); + } else { + bean.put("haveAccess", false); + } + } + return beans; + } + +} + diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/classenum/IncomeAndExpenseType.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/classenum/IncomeAndExpenseType.java new file mode 100644 index 0000000..a996c61 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/classenum/IncomeAndExpenseType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: IncomeAndExpenseType + * @Description: 收支项目类型的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/24 22:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum IncomeAndExpenseType implements SkyeyeEnumClass { + + INCOME(1, "收入", true, true), + EXPENSE(2, "支出", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/controller/IncomeAndExpenseController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/controller/IncomeAndExpenseController.java new file mode 100644 index 0000000..7eca387 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/controller/IncomeAndExpenseController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.incomeandexpense.entity.IncomeAndExpense; +import com.skyeye.incomeandexpense.service.IncomeAndExpenseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IncomeAndExpenseController + * @Description: 收支项目管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/21 17:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "收支项目管理", tags = "收支项目管理", modelName = "收支项目管理") +public class IncomeAndExpenseController { + + @Autowired + private IncomeAndExpenseService incomeAndExpenseService; + + /** + * 获取收支项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inoutitem001", value = "获取收支项目信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/InoutitemController/queryInoutitemList") + public void queryInoutitemList(InputObject inputObject, OutputObject outputObject) { + incomeAndExpenseService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑收支项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeIncomeAndExpense", value = "添加/编辑收支项目", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = IncomeAndExpense.class) + @RequestMapping("/post/InoutitemController/writeIncomeAndExpense") + public void writeIncomeAndExpense(InputObject inputObject, OutputObject outputObject) { + incomeAndExpenseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除收支项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inoutitem004", value = "删除收支项目信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/InoutitemController/deleteInoutitemById") + public void deleteInoutitemById(InputObject inputObject, OutputObject outputObject) { + incomeAndExpenseService.deleteById(inputObject, outputObject); + } + + /** + * 根据条件查询收支项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "inoutitem007", value = "根据条件查询收支项目", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "type", name = "type", value = "收支类型", required = "required,num")}) + @RequestMapping("/post/InoutitemController/queryInoutitemListByType") + public void queryInoutitemListByType(InputObject inputObject, OutputObject outputObject) { + incomeAndExpenseService.queryInoutitemListByType(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/dao/IncomeAndExpenseDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/dao/IncomeAndExpenseDao.java new file mode 100644 index 0000000..ca53d04 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/dao/IncomeAndExpenseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.incomeandexpense.entity.IncomeAndExpense; + +/** + * @ClassName: IncomeAndExpenseDao + * @Description: 收支项目信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeAndExpenseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/entity/IncomeAndExpense.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/entity/IncomeAndExpense.java new file mode 100644 index 0000000..b7ac4bc --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/entity/IncomeAndExpense.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.subject.entity.AccountSubject; +import lombok.Data; + +/** + * @ClassName: IncomeAndExpense + * @Description: 收支信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "ifs:incomeAndExpense") +@TableName(value = "ifs_income_and_expense", autoResultMap = true) +@ApiModel("收支信息实体类") +public class IncomeAndExpense extends BaseGeneralInfo { + + @TableField(value = "type") + @ApiModelProperty(value = "类型,参考#IncomeAndExpenseType", required = "required,num") + private Integer type; + + @TableField(value = "subject_id") + @ApiModelProperty(value = "会计科目id") + private String subjectId; + + @TableField(exist = false) + @Property(value = "会计科目信息") + private AccountSubject subjectMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/IncomeAndExpenseService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/IncomeAndExpenseService.java new file mode 100644 index 0000000..ff9a112 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/IncomeAndExpenseService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.incomeandexpense.entity.IncomeAndExpense; + +/** + * @ClassName: IncomeAndExpenseService + * @Description: 收支项目管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/21 17:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeAndExpenseService extends SkyeyeBusinessService { + + void queryInoutitemListByType(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/impl/IncomeAndExpenseServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/impl/IncomeAndExpenseServiceImpl.java new file mode 100644 index 0000000..da522a9 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/incomeandexpense/service/impl/IncomeAndExpenseServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.incomeandexpense.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.incomeandexpense.dao.IncomeAndExpenseDao; +import com.skyeye.incomeandexpense.entity.IncomeAndExpense; +import com.skyeye.incomeandexpense.service.IncomeAndExpenseService; +import com.skyeye.subject.service.IfsAccountSubjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IncomeAndExpenseServiceImpl + * @Description: 收支项目信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "收支项目管理", groupName = "收支项目管理") +public class IncomeAndExpenseServiceImpl extends SkyeyeBusinessServiceImpl implements IncomeAndExpenseService { + + @Autowired + private IfsAccountSubjectService ifsAccountSubjectService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + ifsAccountSubjectService.setMationForMap(beans, "subjectId", "subjectMation"); + return beans; + } + + /** + * 根据条件查询收支项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInoutitemListByType(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String type = params.get("type").toString(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(IncomeAndExpense::getType), type); + queryWrapper.eq(MybatisPlusUtil.toColumns(IncomeAndExpense::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + + List beans = list(queryWrapper); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanBorrowController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanBorrowController.java new file mode 100644 index 0000000..39aa96c --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanBorrowController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.loan.entity.LoanBorrow; +import com.skyeye.loan.service.LoanBorrowService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LoanBorrowController + * @Description: 借款单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "借款单", tags = "借款单", modelName = "借款单") +public class LoanBorrowController { + + @Autowired + private LoanBorrowService loanBorrowService; + + /** + * 查询借款单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLoanBorrowList", value = "查询借款单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LoanBorrowController/queryLoanBorrowList") + public void queryLoanBorrowList(InputObject inputObject, OutputObject outputObject) { + loanBorrowService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑借款单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLoanBorrow", value = "新增/编辑借款单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LoanBorrow.class) + @RequestMapping("/post/LoanBorrowController/writeLoanBorrow") + public void writeLoanBorrow(InputObject inputObject, OutputObject outputObject) { + loanBorrowService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除借款单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLoanBorrowById", value = "删除借款单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LoanBorrowController/deleteLoanBorrowById") + public void deleteLoanBorrowById(InputObject inputObject, OutputObject outputObject) { + loanBorrowService.deleteById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitLoanBorrowToApproval", value = "借款单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/LoanBorrowController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + loanBorrowService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeLoanBorrow", value = "撤销借款单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/LoanBorrowController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + loanBorrowService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanRepayController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanRepayController.java new file mode 100644 index 0000000..c80e579 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/controller/LoanRepayController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.loan.entity.LoanRepay; +import com.skyeye.loan.service.LoanRepayService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LoanRepayController + * @Description: 还款单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:22 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "还款单", tags = "还款单", modelName = "还款单") +public class LoanRepayController { + + @Autowired + private LoanRepayService loanRepayService; + + /** + * 查询还款单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLoanRepayList", value = "查询还款单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LoanRepayController/queryLoanRepayList") + public void queryLoanRepayList(InputObject inputObject, OutputObject outputObject) { + loanRepayService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑还款单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLoanRepay", value = "新增/编辑还款单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = LoanRepay.class) + @RequestMapping("/post/LoanRepayController/writeLoanRepay") + public void writeLoanRepay(InputObject inputObject, OutputObject outputObject) { + loanRepayService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除还款单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLoanRepayById", value = "删除还款单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LoanRepayController/deleteLoanRepayById") + public void deleteLoanRepayById(InputObject inputObject, OutputObject outputObject) { + loanRepayService.deleteById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitLoanRepayToApproval", value = "还款单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/LoanRepayController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + loanRepayService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeLoanRepay", value = "撤销还款单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/LoanRepayController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + loanRepayService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanBorrowDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanBorrowDao.java new file mode 100644 index 0000000..622e08a --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanBorrowDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.loan.entity.LoanBorrow; + +/** + * @ClassName: LoanBorrowDao + * @Description: 借款单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LoanBorrowDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanRepayDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanRepayDao.java new file mode 100644 index 0000000..442d536 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/LoanRepayDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.loan.entity.LoanRepay; + +/** + * @ClassName: LoanRepayDao + * @Description: 还款单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LoanRepayDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/UserLoanDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/UserLoanDao.java new file mode 100644 index 0000000..ec38052 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/dao/UserLoanDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.loan.entity.UserLoan; + +/** + * @ClassName: UserLoanDao + * @Description: 用户借款金额数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UserLoanDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanBorrow.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanBorrow.java new file mode 100644 index 0000000..528548f --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanBorrow.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: LoanBorrow + * @Description: 借款单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ifs:loanBorrow", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "ifs_loan_borrow", autoResultMap = true) +@ApiModel("借款单实体类") +public class LoanBorrow extends SkyeyeFlowable { + + @TableField(value = "purpose") + @ApiModelProperty(value = "借款用途", required = "required") + private String purpose; + + @TableField(value = "collection_name") + @ApiModelProperty(value = "收款人全称", required = "required") + private String collectionName; + + @TableField(value = "collection_code") + @ApiModelProperty(value = "收款账号") + private String collectionCode; + + @TableField(value = "pay_type_id") + @ApiModelProperty(value = "付款方式id,参考数据字典", required = "required") + private String payTypeId; + + @TableField(exist = false) + @Property(value = "付款方式信息") + private Map payTypeMation; + + @TableField(value = "opening_bank") + @ApiModelProperty(value = "开户行") + private String openingBank; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "price") + @ApiModelProperty(value = "借款金额", required = "required,double") + private String price; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanRepay.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanRepay.java new file mode 100644 index 0000000..5e8339f --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/LoanRepay.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: LoanRepay + * @Description: 还款单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ifs:loanRepay", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "ifs_loan_repay", autoResultMap = true) +@ApiModel("还款单实体类") +public class LoanRepay extends SkyeyeFlowable { + + @TableField(value = "collection_name") + @ApiModelProperty(value = "收款人全称", required = "required") + private String collectionName; + + @TableField(value = "collection_code") + @ApiModelProperty(value = "收款账号") + private String collectionCode; + + @TableField(value = "pay_type_id") + @ApiModelProperty(value = "付款方式id,参考数据字典", required = "required") + private String payTypeId; + + @TableField(exist = false) + @Property(value = "付款方式信息") + private Map payTypeMation; + + @TableField(value = "opening_bank") + @ApiModelProperty(value = "开户行") + private String openingBank; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "price") + @ApiModelProperty(value = "还款金额", required = "required,double") + private String price; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/UserLoan.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/UserLoan.java new file mode 100644 index 0000000..3e144ae --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/entity/UserLoan.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: UserLoan + * @Description: 用户借款金额实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ifs:userLoan", value = {"id", "userId"}, cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "ifs_user_loan", autoResultMap = true) +@ApiModel("用户借款金额实体类") +public class UserLoan extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "user_id") + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @TableField(exist = false) + @Property(value = "用户信息") + private Map userMation; + + @TableField(value = "price") + @ApiModelProperty(value = "借款总金额", required = "double") + private String price; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanBorrowService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanBorrowService.java new file mode 100644 index 0000000..cf5aba3 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanBorrowService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.loan.entity.LoanBorrow; + +/** + * @ClassName: LoanBorrowService + * @Description: 借款单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LoanBorrowService extends SkyeyeFlowableService { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanRepayService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanRepayService.java new file mode 100644 index 0000000..f537213 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/LoanRepayService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.loan.entity.LoanRepay; + +/** + * @ClassName: LoanRepayService + * @Description: 还款单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LoanRepayService extends SkyeyeFlowableService { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/UserLoanService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/UserLoanService.java new file mode 100644 index 0000000..86bbee5 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/UserLoanService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.loan.entity.UserLoan; + +/** + * @ClassName: UserLoanService + * @Description: 用户借款金额服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UserLoanService extends SkyeyeBusinessService { + + void calcUserLoanPrice(String userId, String price, boolean type); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanBorrowServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanBorrowServiceImpl.java new file mode 100644 index 0000000..acec506 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanBorrowServiceImpl.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.loan.dao.LoanBorrowDao; +import com.skyeye.loan.entity.LoanBorrow; +import com.skyeye.loan.service.LoanBorrowService; +import com.skyeye.loan.service.UserLoanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: LoanBorrowServiceImpl + * @Description: 借款单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "借款单", groupName = "借款单", flowable = true) +public class LoanBorrowServiceImpl extends SkyeyeFlowableServiceImpl implements LoanBorrowService { + + @Autowired + private UserLoanService userLoanService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(LoanBorrow::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + return queryWrapper; + } + + @Override + public LoanBorrow selectById(String id) { + LoanBorrow loanBorrow = super.selectById(id); + iSysDictDataService.setDataMation(loanBorrow, LoanBorrow::getPayTypeId); + return loanBorrow; + } + + @Override + public void approvalEndIsSuccess(LoanBorrow entity) { + userLoanService.calcUserLoanPrice(entity.getCreateId(), entity.getPrice(), true); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanRepayServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanRepayServiceImpl.java new file mode 100644 index 0000000..f7ccb2a --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/LoanRepayServiceImpl.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.loan.dao.LoanRepayDao; +import com.skyeye.loan.entity.LoanRepay; +import com.skyeye.loan.service.LoanRepayService; +import com.skyeye.loan.service.UserLoanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: LoanRepayServiceImpl + * @Description: 还款单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 14:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "还款单", groupName = "还款单", flowable = true) +public class LoanRepayServiceImpl extends SkyeyeFlowableServiceImpl implements LoanRepayService { + + @Autowired + private UserLoanService userLoanService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(LoanRepay::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + return queryWrapper; + } + + @Override + public LoanRepay selectById(String id) { + LoanRepay loanRepay = super.selectById(id); + iSysDictDataService.setDataMation(loanRepay, LoanRepay::getPayTypeId); + return loanRepay; + } + + @Override + public void approvalEndIsSuccess(LoanRepay entity) { + userLoanService.calcUserLoanPrice(entity.getCreateId(), entity.getPrice(), false); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/UserLoanServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/UserLoanServiceImpl.java new file mode 100644 index 0000000..4064573 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/loan/service/impl/UserLoanServiceImpl.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.loan.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.loan.dao.UserLoanDao; +import com.skyeye.loan.entity.UserLoan; +import com.skyeye.loan.service.UserLoanService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: UserLoanServiceImpl + * @Description: 用户借款金额服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/5 13:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户借款金额", groupName = "用户借款金额", manageShow = false) +public class UserLoanServiceImpl extends SkyeyeBusinessServiceImpl implements UserLoanService { + + @Override + public void calcUserLoanPrice(String userId, String price, boolean type) { + UserLoan userLoan = selectById(userId); + String allPrice = "0"; + if (ObjectUtil.isNotEmpty(userLoan) && StrUtil.isNotEmpty(userLoan.getId())) { + allPrice = userLoan.getPrice(); + } + if (type) { + // 增加 + allPrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, allPrice, price); + } else { + // 减少 + allPrice = CalculationUtil.subtract(allPrice, price, CommonNumConstants.NUM_TWO); + } + if (ObjectUtil.isNotEmpty(userLoan) && StrUtil.isNotEmpty(userLoan.getId())) { + // 编辑 + userLoan.setPrice(allPrice); + updateEntity(userLoan, StrUtil.EMPTY); + } else { + // 新增 + userLoan.setPrice(allPrice); + userLoan.setUserId(userId); + createEntity(userLoan, StrUtil.EMPTY); + } + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/controller/IncomeOrderController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/controller/IncomeOrderController.java new file mode 100644 index 0000000..d1ecaa8 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/controller/IncomeOrderController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.order.entity.IncomeOrder; +import com.skyeye.order.service.IncomeOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IncomeOrderController + * @Description: 明细账管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 11:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "明细账管理", tags = "明细账管理", modelName = "明细账管理") +public class IncomeOrderController { + + @Autowired + private IncomeOrderService incomeService; + + /** + * 查询明细账列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "income001", value = "查询明细账列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/IncomeController/queryIncomeByList") + public void queryIncomeByList(InputObject inputObject, OutputObject outputObject) { + incomeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑明细账 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeIncomeOrder", value = "新增/编辑明细账", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = IncomeOrder.class) + @RequestMapping("/post/IncomeController/writeIncomeOrder") + public void writeIncomeOrder(InputObject inputObject, OutputObject outputObject) { + incomeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除明细账信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "income005", value = "删除明细账信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/IncomeController/deleteIncomeOrderById") + public void deleteIncomeOrderById(InputObject inputObject, OutputObject outputObject) { + incomeService.deleteById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "income008", value = "明细账申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/IncomeController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + incomeService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "income009", value = "撤销明细账申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/IncomeController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + incomeService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderDao.java new file mode 100644 index 0000000..c79f189 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.order.entity.IncomeOrder; + +/** + * @ClassName: IncomeOrderDao + * @Description: 明细账管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 22:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderItemDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderItemDao.java new file mode 100644 index 0000000..2b85a29 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/dao/IncomeOrderItemDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.order.entity.IncomeOrderItem; + +/** + * @ClassName: IncomeOrderItemDao + * @Description: 明细账子单据管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 10:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeOrderItemDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IfsOrderQueryDo.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IfsOrderQueryDo.java new file mode 100644 index 0000000..3077095 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IfsOrderQueryDo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: IfsOrderQueryDo + * @Description: 财务单据查询实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 11:13 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("财务单据查询实体类") +public class IfsOrderQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "单据类型") + private String orderType; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrder.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrder.java new file mode 100644 index 0000000..408bd60 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrder.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IncomeOrder + * @Description: 明细账订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/23 12:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ifs:order", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "ifs_order_head", autoResultMap = true) +@ApiModel("明细账订单实体类") +public class IncomeOrder extends SkyeyeFlowable { + + @TableField(value = "holder_id", fill = FieldFill.INSERT) + @ApiModelProperty(value = "往来单位Id", required = "required") + private String holderId; + + @TableField(value = "holder_key", fill = FieldFill.INSERT) + @ApiModelProperty(value = "往来单位Key", required = "required") + private String holderKey; + + @TableField(exist = false) + @Property(value = "往来单位信息") + private Map holderMation; + + @TableField(value = "type") + @ApiModelProperty(value = "单据类型", required = "required") + private String type; + + @TableField(value = "hands_person_id") + @ApiModelProperty(value = "经手人Id", required = "required") + private String handsPersonId; + + @TableField(exist = false) + @Property(value = "经手人信息") + private Map handsPersonMation; + + @TableField("bill_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField("account_id") + @ApiModelProperty(value = "账户Id", required = "required") + private String accountId; + + @TableField(exist = false) + @Property(value = "账户信息") + private Map accountMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("set_of_books_id") + @ApiModelProperty(value = "账套id", required = "required") + private String setOfBooksId; + + @TableField(exist = false) + @Property(value = "账套信息") + private Map setOfBooksMation; + + @TableField(exist = false) + @ApiModelProperty(value = "收入项目列表", required = "required,json") + private List initem; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrderItem.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrderItem.java new file mode 100644 index 0000000..8049e79 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/entity/IncomeOrderItem.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: IncomeOrderItem + * @Description: 明细账订单子内容实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/23 12:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "ifs_order_item") +@ApiModel("明细账订单子内容实体类") +public class IncomeOrderItem extends SkyeyeLinkData { + + @TableField("voucher_id") + @ApiModelProperty(value = "凭证ID", required = "required") + private String voucherId; + + @TableField(exist = false) + @Property(value = "凭证信息") + private Map voucherMation; + + @TableField("subject_id") + @ApiModelProperty(value = "会计科目ID", required = "required") + private String subjectId; + + @TableField(exist = false) + @Property(value = "会计科目信息") + private Map subjectMation; + + @TableField("each_amount") + @ApiModelProperty(value = "金额", required = "required") + private String eachAmount; + + @TableField("direction_type") + @ApiModelProperty(value = "金额类型,参考#AmountDirection", required = "required,num") + private Integer directionType; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderItemService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderItemService.java new file mode 100644 index 0000000..e9baadc --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderItemService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.order.entity.IncomeOrderItem; + +import java.util.List; + +/** + * @ClassName: IncomeOrderItemService + * @Description: 明细账子单据服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 10:15 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeOrderItemService extends SkyeyeLinkDataService { + + /** + * 计算单据信息的总价 + * + * @param orderItemList + * @return + */ + String calcOrderAllTotalPrice(List orderItemList); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderService.java new file mode 100644 index 0000000..024ebba --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/IncomeOrderService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.order.entity.IncomeOrder; + +/** + * @ClassName: IncomeOrderService + * @Description: 明细账管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/16 16:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IncomeOrderService extends SkyeyeFlowableService { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderItemServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderItemServiceImpl.java new file mode 100644 index 0000000..ab682a5 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderItemServiceImpl.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service.impl; + +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.order.dao.IncomeOrderItemDao; +import com.skyeye.order.entity.IncomeOrderItem; +import com.skyeye.order.service.IncomeOrderItemService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: IncomeOrderItemServiceImpl + * @Description: 明细账子单据服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 10:15 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class IncomeOrderItemServiceImpl extends SkyeyeLinkDataServiceImpl implements IncomeOrderItemService { + + /** + * 计算单据信息的总价 + * + * @param orderItemList + * @return + */ + @Override + public String calcOrderAllTotalPrice(List orderItemList) { + String totalPrice = "0"; + for (IncomeOrderItem orderItem : orderItemList) { + // 计算子单据总价:单价相加 + totalPrice = CalculationUtil.add(totalPrice, orderItem.getEachAmount()); + } + return totalPrice; + } +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderServiceImpl.java new file mode 100644 index 0000000..80e8ec5 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/order/service/impl/IncomeOrderServiceImpl.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.account.service.AccountService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.books.service.IfsSetOfBooksService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CorrespondentEnterEnum; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.crm.service.ICustomerService; +import com.skyeye.erp.service.ISupplierService; +import com.skyeye.order.dao.IncomeOrderDao; +import com.skyeye.order.entity.IncomeOrder; +import com.skyeye.order.entity.IncomeOrderItem; +import com.skyeye.order.service.IncomeOrderItemService; +import com.skyeye.order.service.IncomeOrderService; +import com.skyeye.subject.service.IfsAccountSubjectService; +import com.skyeye.voucher.classenum.VoucherState; +import com.skyeye.voucher.service.IfsVoucherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: IncomeOrderServiceImpl + * @Description: 明细账管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "明细账管理", groupName = "明细账管理", flowable = true) +public class IncomeOrderServiceImpl extends SkyeyeFlowableServiceImpl implements IncomeOrderService { + + @Autowired + private IncomeOrderItemService incomeOrderItemService; + + @Autowired + private IfsVoucherService ifsVoucherService; + + @Autowired + private ICustomerService iCustomerService; + + @Autowired + private ISupplierService iSupplierService; + + @Autowired + private AccountService accountService; + + @Autowired + private IfsSetOfBooksService ifsSetOfBooksService; + + @Autowired + private IfsAccountSubjectService ifsAccountSubjectService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "myCreate")) { + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(IncomeOrder::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setNameForMap(beans, "handsPersonId", "handsPersonName"); + setHolderMation(beans); + return beans; + } + + /** + * 设置往来单位信息 + * + * @param beans + */ + private void setHolderMation(List> beans) { + // 客户 + List customIds = beans.stream().filter(bean -> StrUtil.equals(bean.get("holderKey").toString(), CorrespondentEnterEnum.CUSTOM.getKey())) + .map(bean -> bean.get("holderId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(customIds)) { + Map> customMap = iCustomerService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(customIds)); + beans.forEach(bean -> { + if (StrUtil.equals(bean.get("holderKey").toString(), CorrespondentEnterEnum.CUSTOM.getKey())) { + String holderId = bean.get("holderId").toString(); + bean.put("holderMation", customMap.get(holderId)); + } + }); + } + // 供应商 + List supplierIds = beans.stream().filter(bean -> StrUtil.equals(bean.get("holderKey").toString(), CorrespondentEnterEnum.SUPPLIER.getKey())) + .map(bean -> bean.get("holderId").toString()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(supplierIds)) { + Map> supplierMap = iSupplierService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(supplierIds)); + beans.forEach(bean -> { + if (StrUtil.equals(bean.get("holderKey").toString(), CorrespondentEnterEnum.SUPPLIER.getKey())) { + String holderId = bean.get("holderId").toString(); + bean.put("holderMation", supplierMap.get(holderId)); + } + }); + } + } + + @Override + public void writeChild(IncomeOrder entity, String userId) { + incomeOrderItemService.saveLinkList(entity.getId(), entity.getInitem()); + super.writeChild(entity, userId); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + incomeOrderItemService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public IncomeOrder selectById(String id) { + IncomeOrder incomeOrder = super.selectById(id); + // 往来单位 + if (StrUtil.equals(incomeOrder.getHolderKey(), CorrespondentEnterEnum.CUSTOM.getKey())) { + incomeOrder.setHolderMation(iCustomerService.queryDataMationById(incomeOrder.getHolderId())); + } else if (StrUtil.equals(incomeOrder.getHolderKey(), CorrespondentEnterEnum.SUPPLIER.getKey())) { + incomeOrder.setHolderMation(iSupplierService.queryDataMationById(incomeOrder.getHolderId())); + } + // 经手人 + incomeOrder.setHandsPersonMation(iAuthUserService.queryDataMationById(incomeOrder.getHandsPersonId())); + // 账户 + incomeOrder.setAccountMation(accountService.selectMapById(incomeOrder.getAccountId())); + // 账套 + incomeOrder.setSetOfBooksMation(ifsSetOfBooksService.selectMapById(incomeOrder.getSetOfBooksId())); + // 凭证信息/会计科目信息 + List voucherIds = incomeOrder.getInitem().stream().map(IncomeOrderItem::getVoucherId).collect(Collectors.toList()); + Map> voucherMap = ifsVoucherService.selectValIsMapByIds(voucherIds); + List subjectIds = incomeOrder.getInitem().stream().map(IncomeOrderItem::getSubjectId).collect(Collectors.toList()); + Map> subjectMap = ifsAccountSubjectService.selectValIsMapByIds(subjectIds); + incomeOrder.getInitem().forEach(incomeOrderItem -> { + incomeOrderItem.setVoucherMation(voucherMap.get(incomeOrderItem.getVoucherId())); + incomeOrderItem.setSubjectMation(subjectMap.get(incomeOrderItem.getSubjectId())); + }); + + return incomeOrder; + } + + @Override + public IncomeOrder getDataFromDb(String id) { + IncomeOrder incomeOrder = super.getDataFromDb(id); + List incomeOrderItemList = incomeOrderItemService.selectByPId(incomeOrder.getId()); + incomeOrderItemList.forEach(incomeOrderItem -> { + incomeOrderItem.setEachAmount(CalculationUtil.formatNoScale(incomeOrderItem.getEachAmount())); + }); + incomeOrder.setInitem(incomeOrderItemList); + return incomeOrder; + } + + /** + * 撤销完成的后置执行 + * + * @param entity + */ + @Override + public void revokePostpose(IncomeOrder entity) { + super.revokePostpose(entity); + incomeOrderItemService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + /** + * 审批成功的回调函数 + * + * @param entity + */ + @Override + protected void approvalEndIsSuccess(IncomeOrder entity) { + incomeOrderItemService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + List incomeOrderItemList = incomeOrderItemService.selectByPId(entity.getId()); + // 修改凭证状态为已整理 + incomeOrderItemList.forEach(incomeOrderItem -> { + ifsVoucherService.editIfsVoucherState(incomeOrderItem.getVoucherId(), VoucherState.CLUTTERED.getKey()); + }); + } + + /** + * 审批失败的回调函数 + * + * @param entity + */ + @Override + protected void approvalEndIsFailed(IncomeOrder entity) { + incomeOrderItemService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/controller/ReimbursementController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/controller/ReimbursementController.java new file mode 100644 index 0000000..c405c73 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/controller/ReimbursementController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.reimbursement.entity.Reimbursement; +import com.skyeye.reimbursement.service.ReimbursementService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReimbursementController + * @Description: 报销订单控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "报销订单", tags = "报销订单", modelName = "报销订单") +public class ReimbursementController { + + @Autowired + private ReimbursementService reimbursementService; + + /** + * 查询报销订单列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReimbursementList", value = "查询报销订单列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReimbursementController/queryReimbursementList") + public void queryReimbursementList(InputObject inputObject, OutputObject outputObject) { + reimbursementService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑报销订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeReimbursement", value = "新增/编辑报销订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Reimbursement.class) + @RequestMapping("/post/ReimbursementController/writeReimbursement") + public void writeReimbursement(InputObject inputObject, OutputObject outputObject) { + reimbursementService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除报销订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteReimbursementById", value = "删除报销订单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReimbursementController/deleteReimbursementById") + public void deleteReimbursementById(InputObject inputObject, OutputObject outputObject) { + reimbursementService.deleteById(inputObject, outputObject); + } + + /** + * 提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitReimbursementToApproval", value = "报销订单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ReimbursementController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + reimbursementService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeReimbursement", value = "撤销报销订单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ReimbursementController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + reimbursementService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementChildDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementChildDao.java new file mode 100644 index 0000000..286a485 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.reimbursement.entity.ReimbursementChild; + +/** + * @ClassName: ReimbursementChildDao + * @Description: 报销订单子内容数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReimbursementChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementDao.java new file mode 100644 index 0000000..498aaa3 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/dao/ReimbursementDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.reimbursement.entity.Reimbursement; + +/** + * @ClassName: ReimbursementDao + * @Description: 报销订单数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReimbursementDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/Reimbursement.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/Reimbursement.java new file mode 100644 index 0000000..6389b0c --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/Reimbursement.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Reimbursement + * @Description: 报销订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "ifs:reimbursement", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "ifs_reimbursement", autoResultMap = true) +@ApiModel("报销订单实体类") +public class Reimbursement extends SkyeyeFlowable { + + @TableField(value = "collection_name") + @ApiModelProperty(value = "收款人全称", required = "required") + private String collectionName; + + @TableField(value = "collection_code") + @ApiModelProperty(value = "收款账号") + private String collectionCode; + + @TableField(value = "pay_type_id") + @ApiModelProperty(value = "付款方式id,参考数据字典", required = "required") + private String payTypeId; + + @TableField(exist = false) + @Property(value = "付款方式信息") + private Map payTypeMation; + + @TableField(value = "opening_bank") + @ApiModelProperty(value = "开户行") + private String openingBank; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "price") + @ApiModelProperty(value = "报销金额") + private String price; + + @TableField(exist = false) + @ApiModelProperty(value = "报销明细", required = "required,json") + private List reimbursementChildList; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/ReimbursementChild.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/ReimbursementChild.java new file mode 100644 index 0000000..0591fce --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/entity/ReimbursementChild.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ReimbursementChild + * @Description: 报销订单子内容实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "ifs_reimbursement_child") +@ApiModel("报销订单子内容实体类") +public class ReimbursementChild extends SkyeyeLinkData { + + @TableField("occur_time") + @ApiModelProperty(value = "发生日期", required = "required") + private String occurTime; + + @TableField("reimburse_pro_id") + @ApiModelProperty(value = "报销项目id,参考数据字典", required = "required") + private String reimburseProId; + + @TableField(exist = false) + @Property(value = "报销项目信息") + private Map reimburseProMation; + + @TableField(value = "price") + @ApiModelProperty(value = "报销金额", required = "required,double") + private String price; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementChildService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementChildService.java new file mode 100644 index 0000000..2a859b4 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementChildService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.service; + +import com.skyeye.base.business.service.SkyeyeLinkDataService; +import com.skyeye.reimbursement.entity.ReimbursementChild; + +import java.util.List; + +/** + * @ClassName: ReimbursementChildService + * @Description: 报销订单子内容服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReimbursementChildService extends SkyeyeLinkDataService { + + /** + * 计算单据信息的总价 + * + * @param orderItemList + * @return + */ + String calcOrderAllTotalPrice(List orderItemList); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementService.java new file mode 100644 index 0000000..f969f29 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/ReimbursementService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.reimbursement.entity.Reimbursement; + +/** + * @ClassName: ReimbursementService + * @Description: 报销订单服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReimbursementService extends SkyeyeFlowableService { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementChildServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementChildServiceImpl.java new file mode 100644 index 0000000..3116c61 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementChildServiceImpl.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.service.impl; + +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.reimbursement.dao.ReimbursementChildDao; +import com.skyeye.reimbursement.entity.ReimbursementChild; +import com.skyeye.reimbursement.service.ReimbursementChildService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReimbursementChildServiceImpl + * @Description: 报销订单子内容服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ReimbursementChildServiceImpl extends SkyeyeLinkDataServiceImpl implements ReimbursementChildService { + + @Override + public String calcOrderAllTotalPrice(List orderItemList) { + String totalPrice = "0"; + for (ReimbursementChild orderItem : orderItemList) { + // 计算子单据总价:单价相加 + totalPrice = CalculationUtil.add(totalPrice, orderItem.getPrice()); + } + return totalPrice; + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementServiceImpl.java new file mode 100644 index 0000000..5392780 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/reimbursement/service/impl/ReimbursementServiceImpl.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.reimbursement.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.reimbursement.dao.ReimbursementDao; +import com.skyeye.reimbursement.entity.Reimbursement; +import com.skyeye.reimbursement.entity.ReimbursementChild; +import com.skyeye.reimbursement.service.ReimbursementChildService; +import com.skyeye.reimbursement.service.ReimbursementService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReimbursementServiceImpl + * @Description: 报销订单服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/4 16:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "报销订单", groupName = "报销订单", flowable = true) +public class ReimbursementServiceImpl extends SkyeyeFlowableServiceImpl implements ReimbursementService { + + @Autowired + private ReimbursementChildService reimbursementChildService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "myCreate")) { + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(Reimbursement::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + } + return queryWrapper; + } + + @Override + public void validatorEntity(Reimbursement entity) { + super.validatorEntity(entity); + entity.setPrice(reimbursementChildService.calcOrderAllTotalPrice(entity.getReimbursementChildList())); + } + + @Override + public void writeChild(Reimbursement entity, String userId) { + reimbursementChildService.saveLinkList(entity.getId(), entity.getReimbursementChildList()); + super.writeChild(entity, userId); + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + reimbursementChildService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public Reimbursement getDataFromDb(String id) { + Reimbursement reimbursement = super.getDataFromDb(id); + List reimbursementChildList = reimbursementChildService.selectByPId(reimbursement.getId()); + reimbursement.setReimbursementChildList(reimbursementChildList); + return reimbursement; + } + + @Override + public Reimbursement selectById(String id) { + Reimbursement reimbursement = super.selectById(id); + iSysDictDataService.setDataMation(reimbursement, Reimbursement::getPayTypeId); + iSysDictDataService.setDataMation(reimbursement.getReimbursementChildList(), ReimbursementChild::getReimburseProId); + return reimbursement; + } + + @Override + public void deletePostpose(String id) { + reimbursementChildService.deleteByPId(id); + } + + @Override + public void revokePostpose(Reimbursement entity) { + super.revokePostpose(entity); + reimbursementChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + protected void approvalEndIsSuccess(Reimbursement entity) { + reimbursementChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + } + + @Override + protected void approvalEndIsFailed(Reimbursement entity) { + reimbursementChildService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AccountSubjectType.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AccountSubjectType.java new file mode 100644 index 0000000..19052e7 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AccountSubjectType.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AccountSubjectType + * @Description: 会计科目类型的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 22:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AccountSubjectType implements SkyeyeEnumClass { + + PROPERTY(1, "资产", true, true), + IN_DEBT(2, "负债", true, false), + RIGHTS_AND_INTERESTS(3, "权益", true, false), + PRIME_COST(4, "成本", true, false), + INCREASE_AND_DECREASE(5, "损益", true, false), + COMMON(6, "共同", true, false), + OTHER(7, "其他", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AmountDirection.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AmountDirection.java new file mode 100644 index 0000000..4de1485 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/classenum/AmountDirection.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AmountDirection + * @Description: 余额方向的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 22:17 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AmountDirection implements SkyeyeEnumClass { + + BORROW(1, "借", true, true), + LOAN(2, "贷", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/controller/IfsAccountSubjectController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/controller/IfsAccountSubjectController.java new file mode 100644 index 0000000..c842c9a --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/controller/IfsAccountSubjectController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.subject.entity.AccountSubject; +import com.skyeye.subject.service.IfsAccountSubjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IfsAccountSubjectController + * @Description: 会计科目管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 21:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "会计科目管理", tags = "会计科目管理", modelName = "会计科目管理") +public class IfsAccountSubjectController { + + @Autowired + private IfsAccountSubjectService ifsAccountSubjectService; + + /** + * 获取会计科目列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifsaccountsubject001", value = "获取会计科目列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/IfsAccountSubjectController/queryIfsAccountSubjectList") + public void queryIfsAccountSubjectList(InputObject inputObject, OutputObject outputObject) { + ifsAccountSubjectService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑会计科目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeIfsAccountSubject", value = "新增/编辑会计科目", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AccountSubject.class) + @RequestMapping("/post/IfsAccountSubjectController/writeIfsAccountSubject") + public void writeIfsAccountSubject(InputObject inputObject, OutputObject outputObject) { + ifsAccountSubjectService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除会计科目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifsaccountsubject005", value = "删除会计科目信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/IfsAccountSubjectController/deleteIfsAccountSubjectById") + public void deleteIfsAccountSubjectById(InputObject inputObject, OutputObject outputObject) { + ifsAccountSubjectService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的会计科目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledSubjectList", value = "获取已启用的会计科目", method = "GET", allUse = "2") + @RequestMapping("/post/IfsAccountSubjectController/queryEnabledSubjectList") + public void queryEnabledSubjectList(InputObject inputObject, OutputObject outputObject) { + ifsAccountSubjectService.queryEnabledSubjectList(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/dao/IfsAccountSubjectDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/dao/IfsAccountSubjectDao.java new file mode 100644 index 0000000..2becea7 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/dao/IfsAccountSubjectDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.subject.entity.AccountSubject; + +/** + * @ClassName: IfsAccountSubjectDao + * @Description: 会计科目管理数据层 + * @author: skyeye云系列 + * @date: 2021/11/27 12:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsAccountSubjectDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/entity/AccountSubject.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/entity/AccountSubject.java new file mode 100644 index 0000000..8d7a408 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/entity/AccountSubject.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: AccountSubject + * @Description: 会计科目实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "ifs:accountSubject") +@TableName(value = "ifs_account_subject", autoResultMap = true) +@ApiModel("会计科目实体类") +public class AccountSubject extends BaseGeneralInfo { + + @TableField(value = "num") + @ApiModelProperty(value = "编号", required = "required") + private String num; + + @TableField(value = "type") + @ApiModelProperty(value = "类型,参考#AccountSubjectType", required = "required,num") + private Integer type; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("amount_direction") + @ApiModelProperty(value = "余额方向,参考#AmountDirection", required = "required,num") + private Integer amountDirection; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/IfsAccountSubjectService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/IfsAccountSubjectService.java new file mode 100644 index 0000000..338de5b --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/IfsAccountSubjectService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.subject.entity.AccountSubject; + +/** + * @ClassName: IfsAccountSubjectService + * @Description: 会计科目管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 21:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsAccountSubjectService extends SkyeyeBusinessService { + + void queryEnabledSubjectList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/impl/IfsAccountSubjectServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/impl/IfsAccountSubjectServiceImpl.java new file mode 100644 index 0000000..93016d1 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/subject/service/impl/IfsAccountSubjectServiceImpl.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.subject.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.subject.dao.IfsAccountSubjectDao; +import com.skyeye.subject.entity.AccountSubject; +import com.skyeye.subject.service.IfsAccountSubjectService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; + +/** + * @ClassName: IfsAccountSubjectServiceImpl + * @Description: 会计科目管理服务类 + * @author: skyeye云系列 + * @date: 2021/11/27 12:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "会计科目管理", groupName = "会计科目管理") +public class IfsAccountSubjectServiceImpl extends SkyeyeBusinessServiceImpl implements IfsAccountSubjectService { + + @Override + public void validatorEntity(AccountSubject entity) { + super.validatorEntity(entity); + // 校验基础信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AccountSubject::getNum), entity.getNum()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + AccountSubject checkMation = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkMation)) { + throw new CustomException("this 【num】 is exist."); + } + } + + @Override + public void queryEnabledSubjectList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AccountSubject::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List accountSubjectList = list(queryWrapper); + accountSubjectList.forEach(accountSubject -> { + accountSubject.setName(String.format(Locale.ROOT, "%s_%s", accountSubject.getNum(), accountSubject.getName())); + }); + outputObject.setBeans(accountSubjectList); + outputObject.settotal(accountSubjectList.size()); + } +} + diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherState.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherState.java new file mode 100644 index 0000000..6fcd058 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: VoucherState + * @Description: 凭证状态的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 22:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum VoucherState implements SkyeyeEnumClass { + + UN_CLUTTERED(1, "未整理", true, true), + CLUTTERED(2, "已整理", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherType.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherType.java new file mode 100644 index 0000000..b4a279e --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/classenum/VoucherType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: VoucherType + * @Description: 凭证类型的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 22:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum VoucherType implements SkyeyeEnumClass { + + ORIGINAL_VOUCHER(1, "原始凭证", true, true), + ENTER_VOUCHERS_MANUALLY(2, "手工录入凭证", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/controller/IfsVoucherController.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/controller/IfsVoucherController.java new file mode 100644 index 0000000..25a982b --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/controller/IfsVoucherController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.voucher.entity.Voucher; +import com.skyeye.voucher.service.IfsVoucherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: IfsVoucherController + * @Description: 凭证信息管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/3 18:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "凭证管理", tags = "凭证管理", modelName = "凭证管理") +public class IfsVoucherController { + + @Autowired + private IfsVoucherService ifsVoucherService; + + /** + * 查询我上传的凭证 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifsVoucher001", value = "查询我上传的凭证", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/IfsVoucherController/queryIfsVoucherList") + public void queryIfsVoucherList(InputObject inputObject, OutputObject outputObject) { + ifsVoucherService.queryPageList(inputObject, outputObject); + } + + /** + * 新增凭证 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifsVoucher002", value = "新增凭证", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Voucher.class) + @RequestMapping("/post/IfsVoucherController/insertIfsVoucher") + public void insertIfsVoucher(InputObject inputObject, OutputObject outputObject) { + ifsVoucherService.createEntity(inputObject, outputObject); + } + + /** + * 删除上传的凭证 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "ifsVoucher003", value = "删除上传的凭证", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/IfsVoucherController/deleteIfsVoucherById") + public void deleteIfsVoucherById(InputObject inputObject, OutputObject outputObject) { + ifsVoucherService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/dao/IfsVoucherDao.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/dao/IfsVoucherDao.java new file mode 100644 index 0000000..34088d9 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/dao/IfsVoucherDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.voucher.entity.Voucher; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IfsVoucherDao + * @Description: 凭证信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/3 18:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsVoucherDao extends SkyeyeBaseMapper { + + List> queryIfsVoucherList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/entity/Voucher.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/entity/Voucher.java new file mode 100644 index 0000000..2d4131f --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/entity/Voucher.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: Voucher + * @Description: 凭证实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/12 12:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "ifs:voucher") +@TableName(value = "ifs_voucher", autoResultMap = true) +@ApiModel("凭证实体类") +public class Voucher extends BaseGeneralInfo { + + @TableField(value = "path") + @ApiModelProperty(value = "凭证文件路径") + private String path; + + @TableField(value = "state") + @ApiModelProperty(value = "状态,参考#VoucherState") + private Integer state; + + @TableField(value = "type") + @ApiModelProperty(value = "类型,参考#VoucherType", required = "required,num") + private Integer type; + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/IfsVoucherService.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/IfsVoucherService.java new file mode 100644 index 0000000..2c9e818 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/IfsVoucherService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.voucher.entity.Voucher; + +/** + * @ClassName: IfsVoucherService + * @Description: 凭证信息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/3 18:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IfsVoucherService extends SkyeyeBusinessService { + + void editIfsVoucherState(String id, Integer state); + +} diff --git a/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/impl/IfsVoucherServiceImpl.java b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/impl/IfsVoucherServiceImpl.java new file mode 100644 index 0000000..c9e48f4 --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/java/com/skyeye/voucher/service/impl/IfsVoucherServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.voucher.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.voucher.classenum.VoucherState; +import com.skyeye.voucher.dao.IfsVoucherDao; +import com.skyeye.voucher.entity.Voucher; +import com.skyeye.voucher.service.IfsVoucherService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IfsVoucherServiceImpl + * @Description: 凭证信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/3 18:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "凭证管理", groupName = "凭证管理") +public class IfsVoucherServiceImpl extends SkyeyeBusinessServiceImpl implements IfsVoucherService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.queryIfsVoucherList(commonPageInfo); + return beans; + } + + @Override + protected void createPrepose(Voucher entity) { + super.createPrepose(entity); + entity.setState(VoucherState.UN_CLUTTERED.getKey()); + } + + @Override + public void deletePostpose(Voucher entity) { + if (VoucherState.UN_CLUTTERED.getKey() == entity.getState()) { + String basePath = tPath + entity.getPath().replace("/images/", ""); + FileUtil.deleteFile(basePath); + } + } + + @Override + public void editIfsVoucherState(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Voucher::getState), state); + update(updateWrapper); + refreshCache(id); + } +} diff --git a/skyeye-ifs/ifs-pro/src/main/resources/mapper/voucher/IfsVoucherMapper.xml b/skyeye-ifs/ifs-pro/src/main/resources/mapper/voucher/IfsVoucherMapper.xml new file mode 100644 index 0000000..86dc94e --- /dev/null +++ b/skyeye-ifs/ifs-pro/src/main/resources/mapper/voucher/IfsVoucherMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-ifs/ifs-web/.gitignore b/skyeye-ifs/ifs-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-ifs/ifs-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-ifs/ifs-web/pom.xml b/skyeye-ifs/ifs-web/pom.xml new file mode 100644 index 0000000..06e96df --- /dev/null +++ b/skyeye-ifs/ifs-web/pom.xml @@ -0,0 +1,88 @@ + + + + skyeye-ifs + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + ifs-web + + + + + com.skyeye + ifs-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-ifs/ifs-web/src/main/java/com/IfsApplication.java b/skyeye-ifs/ifs-web/src/main/java/com/IfsApplication.java new file mode 100644 index 0000000..7b92298 --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/java/com/IfsApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class IfsApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(IfsApplication.class, args); + } + +} diff --git a/skyeye-ifs/ifs-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-ifs/ifs-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..f8d5cdd --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-ifs/ifs-web/src/main/resources/banner.txt b/skyeye-ifs/ifs-web/src/main/resources/banner.txt new file mode 100644 index 0000000..b1cb7f9 --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev ifs-web.jar >> /opt/service/project/nohup-ifs.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-ifs/ifs-web/src/main/resources/bootstrap.yml b/skyeye-ifs/ifs-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..b1b9f8a --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +server: + port: 8107 + +spring: + application: + name: skyeye-ifs-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-ifs/ifs-web/src/main/resources/jvm调优参数配置 b/skyeye-ifs/ifs-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-ifs/ifs-web/src/main/resources/log4j.properties b/skyeye-ifs/ifs-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-ifs/ifs-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-ifs/pom.xml b/skyeye-ifs/pom.xml new file mode 100644 index 0000000..9181c4b --- /dev/null +++ b/skyeye-ifs/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + ifs-common + ifs-pro + ifs-web + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-ifs + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-monitor/.gitignore b/skyeye-monitor/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-monitor/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-monitor/.project b/skyeye-monitor/.project new file mode 100644 index 0000000..e42c99a --- /dev/null +++ b/skyeye-monitor/.project @@ -0,0 +1,23 @@ + + + skyeye-monitor + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-monitor/pom.xml b/skyeye-monitor/pom.xml new file mode 100644 index 0000000..3f67683 --- /dev/null +++ b/skyeye-monitor/pom.xml @@ -0,0 +1,173 @@ + + + 4.0.0 + com.monitor + skyeye-monitor + 0.0.1-SNAPSHOT + + + UTF-8 + UTF-8 + 1.8 + + 2.7.18 + 2021.0.9 + 2021.0.6.1 + + + 2.7.15 + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + de.codecentric + spring-boot-admin-starter-server + ${spring-boot-admin.version} + + + + de.codecentric + spring-boot-admin-server-ui + ${spring-boot-admin.version} + + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + org.jolokia + jolokia-core + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + ${project.artifactId} + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-monitor/src/main/java/com/SpringBootAdminApplication.java b/skyeye-monitor/src/main/java/com/SpringBootAdminApplication.java new file mode 100644 index 0000000..417001f --- /dev/null +++ b/skyeye-monitor/src/main/java/com/SpringBootAdminApplication.java @@ -0,0 +1,17 @@ +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Configuration; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; + + +@Configuration +@SpringBootApplication +@EnableAdminServer +public class SpringBootAdminApplication { + public static void main(String[] args) { + SpringApplication.run(SpringBootAdminApplication.class, args); + } +} diff --git a/skyeye-monitor/src/main/resources/application.properties b/skyeye-monitor/src/main/resources/application.properties new file mode 100644 index 0000000..34c2bcb --- /dev/null +++ b/skyeye-monitor/src/main/resources/application.properties @@ -0,0 +1,18 @@ +server.port=8000 + +# JavaMailSender 邮件发送的配置 +spring.mail.host=smtp.qq.com +spring.mail.username=598748873@qq.com +# 此处为qq邮箱授权码,如何设置授权码见:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256 +spring.mail.password=kgcfkcynnwqsbeja +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true +# 配置发送人 +spring.boot.admin.notify.mail.from=598748873@qq.com +# 配置接收人 +spring.boot.admin.notify.mail.to=3532684497@qq.com + +# 登录用户名密码 +#spring.security.user.name=admin +#spring.security.user.password=admin \ No newline at end of file diff --git a/skyeye-project/.gitignore b/skyeye-project/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-project/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-project/pom.xml b/skyeye-project/pom.xml new file mode 100644 index 0000000..69b22f8 --- /dev/null +++ b/skyeye-project/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + project-common + project-web + project-pro + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-project + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-project/project-common/.gitignore b/skyeye-project/project-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-project/project-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-project/project-common/pom.xml b/skyeye-project/project-common/pom.xml new file mode 100644 index 0000000..2936d4f --- /dev/null +++ b/skyeye-project/project-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-project + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + project-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-project/project-pro/.gitignore b/skyeye-project/project-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-project/project-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-project/project-pro/pom.xml b/skyeye-project/project-pro/pom.xml new file mode 100644 index 0000000..fd4d6c2 --- /dev/null +++ b/skyeye-project/project-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-project + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + project-pro + + + + + com.skyeye + project-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneAuthEnum.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneAuthEnum.java new file mode 100644 index 0000000..8045098 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneAuthEnum.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MilestoneAuthEnum + * @Description: 里程碑权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MilestoneAuthEnum implements SkyeyeEnumClass { + + + LIST("list", "所有里程碑列表", true, false), + MY_CREATE("myCreate", "我创建的里程碑列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false), + + EXECUTING("executing", "执行中", true, false), + COMPLETED("completed", "执行完成", true, false), + CLOSE("close", "已关闭", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneImported.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneImported.java new file mode 100644 index 0000000..af8a0bd --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneImported.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MilestoneImported + * @Description: 里程碑重要性 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MilestoneImported implements SkyeyeEnumClass { + + ORDINARY("ordinary", "普通", true, false), + COMMONLY("commonly", "一般", true, false), + IMPORTANT("important", "重要", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneStateEnum.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneStateEnum.java new file mode 100644 index 0000000..d773998 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/classenum/MilestoneStateEnum.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: MilestoneStateEnum + * @Description: 里程碑状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MilestoneStateEnum implements SkyeyeEnumClass { + + TO_BE_EXECUTED("toBeExecuted", "待执行", true, false), + EXECUTING("executing", "执行中", true, false), + COMPLETED("completed", "执行完成", true, false), + CLOSE("close", "已关闭", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/controller/MilestoneController.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/controller/MilestoneController.java new file mode 100644 index 0000000..16b0063 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/controller/MilestoneController.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.milestone.entity.Milestone; +import com.skyeye.milestone.service.MilestoneService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MilestoneController + * @Description: 里程碑管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "里程碑管理", tags = "里程碑管理", modelName = "里程碑管理") +public class MilestoneController { + + @Autowired + private MilestoneService milestoneService; + + /** + * 获取里程碑列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMilestoneList", value = "获取里程碑列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MilestoneController/queryMilestoneList") + public void queryMilestoneList(InputObject inputObject, OutputObject outputObject) { + milestoneService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑里程碑管理 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMilestone", value = "新增/编辑里程碑管理", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Milestone.class) + @RequestMapping("/post/MilestoneController/writeMilestone") + public void writeMilestone(InputObject inputObject, OutputObject outputObject) { + milestoneService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除里程碑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMilestoneById", value = "删除里程碑信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MilestoneController/deleteMilestoneById") + public void deleteMilestoneById(InputObject inputObject, OutputObject outputObject) { + milestoneService.deleteById(inputObject, outputObject); + } + + /** + * 撤销里程碑审批申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeMilestone", value = "撤销里程碑审批申请", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/MilestoneController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + milestoneService.revoke(inputObject, outputObject); + } + + /** + * 里程碑提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitToApprovalMilestone", value = "里程碑提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/MilestoneController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + milestoneService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废里程碑 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidMilestone", value = "作废里程碑", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MilestoneController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + milestoneService.invalid(inputObject, outputObject); + } + + /** + * 里程碑开始执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "executionMilestone", value = "里程碑开始执行", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MilestoneController/executionMilestone") + public void executionMilestone(InputObject inputObject, OutputObject outputObject) { + milestoneService.executionMilestone(inputObject, outputObject); + } + + /** + * 里程碑执行完成 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "complateMilestone", value = "里程碑执行完成", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MilestoneController/complateMilestone") + public void complateMilestone(InputObject inputObject, OutputObject outputObject) { + milestoneService.complateMilestone(inputObject, outputObject); + } + + /** + * 里程碑关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "closeMilestone", value = "里程碑关闭", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MilestoneController/closeMilestone") + public void closeMilestone(InputObject inputObject, OutputObject outputObject) { + milestoneService.closeMilestone(inputObject, outputObject); + } + + /** + * 根据供应商id获取执行中的里程碑列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllExecutingMilestoneList", value = "根据供应商id获取执行中的里程碑列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id")}) + @RequestMapping("/post/MilestoneController/queryAllExecutingMilestoneList") + public void queryAllExecutingMilestoneList(InputObject inputObject, OutputObject outputObject) { + milestoneService.queryAllExecutingMilestoneList(inputObject, outputObject); + } + + /** + * 根据供应商id获取所有审批通过之后的里程碑列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllApprovalMilestoneList", value = "根据供应商id获取所有审批通过之后的里程碑列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required")}) + @RequestMapping("/post/MilestoneController/queryAllApprovalMilestoneList") + public void queryAllApprovalMilestoneList(InputObject inputObject, OutputObject outputObject) { + milestoneService.queryAllApprovalMilestoneList(inputObject, outputObject); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/dao/MilestoneDao.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/dao/MilestoneDao.java new file mode 100644 index 0000000..232db85 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/dao/MilestoneDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.milestone.entity.Milestone; + +/** + * @ClassName: MilestoneDao + * @Description: 里程碑管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MilestoneDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/entity/Milestone.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/entity/Milestone.java new file mode 100644 index 0000000..9639fa5 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/entity/Milestone.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Milestone + * @Description: 里程碑管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "name"}) +@RedisCacheField(name = "pm:milestone", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "pro_milestone", autoResultMap = true) +@ApiModel("里程碑管理实体类") +public class Milestone extends SkyeyeFlowable { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField("start_time") + @ApiModelProperty(value = "开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间", required = "required") + private String endTime; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(value = "responsible_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "负责人ID") + private List responsibleId; + + @TableField(exist = false) + @Property(value = "负责人") + private List> responsibleMation; + + @TableField(value = "total_workload") + @Property(value = "总工作量(小时)") + private String totalWorkload; + + @TableField(value = "completed_workload") + @Property(value = "已完成工作量(小时)") + private String completedWorkload; + + @TableField("imported") + @ApiModelProperty(value = "重要性,参考#MilestoneImported", required = "required") + private String imported; + + @TableField(exist = false) + private String pId; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/MilestoneService.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/MilestoneService.java new file mode 100644 index 0000000..1a82a91 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/MilestoneService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.milestone.entity.Milestone; + +/** + * @ClassName: MilestoneService + * @Description: 里程碑管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MilestoneService extends SkyeyeFlowableService { + + void executionMilestone(InputObject inputObject, OutputObject outputObject); + + void complateMilestone(InputObject inputObject, OutputObject outputObject); + + void closeMilestone(InputObject inputObject, OutputObject outputObject); + + void queryAllExecutingMilestoneList(InputObject inputObject, OutputObject outputObject); + + void queryAllApprovalMilestoneList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/impl/MilestoneServiceImpl.java b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/impl/MilestoneServiceImpl.java new file mode 100644 index 0000000..de48f16 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/milestone/service/impl/MilestoneServiceImpl.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.milestone.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.milestone.classenum.MilestoneAuthEnum; +import com.skyeye.milestone.classenum.MilestoneStateEnum; +import com.skyeye.milestone.dao.MilestoneDao; +import com.skyeye.milestone.entity.Milestone; +import com.skyeye.milestone.service.MilestoneService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MilestoneServiceImpl + * @Description: 里程碑管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "里程碑管理", groupName = "里程碑管理", flowable = true, teamAuth = true) +public class MilestoneServiceImpl extends SkyeyeFlowableServiceImpl implements MilestoneService { + + @Override + public Class getAuthEnumClass() { + return MilestoneAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(MilestoneAuthEnum.ADD.getKey(), MilestoneAuthEnum.EDIT.getKey(), MilestoneAuthEnum.DELETE.getKey(), + MilestoneAuthEnum.REVOKE.getKey(), MilestoneAuthEnum.INVALID.getKey(), MilestoneAuthEnum.SUBMIT_TO_APPROVAL.getKey(), MilestoneAuthEnum.LIST.getKey(), + MilestoneAuthEnum.EXECUTING.getKey(), MilestoneAuthEnum.COMPLETED.getKey(), MilestoneAuthEnum.CLOSE.getKey(), MilestoneAuthEnum.MY_CREATE.getKey()); + } + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getObjectId), commonPageInfo.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getObjectKey), commonPageInfo.getObjectKey()); + if (StrUtil.equals("myCreate", commonPageInfo.getType())) { + Milestone milestone = ReflectUtil.newInstance(clazz); + milestone.setObjectId(commonPageInfo.getObjectId()); + milestone.setObjectKey(commonPageInfo.getObjectKey()); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + checkAuthPermission(milestone, userId, CommonNumConstants.NUM_TEN); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getCreateId), userId); + } + return queryWrapper; + } + + @Override + public Milestone selectById(String id) { + Milestone milestone = super.selectById(id); + // 负责人 + if (CollectionUtil.isNotEmpty(milestone.getResponsibleId())) { + milestone.setResponsibleMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(milestone.getResponsibleId()))); + } + + return milestone; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void executionMilestone(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Milestone milestone = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(milestone, userId, CommonNumConstants.NUM_SEVEN); + + if (StrUtil.equals(FlowableStateEnum.PASS.getKey(), milestone.getState())) { + // 审核通过可以开始执行 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Milestone::getState), MilestoneStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void complateMilestone(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Milestone milestone = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(milestone, userId, CommonNumConstants.NUM_EIGHT); + + if (StrUtil.equals(MilestoneStateEnum.EXECUTING.getKey(), milestone.getState())) { + // 执行中状态下可以执行完成 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Milestone::getState), MilestoneStateEnum.COMPLETED.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void closeMilestone(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Milestone milestone = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(milestone, userId, CommonNumConstants.NUM_NINE); + + if (StrUtil.equals(MilestoneStateEnum.COMPLETED.getKey(), milestone.getState())) { + // 执行完成状态下可以关闭 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Milestone::getState), MilestoneStateEnum.CLOSE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + @Override + public void queryAllExecutingMilestoneList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + if (StrUtil.isEmpty(objectId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getState), MilestoneStateEnum.EXECUTING.getKey()); + List milestoneList = list(queryWrapper); + outputObject.setBeans(milestoneList); + outputObject.settotal(milestoneList.size()); + } + + @Override + public void queryAllApprovalMilestoneList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Milestone::getObjectId), objectId); + List states = Arrays.asList(FlowableStateEnum.DRAFT.getKey(), + FlowableStateEnum.IN_EXAMINE.getKey(), FlowableStateEnum.REJECT.getKey(), FlowableStateEnum.REVOKE.getKey()); + queryWrapper.notIn(MybatisPlusUtil.toColumns(Milestone::getState), states); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Milestone::getStartTime)); + List milestoneList = list(queryWrapper); + milestoneList.forEach(milestone -> { + milestone.setPId(CommonNumConstants.NUM_ZERO.toString()); + }); + outputObject.setBeans(milestoneList); + outputObject.settotal(milestoneList.size()); + } +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/classenum/ProjectStateEnum.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/classenum/ProjectStateEnum.java new file mode 100644 index 0000000..d2da5a9 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/classenum/ProjectStateEnum.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: ProjectStateEnum + * @Description: 项目状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProjectStateEnum implements SkyeyeEnumClass { + + EXECUTING("executing", "执行中", true, false), + COMPLETED("completed", "已完成", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/controller/ProProjectController.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/controller/ProProjectController.java new file mode 100644 index 0000000..df632ad --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/controller/ProProjectController.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.project.entity.Project; +import com.skyeye.project.service.ProProjectService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ProProjectController + * @Description: 项目管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "项目管理", tags = "项目管理", modelName = "项目管理") +public class ProProjectController { + + @Autowired + private ProProjectService proProjectService; + + /** + * 获取项目管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProProjectList", value = "获取项目管理列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ProProjectController/queryProProjectList") + public void queryProProjectList(InputObject inputObject, OutputObject outputObject) { + proProjectService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeProject", value = "新增/编辑项目信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Project.class) + @RequestMapping("/post/ProProjectController/writeProject") + public void writeProject(InputObject inputObject, OutputObject outputObject) { + proProjectService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id批量获取项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProProjectByIds", value = "根据id批量获取项目信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/ProProjectController/queryProProjectByIds") + public void queryProProjectByIds(InputObject inputObject, OutputObject outputObject) { + proProjectService.selectByIds(inputObject, outputObject); + } + + /** + * 项目提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject008", value = "项目提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "[提交审批]操作必填审批人", required = "required")}) + @RequestMapping("/post/ProProjectController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + proProjectService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除项目信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject009", value = "删除项目信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProProjectController/deleteProjectById") + public void deleteProjectById(InputObject inputObject, OutputObject outputObject) { + proProjectService.deleteById(inputObject, outputObject); + } + + /** + * 撤销项目审批申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject010", value = "撤销项目审批申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程id", required = "required")}) + @RequestMapping("/post/ProProjectController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + proProjectService.revoke(inputObject, outputObject); + } + + /** + * 作废项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject011", value = "作废项目", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProProjectController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + proProjectService.invalid(inputObject, outputObject); + } + + /** + * 开始执行项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject012", value = "开始执行项目", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProProjectController/executeProjectById") + public void executeProjectById(InputObject inputObject, OutputObject outputObject) { + proProjectService.executeProjectById(inputObject, outputObject); + } + + /** + * 信息完善 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "proproject016", value = "信息完善", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "actualStartTime", name = "actualStartTime", value = "实际开始时间", required = "required"), + @ApiImplicitParam(id = "actualEndTime", name = "actualEndTime", value = "实际结束时间", required = "required"), + @ApiImplicitParam(id = "resultsContent", name = "resultsContent", value = "总结", required = "required")}) + @RequestMapping("/post/ProProjectController/perfectProjectById") + public void perfectProjectById(InputObject inputObject, OutputObject outputObject) { + proProjectService.perfectProjectById(inputObject, outputObject); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/dao/ProProjectDao.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/dao/ProProjectDao.java new file mode 100644 index 0000000..71b7e4d --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/dao/ProProjectDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.project.entity.Project; + +/** + * @ClassName: ProProjectDao + * @Description: 项目管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/5 20:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProProjectDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/entity/Project.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/entity/Project.java new file mode 100644 index 0000000..e3fa709 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/entity/Project.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Project + * @Description: 项目实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/1 15:52 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.PM_PROJECT_CACHE_KEY, cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "pro_project", autoResultMap = true) +@ApiModel("项目实体类") +public class Project extends SkyeyeFlowable { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "number_code") + @ApiModelProperty(value = "项目编号") + private String numberCode; + + @TableField(value = "type_id") + @ApiModelProperty(value = "项目分类,数据来源数据字典", required = "required") + private String typeId; + + @TableField(value = "department_id") + @ApiModelProperty(value = "所属部门id") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Map departmentMation; + + @TableField("start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String endTime; + + @TableField("holder_id") + @ApiModelProperty(value = "关联的客户/供应商id", required = "required") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/供应商") + private Map holderMation; + + @TableField("holder_key") + @ApiModelProperty(value = "关联的客户/供应商的className") + private String holderKey; + + @TableField("contract_id") + @ApiModelProperty(value = "关联的合同id", required = "required") + private String contractId; + + @TableField(exist = false) + @Property(value = "关联的合同信息") + private Map contractMation; + + @TableField(value = "estimated_workload") + @ApiModelProperty(value = "预估工作量") + private String estimatedWorkload; + + @TableField(value = "estimated_cost") + @ApiModelProperty(value = "预估成本费用", required = "double", defaultValue = "0") + private String estimatedCost; + + @TableField(value = "business_content") + @ApiModelProperty(value = "业务需求和目标", required = "required") + private String businessContent; + + @TableField(value = "project_content") + @ApiModelProperty(value = "项目组织和分工") + private String projectContent; + + @TableField(value = "plan_content") + @ApiModelProperty(value = "实施计划和方案") + private String planContent; + + @TableField("actual_start_time") + @ApiModelProperty(value = "实际开始时间,项目完结时必填") + private String actualStartTime; + + @TableField("actual_end_time") + @ApiModelProperty(value = "实际结束时间,项目完结时必填") + private String actualEndTime; + + @TableField("results_content") + @ApiModelProperty(value = "总结,项目完结时必填") + private String resultsContent; + + @TableField("speed_of_progress") + @ApiModelProperty(value = "实施进度 默认为0,最大为100", defaultValue = "0") + private Integer speedOfProgress; + + @TableField(value = "team_template_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "团队模板id") + private String teamTemplateId; + + @TableField(exist = false) + @ApiModelProperty(value = "项目组织附件", required = "json") + private Enclosure projectEnclosureInfo; + + @TableField(exist = false) + @ApiModelProperty(value = "实施计划附件", required = "json") + private Enclosure planEnclosureInfo; + + @TableField(exist = false) + @ApiModelProperty(value = "项目成果附件,项目完结时填写", required = "json") + private Enclosure resultsEnclosureInfo; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/ProProjectService.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/ProProjectService.java new file mode 100644 index 0000000..a21dc22 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/ProProjectService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.project.entity.Project; + +/** + * @ClassName: ProProjectService + * @Description: 项目管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/1 16:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ProProjectService extends SkyeyeFlowableService { + + void executeProjectById(InputObject inputObject, OutputObject outputObject); + + void perfectProjectById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/impl/ProProjectServiceImpl.java b/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/impl/ProProjectServiceImpl.java new file mode 100644 index 0000000..586578b --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/project/service/impl/ProProjectServiceImpl.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.project.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.CorrespondentEnterEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.crm.service.IContractService; +import com.skyeye.crm.service.ICustomerService; +import com.skyeye.erp.service.ISupplierContractService; +import com.skyeye.erp.service.ISupplierService; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.project.classenum.ProjectStateEnum; +import com.skyeye.project.dao.ProProjectDao; +import com.skyeye.project.entity.Project; +import com.skyeye.project.service.ProProjectService; +import com.skyeye.sdk.catalog.service.CatalogSdkService; +import com.skyeye.team.service.ITeamBusinessService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ProProjectServiceImpl + * @Description: 项目管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "项目管理", groupName = "项目管理", flowable = true) +public class ProProjectServiceImpl extends SkyeyeFlowableServiceImpl implements ProProjectService, CatalogSdkService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ITeamBusinessService iTeamBusinessService; + + @Autowired + private ICustomerService iCustomerService; + + @Autowired + private ISupplierService iSupplierService; + + @Autowired + private IContractService iContractService; + + @Autowired + private ISupplierContractService iSupplierContractService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (StrUtil.equals("myCharge", commonPageInfo.getType())) { + // 我负责的 + List teamTemplateIds = iTeamBusinessService.getMyTeamIds(); + if (CollectionUtil.isEmpty(teamTemplateIds)) { + throw new CustomException("您还不在任何团队中,请联系管理员"); + } + queryWrapper.in(MybatisPlusUtil.toColumns(Project::getTeamTemplateId), teamTemplateIds); + } else if (StrUtil.equals("myCreate", commonPageInfo.getType())) { + // 我创建的 + queryWrapper.eq(MybatisPlusUtil.toColumns(Project::getCreateId), userId); + } else if (StrUtil.equals("All", commonPageInfo.getType())) { + // 所有的 + } + return queryWrapper; + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + return beans; + } + + @Override + public void createPostpose(Project entity, String userId) { + // 创建团队信息 + iTeamBusinessService.createTeamBusiness(entity.getTeamTemplateId(), entity.getId(), getServiceClassName()); + } + + @Override + public void deletePostpose(String id) { + iTeamBusinessService.deleteTeamBusiness(id, getServiceClassName()); + } + + @Override + public void validatorEntity(Project entity) { + if (StrUtil.isEmpty(entity.getNumberCode())) { + return; + } + // 校验基础信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Project::getNumberCode), entity.getNumberCode()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + Project checkProject = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkProject)) { + throw new CustomException("该项目编号已存在."); + } + } + + @Override + public Project selectById(String id) { + Project project = super.selectById(id); + // 部门 + iDepmentService.setDataMation(project, Project::getDepartmentId); + // 往来单位 + Map contractMation = new HashMap<>(); + if (StrUtil.equals(project.getHolderKey(), CorrespondentEnterEnum.CUSTOM.getKey())) { + project.setHolderMation(iCustomerService.queryDataMationById(project.getHolderId())); + contractMation = iContractService.queryDataMationById(project.getContractId()); + } else if (StrUtil.equals(project.getHolderKey(), CorrespondentEnterEnum.SUPPLIER.getKey())) { + project.setHolderMation(iSupplierService.queryDataMationById(project.getHolderId())); + contractMation = iSupplierContractService.queryDataMationById(project.getContractId()); + } + contractMation.put("name", contractMation.get("title")); + project.setContractMation(contractMation); + return project; + } + + @Override + public List selectByIds(String... ids) { + List projects = super.selectByIds(ids); + // 部门 + iDepmentService.setDataMation(projects, Project::getDepartmentId); + // 往来单位 + // 供应商 + List supplierIds = projects.stream() + .filter(project -> StrUtil.equals(CorrespondentEnterEnum.SUPPLIER.getKey(), project.getHolderKey())) + .map(Project::getHolderId).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(supplierIds)) { + Map> supplierMap = iSupplierService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(supplierIds)); + projects.forEach(project -> { + if (StrUtil.equals(CorrespondentEnterEnum.SUPPLIER.getKey(), project.getHolderKey())) { + Map tempMap = supplierMap.get(project.getHolderId()); + tempMap.put("name", tempMap.get("title")); + project.setHolderMation(tempMap); + } + }); + } + // 客户 + List customerIds = projects.stream() + .filter(project -> StrUtil.equals(CorrespondentEnterEnum.CUSTOM.getKey(), project.getHolderKey())) + .map(Project::getHolderId).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(customerIds)) { + Map> customerMap = iCustomerService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(customerIds)); + projects.forEach(project -> { + if (StrUtil.equals(CorrespondentEnterEnum.CUSTOM.getKey(), project.getHolderKey())) { + Map tempMap = customerMap.get(project.getHolderId()); + tempMap.put("name", tempMap.get("title")); + project.setHolderMation(tempMap); + } + }); + } + return projects; + } + + /** + * 开始执行项目 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void executeProjectById(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + Project bean = selectById(id); + // 执行中状态下可以完善成果与总结信息 + if (StrUtil.equals(bean.getState(), FlowableStateEnum.PASS.getKey())) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Project::getState), ProjectStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("数据状态已改变,请刷新页面!"); + } + } + + /** + * 信息完善 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void perfectProjectById(InputObject inputObject, OutputObject outputObject) { + Project project = inputObject.getParams(Project.class); + Project bean = selectById(project.getId()); + // 执行中或者已完成状态下可以完善成果与总结信息 + if (StrUtil.equals(bean.getState(), ProjectStateEnum.EXECUTING.getKey()) + || StrUtil.equals(bean.getState(), ProjectStateEnum.COMPLETED.getKey())) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, project.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(Project::getActualStartTime), project.getActualStartTime()); + updateWrapper.set(MybatisPlusUtil.toColumns(Project::getActualEndTime), project.getActualEndTime()); + updateWrapper.set(MybatisPlusUtil.toColumns(Project::getState), ProjectStateEnum.COMPLETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Project::getResultsContent), project.getResultsContent()); + update(updateWrapper); + refreshCache(project.getId()); + } else { + outputObject.setreturnMessage("数据状态已改变,请刷新页面!"); + } + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskAuthEnum.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskAuthEnum.java new file mode 100644 index 0000000..44f3eb7 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskAuthEnum.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: TaskAuthEnum + * @Description: 任务权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 23:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TaskAuthEnum implements SkyeyeEnumClass { + + LIST("list", "所有任务列表", true, false), + MY_EXECUTE("myExecute", "我执行的任务列表", true, false), + MY_CREATE("myCreate", "我创建的任务列表", true, false), + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false), + REVOKE("revoke", "撤销", true, false), + INVALID("invalid", "作废", true, false), + SUBMIT_TO_APPROVAL("submitToApproval", "提交审批", true, false), + + EXECUTING("executing", "执行中", true, false), + COMPLETED("completed", "执行完成", true, false), + CLOSE("close", "已关闭", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskImported.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskImported.java new file mode 100644 index 0000000..5a46e00 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskImported.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: TaskImported + * @Description: 任务重要性 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/14 20:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TaskImported implements SkyeyeEnumClass { + + ORDINARY("ordinary", "普通", true, true), + COMMONLY("commonly", "一般", true, false), + IMPORTANT("important", "重要", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskStateEnum.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskStateEnum.java new file mode 100644 index 0000000..573ff71 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/classenum/TaskStateEnum.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.common.enumeration.FlowableStateEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: TaskStateEnum + * @Description: 任务状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TaskStateEnum implements SkyeyeEnumClass { + + EXECUTING("executing", "执行中", true, false), + COMPLETED("completed", "执行完成", true, false), + CLOSE("close", "已关闭", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(FlowableStateEnum.class); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/controller/ProTaskController.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/controller/ProTaskController.java new file mode 100644 index 0000000..6dd5cd5 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/controller/ProTaskController.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.task.entity.Task; +import com.skyeye.task.service.ProTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ProTaskController + * @Description: 项目任务管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 20:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "任务管理", tags = "任务管理", modelName = "任务管理") +public class ProTaskController { + + @Autowired + private ProTaskService proTaskService; + + /** + * 获取任务列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProTaskList", value = "获取任务列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ProTaskController/queryProTaskList") + public void queryProTaskList(InputObject inputObject, OutputObject outputObject) { + proTaskService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑任务管理 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTask", value = "新增/编辑任务管理", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Task.class) + @RequestMapping("/post/ProTaskController/writeTask") + public void writeTask(InputObject inputObject, OutputObject outputObject) { + proTaskService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteProTaskById", value = "删除任务信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProTaskController/deleteProTaskById") + public void deleteProTaskById(InputObject inputObject, OutputObject outputObject) { + proTaskService.deleteById(inputObject, outputObject); + } + + /** + * 撤销任务审批申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeTask", value = "撤销任务审批申请", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/ProTaskController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + proTaskService.revoke(inputObject, outputObject); + } + + /** + * 任务提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitToApprovalTask", value = "任务提交审批", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/ProTaskController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + proTaskService.submitToApproval(inputObject, outputObject); + } + + /** + * 作废任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "invalidTask", value = "作废任务", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProTaskController/invalid") + public void invalid(InputObject inputObject, OutputObject outputObject) { + proTaskService.invalid(inputObject, outputObject); + } + + /** + * 任务开始执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "executionTask", value = "任务开始执行", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProTaskController/executionTask") + public void executionTask(InputObject inputObject, OutputObject outputObject) { + proTaskService.executionTask(inputObject, outputObject); + } + + /** + * 任务执行完成 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "complateTask", value = "任务执行完成", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "actualWorkload", name = "actualWorkload", value = "实际工作量", required = "required"), + @ApiImplicitParam(id = "executionResult", name = "executionResult", value = "执行结果", required = "required"), + @ApiImplicitParam(id = "executionEnclosureInfo", name = "executionEnclosureInfo", value = "执行结果附件", required = "json")}) + @RequestMapping("/post/ProTaskController/complateTask") + public void complateTask(InputObject inputObject, OutputObject outputObject) { + proTaskService.complateTask(inputObject, outputObject); + } + + /** + * 任务关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "closeTask", value = "任务关闭", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ProTaskController/closeTask") + public void closeTask(InputObject inputObject, OutputObject outputObject) { + proTaskService.closeTask(inputObject, outputObject); + } + + /** + * 获取任务列表(甘特图) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryProTaskListForGantt", value = "获取任务列表(甘特图)", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TableSelectInfo.class) + @RequestMapping("/post/ProTaskController/queryProTaskListForGantt") + public void queryProTaskListForGantt(InputObject inputObject, OutputObject outputObject) { + proTaskService.queryProTaskListForGantt(inputObject, outputObject); + } + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/dao/ProTaskDao.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/dao/ProTaskDao.java new file mode 100644 index 0000000..ef7ced3 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/dao/ProTaskDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.task.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.task.entity.Task; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName: ProTaskDao + * @Description: 项目任务相关数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/1 12:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProTaskDao extends SkyeyeBaseMapper { + + /** + * 根据父id查询所有的子节点信息(包含父id),如果是多个 + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/entity/Task.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/entity/Task.java new file mode 100644 index 0000000..edc2908 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/entity/Task.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.milestone.entity.Milestone; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Task + * @Description: 任务实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/1 15:52 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@UniqueField(value = {"objectId", "name"}) +@RedisCacheField(name = "pm:task", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "pro_task", autoResultMap = true) +@ApiModel("任务实体类") +public class Task extends SkyeyeFlowable { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "type_id") + @ApiModelProperty(value = "任务分类,数据来源数据字典", required = "required") + private String typeId; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(value = "department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Map departmentMation; + + @TableField("start_time") + @ApiModelProperty(value = "计划开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "计划结束时间", required = "required") + private String endTime; + + @TableField(value = "perform_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "执行人ID") + private List performId; + + @TableField(exist = false) + @Property(value = "执行人") + private List> performMation; + + @TableField(value = "estimated_workload") + @ApiModelProperty(value = "预估工作量") + private String estimatedWorkload; + + @TableField(value = "actual_workload") + @ApiModelProperty(value = "实际工作量") + private String actualWorkload; + + @TableField(value = "task_instructions") + @ApiModelProperty(value = "任务说明", required = "required") + private String taskInstructions; + + @TableField(value = "execution_result") + @ApiModelProperty(value = "执行结果") + private String executionResult; + + @TableField(exist = false) + @ApiModelProperty(value = "执行结果附件", required = "json") + private Enclosure executionEnclosureInfo; + + @TableField("imported") + @ApiModelProperty(value = "重要性,参考#TaskImported", required = "required") + private String imported; + + @TableField(value = "milestone_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "里程碑id") + private String milestoneId; + + @TableField(exist = false) + @Property(value = "里程碑信息") + private Milestone milestoneMation; + + @TableField(value = "parent_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "父节点id") + private String parentId; + +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/ProTaskService.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/ProTaskService.java new file mode 100644 index 0000000..06096d4 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/ProTaskService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.task.entity.Task; + +/** + * @ClassName: ProTaskService + * @Description: 项目任务管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/1 20:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ProTaskService extends SkyeyeFlowableService { + + void executionTask(InputObject inputObject, OutputObject outputObject); + + void complateTask(InputObject inputObject, OutputObject outputObject); + + void closeTask(InputObject inputObject, OutputObject outputObject); + + void queryProTaskListForGantt(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/impl/ProTaskServiceImpl.java b/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/impl/ProTaskServiceImpl.java new file mode 100644 index 0000000..750aa04 --- /dev/null +++ b/skyeye-project/project-pro/src/main/java/com/skyeye/task/service/impl/ProTaskServiceImpl.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.task.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.util.PersistableHandlerExecutor; +import com.skyeye.common.base.handler.util.eitity.ExecuteTypeEnum; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.enumeration.ScheduleDayObjectType; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.rest.schedule.OtherModuleScheduleMation; +import com.skyeye.eve.service.IScheduleDayService; +import com.skyeye.exception.CustomException; +import com.skyeye.milestone.entity.Milestone; +import com.skyeye.milestone.service.MilestoneService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.task.classenum.TaskAuthEnum; +import com.skyeye.task.classenum.TaskStateEnum; +import com.skyeye.task.dao.ProTaskDao; +import com.skyeye.task.entity.Task; +import com.skyeye.task.service.ProTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ProTaskServiceImpl + * @Description: 项目任务管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 13:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "任务管理", groupName = "任务管理", flowable = true, teamAuth = true) +public class ProTaskServiceImpl extends SkyeyeFlowableServiceImpl implements ProTaskService { + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private IScheduleDayService iScheduleDayService; + + @Autowired + private MilestoneService milestoneService; + + @Override + public Class getAuthEnumClass() { + return TaskAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(TaskAuthEnum.ADD.getKey(), TaskAuthEnum.EDIT.getKey(), TaskAuthEnum.DELETE.getKey(), + TaskAuthEnum.REVOKE.getKey(), TaskAuthEnum.INVALID.getKey(), TaskAuthEnum.SUBMIT_TO_APPROVAL.getKey(), TaskAuthEnum.LIST.getKey(), + TaskAuthEnum.EXECUTING.getKey(), TaskAuthEnum.COMPLETED.getKey(), TaskAuthEnum.CLOSE.getKey(), TaskAuthEnum.MY_EXECUTE.getKey(), TaskAuthEnum.MY_CREATE.getKey()); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + setQueryWrapper(commonPageInfo, queryWrapper); + return queryWrapper; + } + + private void setQueryWrapper(TableSelectInfo commonPageInfo, QueryWrapper queryWrapper) { + Task task = ReflectUtil.newInstance(clazz); + task.setObjectId(commonPageInfo.getObjectId()); + task.setObjectKey(commonPageInfo.getObjectKey()); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (StrUtil.equals("myExecute", commonPageInfo.getType())) { + // 我执行的 + checkAuthPermission(task, userId, CommonNumConstants.NUM_TEN); + queryWrapper.apply("INSTR(CONCAT(',', REPLACE(REPLACE(" + MybatisPlusUtil.toColumns(Task::getPerformId) + ", '[', ''), ']', ''), ','), CONCAT(',\"', {0}, '\",'))", userId); + } else if (StrUtil.equals("myCreate", commonPageInfo.getType())) { + // 我创建的 + checkAuthPermission(task, userId, CommonNumConstants.NUM_ELEVEN); + queryWrapper.eq(MybatisPlusUtil.toColumns(Task::getCreateId), userId); + } else if (StrUtil.equals("list", commonPageInfo.getType())) { + // 所有的 + checkAuthPermission(task, userId, CommonNumConstants.NUM_SIX); + } + if (StrUtil.isNotEmpty(commonPageInfo.getObjectId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Task::getObjectId), commonPageInfo.getObjectId()); + } + if (StrUtil.isNotEmpty(commonPageInfo.getHolderId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Task::getMilestoneId), commonPageInfo.getHolderId()); + } + } + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + List ids = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return beans; + } + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(ids); + beans = selectMapByIds(childIds).values().stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + beans.forEach(bean -> { + bean.put("lay_is_open", true); + }); + + milestoneService.setMationForMap(beans, "milestoneId", "milestoneMation"); + return beans; + } + + @Override + public void createPrepose(Task entity) { + super.createPrepose(entity); + if (StrUtil.isNotEmpty(entity.getParentId())) { + Task task = selectById(entity.getParentId()); + entity.setMilestoneId(task.getMilestoneId()); + } else { + entity.setParentId(CommonNumConstants.NUM_ZERO.toString()); + } + checkTime(entity.getMilestoneId(), entity.getStartTime(), entity.getEndTime()); + } + + @Override + protected void updatePrepose(Task entity) { + super.updatePrepose(entity); + Task oldTask = selectById(entity.getId()); + checkTime(oldTask.getMilestoneId(), entity.getStartTime(), entity.getEndTime()); + } + + private void checkTime(String milestoneId, String startTime, String endTime) { + Milestone milestone = milestoneService.selectById(milestoneId); + if (DateUtil.getDistanceDay(milestone.getStartTime(), startTime) < 0) { + // 任务开始时间小于里程碑开始时间 + throw new CustomException("任务开始时间不能早于里程碑开始时间"); + } + if (DateUtil.getDistanceDay(milestone.getEndTime(), endTime) > 0) { + // 任务结束时间大于里程碑结束时间 + throw new CustomException("任务结束时间不能晚于里程碑结束时间"); + } + } + + @Override + public void deleteById(String id) { + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(Arrays.asList(id)); + deleteById(childIds); + } + + @Override + public Task selectById(String id) { + Task task = super.selectById(id); + task.setDepartmentMation(iDepmentService.queryDataMationById(task.getDepartmentId())); + task.setPerformMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(task.getPerformId()))); + milestoneService.setDataMation(task, Task::getMilestoneId); + return task; + } + + @Override + public List selectByIds(String... ids) { + List tasks = super.selectByIds(ids); + iDepmentService.setDataMation(tasks, Task::getDepartmentId); + + List performIdList = tasks.stream() + .filter(bean -> CollectionUtil.isNotEmpty(bean.getPerformId())) + .flatMap(norms -> norms.getPerformId().stream()).distinct().collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(performIdList)) { + Map> userMap = iAuthUserService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(performIdList)); + tasks.forEach(task -> { + if (CollectionUtil.isEmpty(task.getPerformId())) { + return; + } + List> userMation = new ArrayList<>(); + task.getPerformId().forEach(performId -> { + if (!userMap.containsKey(performId)) { + return; + } + userMation.add(userMap.get(performId)); + }); + task.setPerformMation(userMation); + }); + } + return tasks; + } + + @Override + public void approvalEndIsSuccess(Task entity) { + for (String executorId : entity.getPerformId()) { + OtherModuleScheduleMation scheduleMation = new OtherModuleScheduleMation(); + scheduleMation.setTitle(entity.getName()); + scheduleMation.setContent(entity.getTaskInstructions()); + scheduleMation.setStartTime(String.format(Locale.ROOT, "%s 00:00:00", entity.getStartTime())); + scheduleMation.setEndTime(String.format(Locale.ROOT, "%s 23:59:59", entity.getEndTime())); + scheduleMation.setUserId(executorId); + scheduleMation.setObjectId(entity.getId()); + scheduleMation.setObjectType(ScheduleDayObjectType.PRO_TASK.getKey()); + iScheduleDayService.insertScheduleMationByOtherModule(scheduleMation); + } + } + + /** + * 任务开始执行 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void executionTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Task task = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(task, userId, CommonNumConstants.NUM_SEVEN); + + if (StrUtil.equals(FlowableStateEnum.PASS.getKey(), task.getState())) { + // 审核通过状态下可以开始执行 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Task::getState), TaskStateEnum.EXECUTING.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 任务执行完成 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void complateTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Task task = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(task, userId, CommonNumConstants.NUM_EIGHT); + + if (StrUtil.equals(TaskStateEnum.EXECUTING.getKey(), task.getState())) { + // 执行中状态下可以执行完成 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Task::getState), TaskStateEnum.COMPLETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Task::getActualWorkload), map.get("actualWorkload").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Task::getExecutionResult), map.get("executionResult").toString()); + update(updateWrapper); + // 处理附件 + Enclosure executionEnclosureInfo = JSONUtil.toBean(map.get("executionEnclosureInfo").toString(), Enclosure.class); + task.setExecutionEnclosureInfo(executionEnclosureInfo); + PersistableHandlerExecutor.executorHandler(task, ExecuteTypeEnum.POST_EXECUTION.getType()); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 任务关闭 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void closeTask(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Task task = selectById(id); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + checkAuthPermission(task, userId, CommonNumConstants.NUM_NINE); + + if (StrUtil.equals(TaskStateEnum.COMPLETED.getKey(), task.getState())) { + // 执行完成状态下可以关闭 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Task::getState), TaskStateEnum.CLOSE.getKey()); + update(updateWrapper); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + @Override + public void queryProTaskListForGantt(InputObject inputObject, OutputObject outputObject) { + TableSelectInfo tableSelectInfo = inputObject.getParams(TableSelectInfo.class); + if (StrUtil.isEmpty(tableSelectInfo.getHolderId())) { + return; + } + // 查询数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + setQueryWrapper(tableSelectInfo, queryWrapper); + List list = list(queryWrapper); + if (CollectionUtil.isEmpty(list)) { + return; + } + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list), null); + // 构造数据 + List> node = new ArrayList<>(); + List> link = new ArrayList<>(); + beans.forEach(bean -> { + node.add(getNode(bean)); + String parentId = MapUtil.checkKeyIsNull(bean, "parentId") ? "" : bean.get("parentId").toString(); + if (StrUtil.isNotEmpty(parentId) && !StrUtil.equals(parentId, CommonNumConstants.NUM_ZERO.toString())) { + link.add(getLink(bean)); + } + }); + Map result = new HashMap<>(); + result.put("node", node); + result.put("link", link); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private Map getNode(Map bean) { + Map retult = new HashMap<>(); + retult.put("id", bean.get("id")); + retult.put("text", bean.get("name")); + retult.put("parent", bean.get("parentId")); + retult.put("start_date", bean.get("startTime")); + retult.put("end_date", bean.get("endTime")); + retult.put("open", true); + return retult; + } + + private Map getLink(Map bean) { + Map retult = new HashMap<>(); + retult.put("id", bean.get("id") + "CC"); + retult.put("source", bean.get("parentId")); + retult.put("target", bean.get("id")); + retult.put("type", CommonNumConstants.NUM_ZERO); + return retult; + } + +} diff --git a/skyeye-project/project-pro/src/main/resources/mapper/task/ProTaskMapper.xml b/skyeye-project/project-pro/src/main/resources/mapper/task/ProTaskMapper.xml new file mode 100644 index 0000000..feb8e79 --- /dev/null +++ b/skyeye-project/project-pro/src/main/resources/mapper/task/ProTaskMapper.xml @@ -0,0 +1,35 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-project/project-web/.gitignore b/skyeye-project/project-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-project/project-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-project/project-web/pom.xml b/skyeye-project/project-web/pom.xml new file mode 100644 index 0000000..bd6cb5a --- /dev/null +++ b/skyeye-project/project-web/pom.xml @@ -0,0 +1,88 @@ + + + + skyeye-project + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + project-web + + + + + com.skyeye + project-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-project/project-web/src/main/java/com/ProjectApplication.java b/skyeye-project/project-web/src/main/java/com/ProjectApplication.java new file mode 100644 index 0000000..b8c038a --- /dev/null +++ b/skyeye-project/project-web/src/main/java/com/ProjectApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class ProjectApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(ProjectApplication.class, args); + } + +} diff --git a/skyeye-project/project-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-project/project-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..f8d5cdd --- /dev/null +++ b/skyeye-project/project-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-project/project-web/src/main/resources/banner.txt b/skyeye-project/project-web/src/main/resources/banner.txt new file mode 100644 index 0000000..83e4c99 --- /dev/null +++ b/skyeye-project/project-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev project-web.jar >> /opt/service/project/nohup-project.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-project/project-web/src/main/resources/bootstrap.yml b/skyeye-project/project-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..ea8d7fa --- /dev/null +++ b/skyeye-project/project-web/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +server: + port: 8109 + +spring: + application: + name: skyeye-project-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 127.0.0.1:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-project/project-web/src/main/resources/jvm调优参数配置 b/skyeye-project/project-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-project/project-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-project/project-web/src/main/resources/log4j.properties b/skyeye-project/project-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-project/project-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-promote/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/skyeye-promote/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch new file mode 100644 index 0000000..627021f --- /dev/null +++ b/skyeye-promote/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/skyeye-promote/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch b/skyeye-promote/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch new file mode 100644 index 0000000..6ef634c --- /dev/null +++ b/skyeye-promote/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/skyeye-promote/.gitattributes b/skyeye-promote/.gitattributes new file mode 100644 index 0000000..2959201 --- /dev/null +++ b/skyeye-promote/.gitattributes @@ -0,0 +1,3 @@ +*.js linguist-language=java +*.css linguist-language=java +*.html linguist-language=java diff --git a/skyeye-promote/.gitignore b/skyeye-promote/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-promote/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-promote/.project b/skyeye-promote/.project new file mode 100644 index 0000000..fd7b55d --- /dev/null +++ b/skyeye-promote/.project @@ -0,0 +1,52 @@ + + + skyeye-promote + + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/skyeye-promote/pom.xml b/skyeye-promote/pom.xml new file mode 100644 index 0000000..ea9ecf0 --- /dev/null +++ b/skyeye-promote/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-promote + 0.0.1-SNAPSHOT + pom + + + skyeye-web + skyeye-common + skyeye-entity + skyeye-quartz + skyeye-mq + skyeye-userauth + skyeye-threed + skyeye-code-doc + skyeye-gateway + skyeye-organization + skyeye-api + skyeye-base-server + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-api/.gitignore b/skyeye-promote/skyeye-api/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-api/pom.xml b/skyeye-promote/skyeye-api/pom.xml new file mode 100644 index 0000000..9d42943 --- /dev/null +++ b/skyeye-promote/skyeye-api/pom.xml @@ -0,0 +1,29 @@ + + + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + skyeye-api + + + UTF-8 + + + + + + + com.skyeye + skyeye-entity + 0.0.1-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiController.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiController.java new file mode 100644 index 0000000..5a81321 --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiController.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.service.ApiService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "公共接口", tags = "公共接口", modelName = "API模块") +public class ApiController { + + @Autowired + private ApiService apiService; + + /** + * 获取接口列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllSysEveReqMapping", value = "获取接口列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "appId", name = "appId", value = "微服务的APPID", required = "required")}) + @RequestMapping("/post/ApiController/queryAllSysEveReqMapping") + public void queryAllSysEveReqMapping(InputObject inputObject, OutputObject outputObject) { + apiService.queryAllSysEveReqMapping(inputObject, outputObject); + } + + /** + * 获取接口详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryApiDetails", value = "获取接口详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "appId", name = "appId", value = "微服务的APPID", required = "required"), + @ApiImplicitParam(id = "rowId", name = "id", value = "接口id", required = "required")}) + @RequestMapping("/post/ApiController/queryApiDetails") + public void queryApiDetails(InputObject inputObject, OutputObject outputObject) { + apiService.queryApiDetails(inputObject, outputObject); + } + + /** + * 获取限制条件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLimitRestrictions", value = "获取限制条件", method = "GET", allUse = "2") + @RequestMapping("/post/ApiController/queryLimitRestrictions") + public void queryLimitRestrictions(InputObject inputObject, OutputObject outputObject) { + apiService.queryLimitRestrictions(inputObject, outputObject); + } + + /** + * 获取所有微服务列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryApiMicroservices", value = "获取所有微服务列表", method = "GET", allUse = "2") + @RequestMapping("/post/ApiController/queryApiMicroservices") + public void queryApiMicroservices(InputObject inputObject, OutputObject outputObject) { + apiService.queryApiMicroservices(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiMationController.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiMationController.java new file mode 100644 index 0000000..7113f36 --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/controller/ApiMationController.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.api.ApiMation; +import com.skyeye.service.ApiMationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "公共接口", tags = "公共接口", modelName = "API模块") +public class ApiMationController { + + @Autowired + private ApiMationService apiMationService; + + /** + * 新增/编辑api接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeApiMation", value = "新增/编辑api接口信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ApiMation.class) + @RequestMapping("/post/ApiMationController/writeApiMation") + public void writeApiMation(InputObject inputObject, OutputObject outputObject) { + apiMationService.writeApiMation(inputObject, outputObject); + } + + /** + * 删除api接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteApiMationById", value = "删除api接口信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ApiMationController/deleteApiMationById") + public void deleteApiMationById(InputObject inputObject, OutputObject outputObject) { + apiMationService.deleteApiMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/dao/ApiMationDao.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/dao/ApiMationDao.java new file mode 100644 index 0000000..116e313 --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/dao/ApiMationDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.entity.api.ApiMation; + +/** + * @ClassName: ApiMationDao + * @Description: api接口数据层 + * @author: skyeye云系列 + * @date: 2021/11/28 12:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ApiMationDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/rest/IServiceApiRest.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/rest/IServiceApiRest.java new file mode 100644 index 0000000..0663dfe --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/rest/IServiceApiRest.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.net.URI; + +/** + * @ClassName: IServiceApiRest + * @Description: 服务接口管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/19 17:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(name = "IServiceApiRest${spring.application.name}", configuration = ClientConfiguration.class, url = "EMPTY") +public interface IServiceApiRest { + + /** + * 获取接口列表 + * + * @return + */ + @GetMapping("/queryAllServiceApiList") + String queryAllServiceApiList(URI uri); + + /** + * 根据id查询接口 + * + * @return + */ + @GetMapping("/queryServiceApiById") + String queryServiceApiById(URI uri, @RequestParam("apiId") String apiId); + +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiMationService.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiMationService.java new file mode 100644 index 0000000..265a6ce --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiMationService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.api.ApiMation; + +import java.util.List; + +public interface ApiMationService { + + void writeApiMation(InputObject inputObject, OutputObject outputObject); + + List queryApiMationByAppIdAndUrlId(String appId, String urlId); + + void deleteApiMationById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiService.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiService.java new file mode 100644 index 0000000..4538abe --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/ApiService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ApiService { + + void queryAllSysEveReqMapping(InputObject inputObject, OutputObject outputObject); + + void queryApiDetails(InputObject inputObject, OutputObject outputObject); + + void queryLimitRestrictions(InputObject inputObject, OutputObject outputObject); + + void queryApiMicroservices(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiMationServiceImpl.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiMationServiceImpl.java new file mode 100644 index 0000000..4bb3c0a --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiMationServiceImpl.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dao.ApiMationDao; +import com.skyeye.eve.entity.api.ApiMation; +import com.skyeye.service.ApiMationService; +import org.apache.commons.lang3.StringUtils; +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.ObjectUtils; + +import java.util.List; + +/** + * @ClassName: ApiMationServiceImpl + * @Description: api接口服务类 + * @author: skyeye云系列 + * @date: 2021/11/28 12:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ApiMationServiceImpl implements ApiMationService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApiMationServiceImpl.class); + + @Autowired + private ApiMationDao apiMationDao; + + /** + * 编辑api接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void writeApiMation(InputObject inputObject, OutputObject outputObject) { + ApiMation apiMation = inputObject.getParams(ApiMation.class); + // 1.校验 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApiMation::getAppId), apiMation.getAppId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApiMation::getRequestUrl), apiMation.getRequestUrl()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApiMation::getTitle), apiMation.getTitle()); + if (StringUtils.isNotEmpty(apiMation.getId())) { + queryWrapper.ne(CommonConstants.ID, apiMation.getId()); + } + ApiMation checkDictTypeMation = apiMationDao.selectOne(queryWrapper); + if (ObjectUtils.isEmpty(checkDictTypeMation)) { + // 2.新增/编辑数据 + if (StringUtils.isNotEmpty(apiMation.getId())) { + LOGGER.info("update ApiMation data, id is {}", apiMation.getId()); + apiMationDao.updateById(apiMation); + } else { + DataCommonUtil.setId(apiMation); + LOGGER.info("insert ApiMation data, id is {}", apiMation.getId()); + apiMationDao.insert(apiMation); + } + outputObject.setBean(apiMation); + } else { + outputObject.setreturnMessage("this data [title] is non-existent."); + } + } + + /** + * 根据appId和urlId获取接口参数信息 + * + * @param appId + * @param urlId + * @return + */ + @Override + public List queryApiMationByAppIdAndUrlId(String appId, String urlId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApiMation::getAppId), appId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApiMation::getRequestUrl), urlId); + List apiMations = apiMationDao.selectList(queryWrapper); + return apiMations; + } + + /** + * 删除api接口信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteApiMationById(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + apiMationDao.deleteById(id); + } + +} + diff --git a/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiServiceImpl.java b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiServiceImpl.java new file mode 100644 index 0000000..ba13539 --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/java/com/skyeye/service/impl/ApiServiceImpl.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.ApiConstants; +import com.skyeye.common.enumeration.VerificationParamsEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.api.ApiMation; +import com.skyeye.eve.entity.search.SearchMation; +import com.skyeye.eve.service.SearchConfigService; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.rest.IServiceApiRest; +import com.skyeye.service.ApiMationService; +import com.skyeye.service.ApiService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.net.URI; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class ApiServiceImpl implements ApiService { + + @Autowired + private JedisClientService jedisClientService; + + @Value("${spring.profiles.active}") + private String env; + + @Autowired + private SearchConfigService searchConfigService; + + @Autowired + private ApiMationService apiMationService; + + @Autowired + private IServiceApiRest iServiceApiRest; + + @Autowired + private DiscoveryClient discoveryClient; + + /** + * 获取接口列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllSysEveReqMapping(InputObject inputObject, OutputObject outputObject) { + String appId = inputObject.getParams().get("appId").toString(); + String key = ApiConstants.getApiMicroservicesRedisCacheKey(appId, env); + Map microservices = JSONUtil.toBean(jedisClientService.get(key), null); + URI uri = getUri(microservices.get("springApplicationName").toString()); + + List> beans = ExecuteFeignClient.get(() -> iServiceApiRest.queryAllServiceApiList(uri)).getRows(); + beans.forEach(bean -> { + // 注释作为标题 + bean.put("title", bean.get("val")); + }); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + private URI getUri(String springApplicationName) { + // 根据服务名获取服务实例 + List allInstances = discoveryClient.getInstances(springApplicationName); + if (CollectionUtils.isEmpty(allInstances)) { + throw new CustomException(String.format(Locale.ROOT, "this service[%s] has no instance.", springApplicationName)); + } + return RandomUtil.randomEle(allInstances).getUri(); + } + + /** + * 获取接口详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryApiDetails(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String appId = map.get("appId").toString(); + String apiId = map.get("id").toString(); + String key = ApiConstants.getApiMicroservicesRedisCacheKey(appId, env); + Map microservices = JSONUtil.toBean(jedisClientService.get(key), null); + URI uri = getUri(microservices.get("springApplicationName").toString()); + + Map apiMation = ExecuteFeignClient.get(() -> iServiceApiRest.queryServiceApiById(uri, apiId)).getBean(); + if (apiMation != null && !apiMation.isEmpty()) { + String allUse = apiMation.get("allUse").toString(); + String s; + if ("0".equals(allUse)) { + s = "无需登录,无需授权即可访问。"; + } else if ("1".equals(allUse)) { + s = "需要登录,需要授权才能访问。"; + } else if ("2".equals(allUse)) { + s = "需要登录,但无需授权即可访问。"; + } else { + s = "错误参数。"; + } + // 权限说明 + apiMation.put("sq", s); + apiMation.put("requestId", apiId); + List> params = (List>) apiMation.get("list"); + params = params.stream().sorted(Comparator.comparing(bean -> bean.get("number").toString())).collect(Collectors.toList()); + apiMation.put("list", params); + loadSearchConfig(appId, apiId, params, apiMation); + + loadApiParamsMation(appId, apiId, apiMation); + outputObject.setBean(apiMation); + } else { + outputObject.setreturnMessage("该信息不存在。"); + } + } + + /** + * 获取api参数信息 + * + * @param appId + * @param apiId + */ + private void loadApiParamsMation(String appId, String apiId, Map apiMation) { + List apiParamsList = apiMationService.queryApiMationByAppIdAndUrlId(appId, apiId); + apiMation.put("apiParamsList", apiParamsList); + } + + /** + * 加载高级筛选json信息 + * + * @param appId appId + * @param urlId 接口id + * @param params 入参信息 + * @param apiMation api信息 + */ + private void loadSearchConfig(String appId, String urlId, List> params, Map apiMation) { + Map pageParam = params.stream().filter(bean -> "page".equals(bean.get("name").toString())).findFirst().orElse(null); + Map limitParam = params.stream().filter(bean -> "limit".equals(bean.get("name").toString())).findFirst().orElse(null); + apiMation.put("advancedSearch", false); + if (!CollectionUtils.isEmpty(pageParam) && !CollectionUtils.isEmpty(limitParam)) { + apiMation.put("advancedSearch", true); + // 存在分页参数,择取获取高级筛选json + SearchMation searchMation = searchConfigService.querySearchMation(urlId, appId); + if (searchMation != null) { + apiMation.put("searchParams", searchMation.getParamsConfigStr()); + apiMation.put("searchParamsId", searchMation.getId()); + } + } + } + + /** + * 获取限制条件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryLimitRestrictions(InputObject inputObject, OutputObject outputObject) { + List> beans = VerificationParamsEnum.getList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取所有微服务列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryApiMicroservices(InputObject inputObject, OutputObject outputObject) { + List keys = jedisClientService.getKeyListByPattern(ApiConstants.API_MICROSERVICES_REDIS_CACHE_KEY + "*"); + List> result = new ArrayList<>(); + keys.forEach(key -> { + if (key.endsWith(env)) { + result.add(JSONUtil.toBean(jedisClientService.get(key), null)); + } + }); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } +} diff --git a/skyeye-promote/skyeye-api/src/main/resources/mapper/api/ApiMationMapper.xml b/skyeye-promote/skyeye-api/src/main/resources/mapper/api/ApiMationMapper.xml new file mode 100644 index 0000000..711c837 --- /dev/null +++ b/skyeye-promote/skyeye-api/src/main/resources/mapper/api/ApiMationMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/.gitignore b/skyeye-promote/skyeye-base-server/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-promote/skyeye-base-server/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/pom.xml b/skyeye-promote/skyeye-base-server/pom.xml new file mode 100644 index 0000000..45ba420 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/pom.xml @@ -0,0 +1,28 @@ + + + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + skyeye-base-server + + + UTF-8 + + + + + + com.skyeye + skyeye-entity + 0.0.1-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogAuthEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogAuthEnum.java new file mode 100644 index 0000000..73837cc --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CatalogAuthEnum + * @Description: 目录权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CatalogAuthEnum implements SkyeyeEnumClass { + ADD_CATALOG("addCatalog", "添加目录", true, false), + DELETE_CATALOG("deleteCatalog", "删除目录", true, false), + RENAME_CATALOG("renameCatalog", "重命名目录", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogTypeEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogTypeEnum.java new file mode 100644 index 0000000..f11be97 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/classenum/CatalogTypeEnum.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CatalogTypeEnum + * @Description: 目录类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CatalogTypeEnum implements SkyeyeEnumClass { + PUBLIC(1, "公共", true, false), + PRIVATELY_OWNED(2, "私有", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/controller/CatalogController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/controller/CatalogController.java new file mode 100644 index 0000000..b9bee18 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/controller/CatalogController.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.catalog.service.CatalogService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CatalogController + * @Description: 目录管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "目录管理", tags = "目录管理", modelName = "基本服务") +public class CatalogController { + + @Autowired + private CatalogService catalogService; + + /** + * 一次性获取所有的目录为树结构 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCatalogForTree", value = "一次性获取所有的目录为树结构", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id"), + @ApiImplicitParam(id = "objectAppId", name = "objectAppId", value = "所属第三方业务数据的应用id"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key"), + @ApiImplicitParam(id = "addOrUser", name = "addOrUser", value = "是否根据创建人查询", required = "required", defaultValue = "false")}) + @RequestMapping("/post/CatalogController/queryCatalogForTree") + public void queryCatalogForTree(InputObject inputObject, OutputObject outputObject) { + catalogService.queryCatalogForTree(inputObject, outputObject); + } + + /** + * 一次性获取所有的目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCatalogList", value = "一次性获取所有的目录", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id"), + @ApiImplicitParam(id = "objectAppId", name = "objectAppId", value = "所属第三方业务数据的应用id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的应用id", required = "required"), + @ApiImplicitParam(id = "addOrUser", name = "addOrUser", value = "是否根据创建人查询", required = "required", defaultValue = "false")}) + @RequestMapping("/post/CatalogController/queryCatalogList") + public void queryCatalogList(InputObject inputObject, OutputObject outputObject) { + catalogService.queryCatalogList(inputObject, outputObject); + } + + /** + * 新增/编辑目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCatalog", value = "新增/编辑目录", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Catalog.class) + @RequestMapping("/post/CatalogController/writeCatalog") + public void writeCatalog(InputObject inputObject, OutputObject outputObject) { + catalogService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCatalogById", value = "删除目录", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "目录id", required = "required")}) + @RequestMapping("/post/CatalogController/deleteCatalogById") + public void deleteCatalogById(InputObject inputObject, OutputObject outputObject) { + catalogService.deleteById(inputObject, outputObject); + } + + /** + * 根据id批量获取目录信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCatalogByIds", value = "根据id批量获取目录信息", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个用逗号隔开", required = "required")}) + @RequestMapping("/post/CatalogController/queryCatalogByIds") + public void queryCatalogByIds(InputObject inputObject, OutputObject outputObject) { + catalogService.selectByIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/dao/CatalogDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/dao/CatalogDao.java new file mode 100644 index 0000000..54e1fa6 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/dao/CatalogDao.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.dao; + +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CatalogDao + * @Description: 目录管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CatalogDao extends SkyeyeBaseMapper { + + /** + * 根据子id查询所有的父节点信息(包含子节点信息) + * + * @param ids 子id + * @return + */ + List> queryAllParentNodeById(@Param("ids") List ids); + + /** + * 根据父id查询所有的子节点信息(包含父id) + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/Catalog.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/Catalog.java new file mode 100644 index 0000000..9ceba2a --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/Catalog.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Catalog + * @Description: 目录信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"name", "parentId", "objectKey"}) +@RedisCacheField(name = CacheConstants.SKYEYE_CATALOG_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "skyeye_catalog") +@ApiModel("目录信息实体类") +public class Catalog extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "目录名称", required = "required") + private String name; + + @TableField(value = "icon") + @ApiModelProperty(value = "图标") + private String icon; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "所属父节点id", required = "required", defaultValue = "0") + private String parentId; + + /** + * 所有的父节点id,用逗号隔开,有序 + */ + @TableField(exist = false) + private String parentIds; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "目录所属业务对象数据的id") + private String objectId; + + @TableField(value = "object_app_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "目录所属业务对象数据的应用id", required = "required") + private String objectAppId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "目录所属业务对象", required = "required") + private String objectKey; + + /** + * 目录子对象,查询时使用 + */ + @TableField(exist = false) + private List children; + + @TableField(value = "type", fill = FieldFill.INSERT) + @ApiModelProperty(value = "目录类型 1. 公共 2.私有", required = "required,num") + private Integer type; + + /** + * 默认所有节点都是文件夹 + */ + @TableField(exist = false) + private Boolean isParent = true; + + /** + * 对象类型,默认是catalog + */ + @TableField(exist = false) + private String objectType = "catalog"; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/CatalogBusinessQueryDo.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/CatalogBusinessQueryDo.java new file mode 100644 index 0000000..fad7e0b --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/entity/CatalogBusinessQueryDo.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +/** + * @ClassName: CatalogBusinessQueryDo + * @Description: 目录关联的业务数据查询的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("目录关联的业务数据查询的实体类") +public class CatalogBusinessQueryDo extends CommonPageInfo { + + @ApiModelProperty(value = "目录id") + private String catelogId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/CatalogService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/CatalogService.java new file mode 100644 index 0000000..ed9b4b6 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/CatalogService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; + +/** + * @ClassName: CatalogService + * @Description: 目录管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:59 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CatalogService extends SkyeyeBusinessService { + + void queryCatalogForTree(InputObject inputObject, OutputObject outputObject); + + void queryCatalogList(InputObject inputObject, OutputObject outputObject); + + List getCatalogs(String objectId, String objectKey, Boolean addOrUser, String userId); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/impl/CatalogServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/impl/CatalogServiceImpl.java new file mode 100644 index 0000000..b11c174 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/catalog/service/impl/CatalogServiceImpl.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.catalog.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.catalog.classenum.CatalogTypeEnum; +import com.skyeye.catalog.dao.CatalogDao; +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.catalog.service.CatalogService; +import com.skyeye.catalog.service.ICatalogService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.server.service.ServiceBeanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: CatalogServiceImpl + * @Description: 目录管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:59 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CatalogServiceImpl extends SkyeyeBusinessServiceImpl implements CatalogService { + + @Autowired + private CatalogDao catalogDao; + + @Autowired + private ICatalogService iCatalogService; + + @Autowired + private ServiceBeanService serviceBeanService; + + /** + * 一次性获取所有的目录为树结构 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCatalogForTree(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + if (StrUtil.isEmpty(objectKey)) { + return; + } + Boolean addOrUser = Boolean.valueOf(params.get("addOrUser").toString()); + String userId = inputObject.getLogParams().get("id").toString(); + List result = getCatalogs(objectId, objectKey, addOrUser, userId); + // 转为树 + List> treeNodes = TreeUtil.build(result, String.valueOf(CommonNumConstants.NUM_ZERO), new TreeNodeConfig(), + (treeNode, tree) -> { + tree.setId(treeNode.getId()); + tree.setParentId(treeNode.getParentId()); + tree.setName(treeNode.getName()); + tree.putExtra("isParent", true); + tree.putExtra("icon", treeNode.getIcon()); + tree.putExtra("type", treeNode.getType()); + }); + outputObject.setBeans(treeNodes); + outputObject.settotal(treeNodes.size()); + } + + /** + * 一次性获取所有的目录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCatalogList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + Boolean addOrUser = Boolean.valueOf(params.get("addOrUser").toString()); + String userId = inputObject.getLogParams().get("id").toString(); + List result = getCatalogs(objectId, objectKey, addOrUser, userId); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + + @Override + public List getCatalogs(String objectId, String objectKey, Boolean addOrUser, String userId) { + // 查询这个业务对象所有公共的目录 + List publicCatalogList = queryList(StrUtil.EMPTY, objectKey, CatalogTypeEnum.PUBLIC.getKey(), addOrUser, userId); + // 查询这个业务对象私有的目录 + List privateCatalogList = queryList(objectId, objectKey, CatalogTypeEnum.PRIVATELY_OWNED.getKey(), addOrUser, userId); + + List result = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(publicCatalogList)) { + result.addAll(publicCatalogList); + } + if (CollectionUtil.isNotEmpty(privateCatalogList)) { + result.addAll(privateCatalogList); + } + return result; + } + + private List queryList(String objectId, String objectKey, Integer type, Boolean addOrUser, String userId) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getObjectKey), objectKey); + if (type != null) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getType), type); + } + if (StrUtil.isNotEmpty(objectId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getObjectId), objectId); + } + if (addOrUser) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getCreateId), userId); + } + return list(queryWrapper); + } + + @Override + public void deleteById(String id) { + Catalog catalog = selectById(id); + URI serviceBeanUri = serviceBeanService.getServiceBean(catalog.getObjectAppId(), catalog.getObjectKey()); + // 获取当前目录与所有的子目录id + List ids = catalogDao.queryAllChildIdsByParentId(Arrays.asList(id)); + super.deleteById(ids); + // 删除业务数据 + iCatalogService.deleteDataMationByCatalogIds(serviceBeanUri, catalog.getObjectKey(), ids); + } + + @Override + public Catalog getDataFromDb(String id) { + Catalog catalog = super.getDataFromDb(id); + // 设置路径id + List> parentList = catalogDao.queryAllParentNodeById(Arrays.asList(id)); + parentList.stream() + .sorted(Comparator.comparing(bean -> bean.get("level").toString(), Comparator.reverseOrder())); + + if (CollectionUtil.isNotEmpty(parentList)) { + List parentIds = parentList.stream().map(bean -> bean.get("_id").toString()).collect(Collectors.toList()); + catalog.setParentIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(parentIds)); + } + return catalog; + } + + @Override + public List getDataFromDb(List idList) { + List catalogList = super.getDataFromDb(idList); + // 设置路径id + List> parentMationList = catalogDao.queryAllParentNodeById(idList); + Map>> groupByMap = parentMationList.stream() + .sorted(Comparator.comparing(bean -> bean.get("level").toString(), Comparator.reverseOrder())) + .collect(Collectors.groupingBy(bean -> bean.get("childId").toString())); + + catalogList.forEach(catalog -> { + List> parentList = groupByMap.get(catalog.getId()); + if (CollectionUtil.isNotEmpty(parentList)) { + List parentIds = parentList.stream().map(bean -> bean.get("_id").toString()).collect(Collectors.toList()); + catalog.setParentIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(parentIds)); + } + }); + return catalogList; + } + + @Override + protected QueryWrapper queryWrapper(Catalog entity, String id) { + QueryWrapper queryWrapper = super.queryWrapper(entity, id); + if (StrUtil.isNotEmpty(entity.getObjectId())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getObjectId), entity.getObjectId()); + } + if (entity.getType().equals(CatalogTypeEnum.PRIVATELY_OWNED.getKey())) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Catalog::getCreateId), userId); + } + + return queryWrapper; + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/classenum/ContactsAuthEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/classenum/ContactsAuthEnum.java new file mode 100644 index 0000000..f8fda8c --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/classenum/ContactsAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ContactsAuthEnum + * @Description: 联系人权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ContactsAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/controller/ContactsController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/controller/ContactsController.java new file mode 100644 index 0000000..03507db --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/controller/ContactsController.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contacts.entity.Contacts; +import com.skyeye.contacts.service.ContactsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ContactsController + * @Description: 联系人管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/26 14:51 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "联系人管理", tags = "联系人管理", modelName = "基本服务") +public class ContactsController { + + @Autowired + private ContactsService contactsService; + + /** + * 获取联系人列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryContactsList", value = "获取联系人列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ContactsController/queryContactsList") + public void queryContactsList(InputObject inputObject, OutputObject outputObject) { + contactsService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑联系人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeContactsMation", value = "新增/编辑联系人信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Contacts.class) + @RequestMapping("/post/ContactsController/writeContactsMation") + public void writeContactsMation(InputObject inputObject, OutputObject outputObject) { + contactsService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除联系人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteContactsMationById", value = "根据id删除联系人信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ContactsController/deleteContactsMationById") + public void deleteContactsMationById(InputObject inputObject, OutputObject outputObject) { + contactsService.deleteById(inputObject, outputObject); + } + + /** + * 根据id批量获取联系人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryContactsByIds", value = "根据id批量获取联系人信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/ContactsController/queryContactsByIds") + public void queryContactsById(InputObject inputObject, OutputObject outputObject) { + contactsService.selectByIds(inputObject, outputObject); + } + + /** + * 根据业务数据id获取联系人列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryContactsListByObject", value = "根据业务数据id获取联系人列表", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务数据id")}) + @RequestMapping("/post/ContactsController/queryContactsListByObject") + public void queryContactsListByObject(InputObject inputObject, OutputObject outputObject) { + contactsService.queryContactsListByObject(inputObject, outputObject); + } + + /** + * 根据业务数据id批量获取联系人列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryContactsListByObjectIds", value = "根据业务数据id批量获取联系人列表", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "objectIds", name = "objectIds", value = "业务数据id集合", required = "json")}) + @RequestMapping("/post/ContactsController/queryContactsListByObjectIds") + public void queryContactsListByObjectIds(InputObject inputObject, OutputObject outputObject) { + contactsService.queryContactsListByObjectIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/dao/ContactsDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/dao/ContactsDao.java new file mode 100644 index 0000000..20513aa --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/dao/ContactsDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.contacts.entity.Contacts; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ContactsDao + * @Description: 客户联系人管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ContactsDao extends SkyeyeBaseMapper { + + List> queryContactsList(CommonPageInfo pageInfo); + + int setContactsIsNotDefault(@Param("objectId") String objectId, @Param("isDefault") Integer isDefault); + + int setContactsIsDefault(@Param("id") String id, @Param("isDefault") Integer isDefault); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/entity/Contacts.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/entity/Contacts.java new file mode 100644 index 0000000..9da7dcd --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/entity/Contacts.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: Contacts + * @Description: 联系人信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/24 15:58 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"name", "objectId"}) +@RedisCacheField(name = CacheConstants.SKYEYE_CONTACTS_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "skyeye_contacts") +@ApiModel("联系人信息实体类") +public class Contacts extends SkyeyeTeamAuth { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "联系人姓名", required = "required") + private String name; + + @TableField(value = "department") + @ApiModelProperty(value = "联系人所属部门") + private String department; + + @TableField(value = "job") + @ApiModelProperty(value = "联系人职位") + private String job; + + @TableField(value = "work_phone") + @ApiModelProperty(value = "办公电话") + private String workPhone; + + @TableField(value = "mobile_phone") + @ApiModelProperty(value = "移动电话", required = "phone") + private String mobilePhone; + + @TableField(value = "email") + @ApiModelProperty(value = "邮箱", required = "email") + private String email; + + @TableField(value = "qq") + @ApiModelProperty(value = "QQ号") + private String qq; + + @TableField(value = "wechat") + @ApiModelProperty(value = "微信") + private String wechat; + + @TableField(value = "is_default") + @ApiModelProperty(value = "默认联系人 1.是 2.否", required = "required,num") + private Integer isDefault; + + /** + * 删除标记,0未删除,1删除 + */ + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/ContactsService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/ContactsService.java new file mode 100644 index 0000000..d92cc72 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/ContactsService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.contacts.entity.Contacts; + +/** + * @ClassName: ContactsService + * @Description: 联系人管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ContactsService extends SkyeyeTeamAuthService { + + void queryContactsListByObject(InputObject inputObject, OutputObject outputObject); + + void queryContactsListByObjectIds(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/impl/ContactsServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/impl/ContactsServiceImpl.java new file mode 100644 index 0000000..e7cae66 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/contacts/service/impl/ContactsServiceImpl.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.contacts.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.contacts.classenum.ContactsAuthEnum; +import com.skyeye.contacts.dao.ContactsDao; +import com.skyeye.contacts.entity.Contacts; +import com.skyeye.contacts.service.ContactsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ContactsServiceImpl + * @Description: 联系人管理 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "联系人管理", groupName = "基础模块", teamAuth = true) +public class ContactsServiceImpl extends SkyeyeTeamAuthServiceImpl implements ContactsService { + + @Autowired + private ContactsDao contactsDao; + + @Override + public Class getAuthEnumClass() { + return ContactsAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(ContactsAuthEnum.ADD.getKey(), ContactsAuthEnum.EDIT.getKey(), ContactsAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = contactsDao.queryContactsList(pageInfo); + return beans; + } + + @Override + public void writePostpose(Contacts entity, String userId) { + super.writePostpose(entity, userId); + if (entity.getIsDefault().equals(IsDefaultEnum.IS_DEFAULT.getKey())) { + // 如果设置为默认联系人,则修改之前的联系人为非默认 + contactsDao.setContactsIsNotDefault(entity.getObjectId(), IsDefaultEnum.NOT_DEFAULT.getKey()); + contactsDao.setContactsIsDefault(entity.getId(), IsDefaultEnum.IS_DEFAULT.getKey()); + } + } + + /** + * 根据业务数据id获取联系人列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryContactsListByObject(InputObject inputObject, OutputObject outputObject) { + String objectId = inputObject.getParams().get("objectId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Contacts::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Contacts::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List contactsList = list(queryWrapper); + outputObject.setBeans(contactsList); + outputObject.settotal(contactsList.size()); + } + + @Override + public void queryContactsListByObjectIds(InputObject inputObject, OutputObject outputObject) { + String objectIdsStr = inputObject.getParams().get("objectIds").toString(); + List objectIds = JSONUtil.toList(objectIdsStr, null); + if (CollectionUtil.isEmpty(objectIds)) { + return; + } + objectIds = objectIds.stream().distinct().collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Contacts::getObjectId), objectIds); + queryWrapper.eq(MybatisPlusUtil.toColumns(Contacts::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List contactsList = list(queryWrapper); + Map> result = contactsList.stream().collect(Collectors.groupingBy(Contacts::getObjectId)); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/classenum/DisCussionAuthEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/classenum/DisCussionAuthEnum.java new file mode 100644 index 0000000..f6bef10 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/classenum/DisCussionAuthEnum.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DisCussionAuthEnum + * @Description: 讨论帖权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DisCussionAuthEnum implements SkyeyeEnumClass { + ADD("add", "新增", true, false), + EDIT("edit", "编辑", true, false), + DELETE("delete", "删除", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionController.java new file mode 100644 index 0000000..de269b2 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.discussion.entity.Discussion; +import com.skyeye.discussion.service.DiscussionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DiscussionController + * @Description: 讨论帖管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "讨论帖管理", tags = "讨论帖管理", modelName = "基本服务") +public class DiscussionController { + + @Autowired + private DiscussionService discussionService; + + /** + * 获取讨论帖列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDiscussionList", value = "获取讨论帖列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DiscussionController/queryDiscussionList") + public void queryDiscussionList(InputObject inputObject, OutputObject outputObject) { + discussionService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑讨论帖信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDiscussion", value = "新增/编辑讨论帖信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Discussion.class) + @RequestMapping("/post/DiscussionController/writeDiscussion") + public void writeDiscussion(InputObject inputObject, OutputObject outputObject) { + discussionService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取讨论帖信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDiscussionById", value = "根据id获取讨论帖信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DiscussionController/queryDiscussionById") + public void queryDiscussionById(InputObject inputObject, OutputObject outputObject) { + discussionService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除讨论帖信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDiscussionById", value = "根据id删除讨论帖信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DiscussionController/deleteDiscussionById") + public void deleteDiscussionById(InputObject inputObject, OutputObject outputObject) { + discussionService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionReplyController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionReplyController.java new file mode 100644 index 0000000..77e470b --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/controller/DiscussionReplyController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.discussion.entity.DiscussionReply; +import com.skyeye.discussion.entity.DiscussionReplyQueryDo; +import com.skyeye.discussion.service.DiscussionReplyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DiscussionReplyController + * @Description: 讨论帖回帖管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "讨论帖回帖管理", tags = "讨论帖回帖管理", modelName = "基本服务") +public class DiscussionReplyController { + + @Autowired + private DiscussionReplyService discussionReplyService; + + /** + * 获取讨论帖回帖列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDiscussionReplyList", value = "获取讨论帖回帖列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DiscussionReplyQueryDo.class) + @RequestMapping("/post/DiscussionReplyController/queryDiscussionReplyList") + public void queryDiscussionReplyList(InputObject inputObject, OutputObject outputObject) { + discussionReplyService.queryPageList(inputObject, outputObject); + } + + /** + * 新增讨论帖回帖信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createDiscussionReply", value = "新增讨论帖回帖信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DiscussionReply.class) + @RequestMapping("/post/DiscussionReplyController/createDiscussionReply") + public void createDiscussionReply(InputObject inputObject, OutputObject outputObject) { + discussionReplyService.createEntity(inputObject, outputObject); + } + + /** + * 根据id删除讨论帖回帖信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDiscussionReplyById", value = "根据id删除讨论帖回帖信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DiscussionReplyController/deleteDiscussionReplyById") + public void deleteDiscussionReplyById(InputObject inputObject, OutputObject outputObject) { + discussionReplyService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionDao.java new file mode 100644 index 0000000..71c86af --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.discussion.entity.Discussion; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +public interface DiscussionDao extends SkyeyeBaseMapper { + + List> queryDiscussionList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionReplyDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionReplyDao.java new file mode 100644 index 0000000..fff8be9 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/dao/DiscussionReplyDao.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.discussion.entity.DiscussionReply; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DiscussionReplyDao + * @Description: 讨论帖回帖数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DiscussionReplyDao extends SkyeyeBaseMapper { + + List> queryDiscussionReplyList(CommonPageInfo pageInfo); + + /** + * 根据父id查询所有的子节点信息(包含父id) + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + + List> queryDiscussionReplyListByIds(@Param("ids") List ids); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/Discussion.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/Discussion.java new file mode 100644 index 0000000..6d56c2e --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/Discussion.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import lombok.Data; + +/** + * @ClassName: Discussion + * @Description: 讨论帖实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.SKYEYE_DISCUSSION_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "skyeye_discussion") +@ApiModel("讨论帖实体类") +public class Discussion extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField(value = "content") + @ApiModelProperty(value = "内容", required = "required") + private String content; + + @TableField(value = "link_id") + @ApiModelProperty(value = "关联的业务数据id,例如:商机id等") + private String linkId; + + @TableField(value = "link_key") + @ApiModelProperty(value = "关联的业务数据key,例如:商机的serviceClassName等") + private String linkKey; + + @TableField(exist = false) + @ApiModelProperty(value = "附件") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReply.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReply.java new file mode 100644 index 0000000..66bacae --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReply.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: DiscussionReply + * @Description: 讨论帖回帖实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_discussion_reply") +@ApiModel("讨论帖回帖实体类") +public class DiscussionReply extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "content") + @ApiModelProperty(value = "内容", required = "required") + private String content; + + @TableField(value = "discussion_id") + @ApiModelProperty(value = "讨论帖id", required = "required") + private String discussionId; + + @TableField(value = "reply_id") + @ApiModelProperty(value = "回复id,如果是首次评论帖,那就是0", required = "required") + private String replyId; + + @TableField(exist = false) + @ApiModelProperty(value = "附件") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReplyQueryDo.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReplyQueryDo.java new file mode 100644 index 0000000..1e5a5b0 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/entity/DiscussionReplyQueryDo.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +/** + * @ClassName: DiscussionReplyQueryDo + * @Description: 论坛贴回帖查询实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/5 23:36 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("论坛贴回帖查询实体类") +public class DiscussionReplyQueryDo extends CommonPageInfo { + + @ApiModelProperty(value = "论坛贴id", required = "required") + private String discussionId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionReplyService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionReplyService.java new file mode 100644 index 0000000..5b71f4c --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionReplyService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.discussion.entity.DiscussionReply; + +/** + * @ClassName: DiscussionReplyService + * @Description: 讨论帖回帖服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DiscussionReplyService extends SkyeyeBusinessService { + + void deleteByDiscussionId(String discussionId); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionService.java new file mode 100644 index 0000000..79485d0 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/DiscussionService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.discussion.entity.Discussion; + +/** + * @ClassName: DiscussionService + * @Description: 讨论帖管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DiscussionService extends SkyeyeTeamAuthService { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionReplyServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionReplyServiceImpl.java new file mode 100644 index 0000000..c0b9028 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionReplyServiceImpl.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.discussion.dao.DiscussionReplyDao; +import com.skyeye.discussion.entity.DiscussionReply; +import com.skyeye.discussion.entity.DiscussionReplyQueryDo; +import com.skyeye.discussion.service.DiscussionReplyService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DiscussionReplyServiceImpl + * @Description: 讨论帖回帖服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 22:07 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DiscussionReplyServiceImpl extends SkyeyeBusinessServiceImpl implements DiscussionReplyService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + DiscussionReplyQueryDo pageInfo = inputObject.getParams(DiscussionReplyQueryDo.class); + List> beans = skyeyeBaseMapper.queryDiscussionReplyList(pageInfo); + List ids = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new ArrayList<>(); + } + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(ids); + beans = skyeyeBaseMapper.queryDiscussionReplyListByIds(childIds); + iAuthUserService.setMationForMap(beans, "createId", "createMation"); + return beans; + } + + @Override + public Boolean builderTree(List> beans, OutputObject outputObject) { + List> treeNodes = TreeUtil.build(beans, String.valueOf(CommonNumConstants.NUM_ZERO), new TreeNodeConfig(), + (treeNode, tree) -> { + tree.setId(treeNode.get("id").toString()); + tree.setParentId(treeNode.get("replyId").toString()); + tree.setName(treeNode.get("content").toString()); + tree.putExtra("createName", treeNode.get("createName").toString()); + tree.putExtra("createTime", treeNode.get("createTime").toString()); + tree.putExtra("createMation", treeNode.get("createMation")); + }); + beans.clear(); + beans.addAll(JSONUtil.toList(JSONUtil.toJsonStr(treeNodes), null)); + return false; + } + + @Override + public void deleteById(String id) { + // 获取当前回帖和所有的子回帖信息 + List ids = skyeyeBaseMapper.queryAllChildIdsByParentId(Arrays.asList(id)); + super.deleteById(ids); + } + + @Override + public void deleteByDiscussionId(String discussionId) { + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq(MybatisPlusUtil.toColumns(DiscussionReply::getDiscussionId), discussionId); + remove(deleteWrapper); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionServiceImpl.java new file mode 100644 index 0000000..f23dda2 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/discussion/service/impl/DiscussionServiceImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.discussion.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.discussion.classenum.DisCussionAuthEnum; +import com.skyeye.discussion.dao.DiscussionDao; +import com.skyeye.discussion.entity.Discussion; +import com.skyeye.discussion.service.DiscussionReplyService; +import com.skyeye.discussion.service.DiscussionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DiscussionServiceImpl + * @Description: 讨论帖管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "讨论帖管理", groupName = "基本服务", teamAuth = true) +public class DiscussionServiceImpl extends SkyeyeTeamAuthServiceImpl implements DiscussionService { + + @Autowired + private DiscussionReplyService discussionReplyService; + + @Override + public Class getAuthEnumClass() { + return DisCussionAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(DisCussionAuthEnum.ADD.getKey(), DisCussionAuthEnum.EDIT.getKey(), DisCussionAuthEnum.DELETE.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryDiscussionList(pageInfo); + return beans; + } + + @Override + public Discussion selectById(String id) { + Discussion discussion = super.selectById(id); + iAuthUserService.setName(discussion, "createId", "createName"); + return discussion; + } + + @Override + public void deletePostpose(String id) { + discussionReplyService.deleteByDiscussionId(id); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/classenum/DocumentAuthEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/classenum/DocumentAuthEnum.java new file mode 100644 index 0000000..a5c1399 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/classenum/DocumentAuthEnum.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.classenum; + +import com.skyeye.catalog.classenum.CatalogAuthEnum; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: DocumentAuthEnum + * @Description: 文档权限控制枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DocumentAuthEnum implements SkyeyeEnumClass { + ADD_DOCUMENT("addDocument", "上传文档", true, false), + EDIT_DOCUMENT("editDocument", "编辑文档", true, false), + DELETE_DOCUMENT("deleteDocument", "删除文档", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static List dependOnEnum() { + return Arrays.asList(CatalogAuthEnum.class); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/controller/DocumentController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/controller/DocumentController.java new file mode 100644 index 0000000..0b692ce --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/controller/DocumentController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.document.entity.Document; +import com.skyeye.document.service.DocumentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DocumentController + * @Description: 文档管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "文档管理", tags = "文档管理", modelName = "基本服务") +public class DocumentController { + + @Autowired + private DocumentService documentService; + + /** + * 获取文档列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDocumentList", value = "获取文档列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DocumentController/queryDocumentList") + public void queryDocumentList(InputObject inputObject, OutputObject outputObject) { + documentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑文档信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDocumentMation", value = "新增/编辑文档信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Document.class) + @RequestMapping("/post/DocumentController/writeDocumentMation") + public void writeDocumentMation(InputObject inputObject, OutputObject outputObject) { + documentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除文档信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDocumentMationById", value = "根据id删除文档信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DocumentController/deleteDocumentMationById") + public void deleteDocumentMationById(InputObject inputObject, OutputObject outputObject) { + documentService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/dao/DocumentDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/dao/DocumentDao.java new file mode 100644 index 0000000..fb70942 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/dao/DocumentDao.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.contacts.entity.Contacts; +import com.skyeye.document.entity.Document; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DocumentDao + * @Description: 文档管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface DocumentDao extends SkyeyeBaseMapper { + + List> queryDocumentList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/entity/Document.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/entity/Document.java new file mode 100644 index 0000000..c06ca64 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/entity/Document.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeTeamAuth; +import com.skyeye.eve.entity.dict.SysDictData; +import lombok.Data; + +/** + * @ClassName: Document + * @Description: 文档管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = CacheConstants.SKYEYE_DOCUMENT_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "skyeye_document") +@ApiModel("文档信息实体类") +public class Document extends SkyeyeTeamAuth implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "文档名称", required = "required") + private String name; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类,数据来源:数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "所属分类信息") + private SysDictData typeMation; + + @TableField(value = "content") + @ApiModelProperty(value = "内容", required = "required") + private String content; + + @TableField(value = "catalog_id") + @ApiModelProperty(value = "所属目录", required = "required") + private String catalogId; + + @TableField(exist = false) + @Property(value = "所属目录信息") + private Catalog catalogMation; + + @TableField(exist = false) + @ApiModelProperty(value = "附件") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/DocumentService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/DocumentService.java new file mode 100644 index 0000000..99ed3db --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/DocumentService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.service; + +import com.skyeye.base.business.service.SkyeyeTeamAuthService; +import com.skyeye.document.entity.Document; + +/** + * @ClassName: DocumentService + * @Description: 文档管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface DocumentService extends SkyeyeTeamAuthService { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/impl/DocumentServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/impl/DocumentServiceImpl.java new file mode 100644 index 0000000..bcd093f --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/document/service/impl/DocumentServiceImpl.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.document.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeTeamAuthServiceImpl; +import com.skyeye.catalog.service.CatalogService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.document.classenum.DocumentAuthEnum; +import com.skyeye.document.dao.DocumentDao; +import com.skyeye.document.entity.Document; +import com.skyeye.document.service.DocumentService; +import com.skyeye.eve.service.SysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DocumentServiceImpl + * @Description: 文档管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/7/24 8:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "文档管理", groupName = "基础模块", teamAuth = true) +public class DocumentServiceImpl extends SkyeyeTeamAuthServiceImpl implements DocumentService { + + @Autowired + private SysDictDataService sysDictDataService; + + @Autowired + private CatalogService catalogService; + + @Override + public Class getAuthEnumClass() { + return DocumentAuthEnum.class; + } + + @Override + public List getAuthPermissionKeyList() { + return Arrays.asList(DocumentAuthEnum.ADD_DOCUMENT.getKey(), DocumentAuthEnum.EDIT_DOCUMENT.getKey(), DocumentAuthEnum.DELETE_DOCUMENT.getKey()); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryDocumentList(pageInfo); + sysDictDataService.setMationForMap(beans, "typeId", "typeMation"); + catalogService.setMationForMap(beans, "catalogId", "catalogMation"); + return beans; + } + + @Override + public Document selectById(String id) { + Document document = super.selectById(id); + sysDictDataService.setDataMation(document, Document::getTypeId); + catalogService.setDataMation(document, Document::getCatalogId); + return document; + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/EnclosureLinkController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/EnclosureLinkController.java new file mode 100644 index 0000000..1b3b57d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/EnclosureLinkController.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.enclosure.entity.EnclosureLinkApi; +import com.skyeye.enclosure.service.EnclosureLinkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: EnclosureLinkController + * @Description: 附件信息与业务对象关系的控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "附件与业务对象关系管理", tags = "附件与业务对象关系管理", modelName = "基本服务") +public class EnclosureLinkController { + + @Autowired + private EnclosureLinkService enclosureLinkService; + + /** + * 新增/编辑附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeEnclosureLink", value = "新增/编辑附件与业务对象关系", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = EnclosureLinkApi.class) + @RequestMapping("/post/EnclosureLinkController/writeEnclosureLink") + public void writeEnclosureLink(InputObject inputObject, OutputObject outputObject) { + enclosureLinkService.writeEnclosureLink(inputObject, outputObject); + } + + /** + * 根据业务对象数据获取附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnclosureLinkList", value = "根据业务对象数据获取附件与业务对象关系", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象数据的id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "业务对象服务的className", required = "required")}) + @RequestMapping("/post/EnclosureLinkController/queryEnclosureLinkList") + public void queryEnclosureLinkList(InputObject inputObject, OutputObject outputObject) { + enclosureLinkService.queryEnclosureLinkList(inputObject, outputObject); + } + + /** + * 根据业务对象数据删除附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteEnclosureLink", value = "根据业务对象数据删除附件与业务对象关系", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象数据的id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "业务对象服务的className", required = "required")}) + @RequestMapping("/post/EnclosureLinkController/deleteEnclosureLink") + public void deleteEnclosureLink(InputObject inputObject, OutputObject outputObject) { + enclosureLinkService.deleteEnclosureLink(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/SysEnclosureController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/SysEnclosureController.java new file mode 100644 index 0000000..4ad30c0 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/controller/SysEnclosureController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.catalog.entity.CatalogBusinessQueryDo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.enclosure.entity.Enclosure; +import com.skyeye.enclosure.service.SysEnclosureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEnclosureController + * @Description: 附件管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "附件管理", tags = "附件管理", modelName = "基本服务") +public class SysEnclosureController { + + @Autowired + private SysEnclosureService sysEnclosureService; + + /** + * 获取指定文件夹下的文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysenclosure004", value = "获取指定文件夹下的文件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CatalogBusinessQueryDo.class) + @RequestMapping("/post/SysEnclosureController/queryEnclosureList") + public void queryEnclosureList(InputObject inputObject, OutputObject outputObject) { + sysEnclosureService.queryPageList(inputObject, outputObject); + } + + /** + * 新增附件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createEnclosure", value = "新增附件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Enclosure.class) + @RequestMapping("/post/SysEnclosureController/createEnclosure") + public void createEnclosure(InputObject inputObject, OutputObject outputObject) { + sysEnclosureService.createEntity(inputObject, outputObject); + } + + /** + * 根据ids(逗号隔开)获取多个附件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnclosureInfoByIds", value = "根据ids(逗号隔开)获取多个附件信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "enclosureInfoIds", name = "enclosureInfoIds", value = "附件id(多个用逗号隔开)")}) + @RequestMapping("/post/SysEnclosureController/queryEnclosureInfo") + public void queryEnclosureInfo(InputObject inputObject, OutputObject outputObject) { + sysEnclosureService.queryEnclosureInfo(inputObject, outputObject); + } + + /** + * 获取我的附件树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnclosureTree", value = "获取我的附件树", method = "GET", allUse = "2") + @RequestMapping("/post/SysEnclosureController/queryEnclosureTree") + public void queryEnclosureTree(InputObject inputObject, OutputObject outputObject) { + sysEnclosureService.queryEnclosureTree(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/EnclosureLinkDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/EnclosureLinkDao.java new file mode 100644 index 0000000..eeac5c0 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/EnclosureLinkDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.dao; + +import com.skyeye.enclosure.entity.EnclosureLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: EnclosureLinkDao + * @Description: 附件信息与业务对象关系的数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EnclosureLinkDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/SysEnclosureDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/SysEnclosureDao.java new file mode 100644 index 0000000..8d73778 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/dao/SysEnclosureDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.dao; + +import com.skyeye.catalog.entity.CatalogBusinessQueryDo; +import com.skyeye.enclosure.entity.Enclosure; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface SysEnclosureDao extends SkyeyeBaseMapper { + + List> queryEnclosureList(CatalogBusinessQueryDo commonPageInfo); + + List> queryEnclosureInfo(@Param("enclosure") String enclosure); + + List> queryEnclosureTree(@Param("userId") String userId); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/Enclosure.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/Enclosure.java new file mode 100644 index 0000000..2afa938 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/Enclosure.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Enclosure + * @Description: 附件信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.SKYEYE_ENCLOSURE_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_enclosure") +@ApiModel("附件信息实体类") +public class Enclosure extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "附件原始名称", required = "required") + private String name; + + @TableField(value = "path") + @ApiModelProperty(value = "文件地址", required = "required") + private String path; + + @TableField(value = "type") + @ApiModelProperty(value = "文件类型", required = "required") + private String type; + + @TableField(value = "size") + @ApiModelProperty(value = "文件大小", required = "required") + private String size; + + @TableField(value = "size_type") + @ApiModelProperty(value = "文件大小单位 bytes", required = "required") + private String sizeType; + + @TableField(value = "catalog") + @ApiModelProperty(value = "文件所属目录", required = "required") + private String catalog; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLink.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLink.java new file mode 100644 index 0000000..db1fa63 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLink.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: EnclosureLink + * @Description: 附件信息与业务对象关联的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "objectKey", "objectField", "enclosureId"}) +@TableName(value = "sys_enclosure_link") +@ApiModel("附件信息与业务对象关联的实体类") +public class EnclosureLink extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + /** + * 业务对象数据的id + */ + @TableField(value = "object_id") + private String objectId; + + /** + * 业务对象服务的className + */ + @TableField(value = "object_key") + private String objectKey; + + /** + * 业务对象的字段列 + */ + @TableField(value = "object_field") + private String objectField; + + /** + * 附件id + */ + @TableField(value = "enclosure_id") + private String enclosureId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLinkApi.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLinkApi.java new file mode 100644 index 0000000..4c2a182 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/entity/EnclosureLinkApi.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EnclosureLinkApi + * @Description: 附件信息与业务对象关联的实体类BOX + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("附件信息与业务对象关联的实体类BOX") +public class EnclosureLinkApi implements Serializable { + + @ApiModelProperty(value = "业务对象数据的id", required = "required") + private String objectId; + + @ApiModelProperty(value = "业务对象服务的className", required = "required") + private String objectKey; + + /** + * 格式:{“enclosure”: ["111", "222"]} + */ + @ApiModelProperty(value = "业务对象的字段列与附件id集合的关系", required = "required,json") + private Map> enclosureIds; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/EnclosureLinkService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/EnclosureLinkService.java new file mode 100644 index 0000000..fe7bd90 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/EnclosureLinkService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.enclosure.entity.EnclosureLink; + +/** + * @ClassName: EnclosureLinkService + * @Description: 附件信息与业务对象关系的服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface EnclosureLinkService extends SkyeyeBusinessService { + + void writeEnclosureLink(InputObject inputObject, OutputObject outputObject); + + void queryEnclosureLinkList(InputObject inputObject, OutputObject outputObject); + + void deleteEnclosureLink(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/SysEnclosureService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/SysEnclosureService.java new file mode 100644 index 0000000..b0fa441 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/SysEnclosureService.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.enclosure.entity.Enclosure; + +public interface SysEnclosureService extends SkyeyeBusinessService { + + void queryEnclosureInfo(InputObject inputObject, OutputObject outputObject); + + void queryEnclosureTree(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/EnclosureLinkServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/EnclosureLinkServiceImpl.java new file mode 100644 index 0000000..f8d0eee --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/EnclosureLinkServiceImpl.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.enclosure.dao.EnclosureLinkDao; +import com.skyeye.enclosure.entity.EnclosureLink; +import com.skyeye.enclosure.entity.EnclosureLinkApi; +import com.skyeye.enclosure.service.EnclosureLinkService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: EnclosureLinkServiceImpl + * @Description: 附件信息与业务对象关系的服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class EnclosureLinkServiceImpl extends SkyeyeBusinessServiceImpl implements EnclosureLinkService { + + /** + * 新增/编辑附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void writeEnclosureLink(InputObject inputObject, OutputObject outputObject) { + EnclosureLinkApi enclosureLinkApi = inputObject.getParams(EnclosureLinkApi.class); + String objectId = enclosureLinkApi.getObjectId(); + String objectKey = enclosureLinkApi.getObjectKey(); + List objectFieldList = new ArrayList<>(enclosureLinkApi.getEnclosureIds().keySet()); + if (CollectionUtil.isEmpty(objectFieldList)) { + return; + } + // 删除之前已经保存的 + remove(objectId, objectKey, objectFieldList); + // 解析入参中最新的数据 + List enclosureLinkList = new ArrayList<>(); + enclosureLinkApi.getEnclosureIds().forEach((objectField, enclosureIds) -> { + enclosureIds.forEach(enclosureId -> { + if (StrUtil.isEmpty(enclosureId)) { + return; + } + EnclosureLink enclosureLink = new EnclosureLink(); + enclosureLink.setObjectField(objectField); + enclosureLink.setObjectId(objectId); + enclosureLink.setObjectKey(objectKey); + enclosureLink.setEnclosureId(enclosureId); + enclosureLinkList.add(enclosureLink); + }); + }); + String userId = inputObject.getLogParams().get("id").toString(); + // 保存 + super.createEntity(enclosureLinkList, userId); + } + + private void remove(String objectId, String objectKey, List objectFieldList) { + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq(MybatisPlusUtil.toColumns(EnclosureLink::getObjectId), objectId); + deleteWrapper.eq(MybatisPlusUtil.toColumns(EnclosureLink::getObjectKey), objectKey); + if (CollectionUtil.isNotEmpty(objectFieldList)) { + deleteWrapper.in(MybatisPlusUtil.toColumns(EnclosureLink::getObjectField), objectFieldList); + } + remove(deleteWrapper); + } + + /** + * 根据业务对象数据获取附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnclosureLinkList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(EnclosureLink::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(EnclosureLink::getObjectKey), objectKey); + List enclosureLinkList = list(queryWrapper); + outputObject.setBeans(enclosureLinkList); + outputObject.settotal(enclosureLinkList.size()); + } + + /** + * 根据业务对象数据删除附件与业务对象关系 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteEnclosureLink(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + remove(objectId, objectKey, null); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/SysEnclosureServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/SysEnclosureServiceImpl.java new file mode 100644 index 0000000..f66393e --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/enclosure/service/impl/SysEnclosureServiceImpl.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.enclosure.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.catalog.entity.Catalog; +import com.skyeye.catalog.entity.CatalogBusinessQueryDo; +import com.skyeye.catalog.service.CatalogService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.BytesUtil; +import com.skyeye.enclosure.dao.SysEnclosureDao; +import com.skyeye.enclosure.entity.Enclosure; +import com.skyeye.enclosure.service.SysEnclosureService; +import com.skyeye.sdk.catalog.service.CatalogSdkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class SysEnclosureServiceImpl extends SkyeyeBusinessServiceImpl implements SysEnclosureService, CatalogSdkService { + + @Autowired + private SysEnclosureDao sysEnclosureDao; + + @Autowired + private CatalogService catalogService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CatalogBusinessQueryDo pageInfo = inputObject.getParams(CatalogBusinessQueryDo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + List> beans = sysEnclosureDao.queryEnclosureList(pageInfo); + beans.forEach(bean -> { + String size = BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("size").toString())); + bean.put("size", size); + }); + return beans; + } + + /** + * 根据ids(逗号隔开)获取多个附件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnclosureInfo(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = sysEnclosureDao.queryEnclosureInfo(map.get("enclosureInfoIds").toString()); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取我的附件树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnclosureTree(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + List> enclosureList = sysEnclosureDao.queryEnclosureTree(userId); + // 获取目录 + List catalogs = catalogService.getCatalogs(StrUtil.EMPTY, getServiceClassName(), true, userId); + for (Catalog catalog : catalogs) { + enclosureList.add(BeanUtil.beanToMap(catalog)); + } + + enclosureList = enclosureList.stream() + .sorted(Comparator.comparing(bean -> bean.get("objectType").toString(), Comparator.naturalOrder())).collect(Collectors.toList()); + // 转为树 + List> treeNodes = TreeUtil.build(enclosureList, String.valueOf(CommonNumConstants.NUM_ZERO), new TreeNodeConfig(), + (treeNode, tree) -> { + tree.setId(treeNode.get("id").toString()); + tree.setParentId(treeNode.get("parentId").toString()); + tree.setName(treeNode.get("name").toString()); + String objectType = treeNode.get("objectType").toString(); + if (StrUtil.equals(objectType, "catalog")) { + tree.putExtra("isParent", true); + } + tree.putExtra("objectType", objectType); + }); + if (CollectionUtil.isNotEmpty(treeNodes)) { + outputObject.setBeans(treeNodes); + outputObject.settotal(treeNodes.size()); + } + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/controller/LifecycleStateController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/controller/LifecycleStateController.java new file mode 100644 index 0000000..d08561e --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/controller/LifecycleStateController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.lifecycle.entity.LifecycleState; +import com.skyeye.lifecycle.service.LifecycleStateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: LifecycleStateController + * @Description: 生命周期状态管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "生命周期状态管理", tags = "生命周期状态管理", modelName = "生命周期") +public class LifecycleStateController { + + @Autowired + private LifecycleStateService lifecycleStateService; + + /** + * 获取状态列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLifecycleStateList", value = "获取状态列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/LifecycleStateController/queryLifecycleStateList") + public void queryLifecycleStateList(InputObject inputObject, OutputObject outputObject) { + lifecycleStateService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑状态信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeLifecycleState", value = "新增/编辑状态信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = LifecycleState.class) + @RequestMapping("/post/LifecycleStateController/writeLifecycleState") + public void writeLifecycleStateMation(InputObject inputObject, OutputObject outputObject) { + lifecycleStateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取状态信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryLifecycleStateById", value = "根据id获取状态信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LifecycleStateController/queryLifecycleStateById") + public void queryLifecycleStateById(InputObject inputObject, OutputObject outputObject) { + lifecycleStateService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除状态信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteLifecycleStateById", value = "根据id删除状态信息", method = "DELETE", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/LifecycleStateController/deleteLifecycleStateById") + public void deleteLifecycleStateById(InputObject inputObject, OutputObject outputObject) { + lifecycleStateService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启用的状态列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllLifecycleStateList", value = "获取所有的状态列表", method = "GET", allUse = "2") + @RequestMapping("/post/LifecycleStateController/queryAllLifecycleStateList") + public void queryAllLifecycleStateList(InputObject inputObject, OutputObject outputObject) { + lifecycleStateService.queryAllLifecycleStateList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/dao/LifecycleStateDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/dao/LifecycleStateDao.java new file mode 100644 index 0000000..8ceebfc --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/dao/LifecycleStateDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.lifecycle.entity.LifecycleState; + +/** + * @ClassName: LifecycleStateDao + * @Description: 生命周期状态管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LifecycleStateDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleState.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleState.java new file mode 100644 index 0000000..f370f16 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleState.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: LifecycleState + * @Description: 生命周期状态实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"numCode"}) +@RedisCacheField(name = CacheConstants.LIFECYCLE_STATE_CACHE_KEY, cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "lifecycle_state") +@ApiModel("生命周期状态实体类") +public class LifecycleState extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("num_code") + @ApiModelProperty(value = "编码", required = "required") + private String numCode; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum枚举类", required = "required,num") + private Integer enabled; + + /** + * 是否删除,参考#DeleteFlagEnum枚举类 + */ + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplate.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplate.java new file mode 100644 index 0000000..587037d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplate.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: LifecycleTemplate + * @Description: 生命周期状态实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.LIFECYCLE_TEMPLATE_CACHE_KEY, cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "lifecycle_template") +@ApiModel("生命周期模板实体类") +public class LifecycleTemplate extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("num_code") + @ApiModelProperty(value = "编码", required = "required") + private String numCode; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum枚举类", required = "required,num") + private Integer enabled; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className,适用对象", required = "required") + private String className; + + /** + * 是否删除,参考#DeleteFlagEnum枚举类 + */ + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateProcess.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateProcess.java new file mode 100644 index 0000000..ae282a0 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateProcess.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: LifecycleTemplateProcess + * @Description: 生命周期模板与流程的关系的实体类,表示通过该流程可以将状态A变成状态B + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"lifecycleStateAId", "lifecycleStateBId", "lifecycleTemplateId"}) +@TableName(value = "lifecycle_template_process") +@ApiModel("生命周期模板与流程的关系的实体类") +public class LifecycleTemplateProcess extends OperatorUserInfo { + + @TableId("id") + private String id; + + @TableId("lifecycle_state_a_id") + @ApiModelProperty(value = "状态id", required = "required") + private String lifecycleStateAId; + + @TableId("lifecycle_state_b_id") + @ApiModelProperty(value = "状态id", required = "required") + private String lifecycleStateBId; + + /** + * 生命周期模板id + */ + @TableId("lifecycle_template_id") + private String lifecycleTemplateId; + + @TableId("act_flow_id") + @ApiModelProperty(value = "流程配置id", required = "required") + private String actFlowId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateStateLink.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateStateLink.java new file mode 100644 index 0000000..1ec94a3 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/LifecycleTemplateStateLink.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: LifecycleTemplateStateLink + * @Description: 生命周期模板与状态的关系的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "lifecycle_template_state_link") +@ApiModel("生命周期模板与状态的关系的实体类") +public class LifecycleTemplateStateLink extends OperatorUserInfo { + + @TableId("id") + private String id; + + @TableId("lifecycle_state_id") + @ApiModelProperty(value = "状态id") + private String lifecycleStateId; + + @TableId("lifecycle_template_id") + @ApiModelProperty(value = "生命周期模板id") + private String lifecycleTemplateId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/TransitionConditions.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/TransitionConditions.java new file mode 100644 index 0000000..cf05afb --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/entity/TransitionConditions.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: TransitionConditions + * @Description: 生命周期转变条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "lifecycle_transition_conditions") +@ApiModel("生命周期转变条件实体类") +public class TransitionConditions extends OperatorUserInfo { + + @TableId("id") + private String id; + + @TableId("operation_id") + @ApiModelProperty(value = "操作id", required = "required") + private String operationId; + + @TableId("lifecycle_state_a_id") + @ApiModelProperty(value = "状态id", required = "required") + private String lifecycleStateAId; + + @TableId("lifecycle_state_b_id") + @ApiModelProperty(value = "状态id", required = "required") + private String lifecycleStateBId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/LifecycleStateService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/LifecycleStateService.java new file mode 100644 index 0000000..b1a7c37 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/LifecycleStateService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.lifecycle.entity.LifecycleState; + +/** + * @ClassName: LifecycleStateService + * @Description: 生命周期状态管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface LifecycleStateService extends SkyeyeBusinessService { + + void queryAllLifecycleStateList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/impl/LifecycleStateServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/impl/LifecycleStateServiceImpl.java new file mode 100644 index 0000000..928c4d2 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/lifecycle/service/impl/LifecycleStateServiceImpl.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.lifecycle.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.lifecycle.dao.LifecycleStateDao; +import com.skyeye.lifecycle.entity.LifecycleState; +import com.skyeye.lifecycle.service.LifecycleStateService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: LifecycleStateServiceImpl + * @Description: 生命周期状态管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class LifecycleStateServiceImpl extends SkyeyeBusinessServiceImpl implements LifecycleStateService { + + + /** + * 获取所有启用的状态列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllLifecycleStateList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(LifecycleState::getEnabled), EnableEnum.ENABLE_USING.getKey()); + wrapper.eq(MybatisPlusUtil.toColumns(LifecycleState::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + List lifecycleStateList = list(wrapper); + outputObject.setBeans(lifecycleStateList); + outputObject.settotal(lifecycleStateList.size()); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/ObjectPermissionFromType.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/ObjectPermissionFromType.java new file mode 100644 index 0000000..52ff7da --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/ObjectPermissionFromType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ObjectPermissionFromType + * @Description: 业务对象权限表的权限来源 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/16 17:48 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ObjectPermissionFromType implements SkyeyeEnumClass { + + TEAM_LINK(1, "团队统一赋权", true, true), + PERSONAL_LINK(2, "私人赋权(例如:用户A赋权给用户B)", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/TeamObjectTypeEnum.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/TeamObjectTypeEnum.java new file mode 100644 index 0000000..4da2441 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/classenum/TeamObjectTypeEnum.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: TeamObjectTypeEnum + * @Description: 团队适用对象枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 12:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TeamObjectTypeEnum implements SkyeyeEnumClass { + + CUSTOMER(1, "客户团队", Arrays.asList("crmContractAuthEnum", "contactsAuthEnum", "crmOpportunityAuthEnum", "crmDocumentaryAuthEnum", "documentAuthEnum", + "disCussionAuthEnum", "crmFollowUpAuthEnum", "crmPaymentCollectionAuthEnum", "crmInvoiceHeaderAuthEnum", "crmInvoiceAuthEnum"), true, true), + SUPPLIER(2, "供应商团队", Arrays.asList("supplierContractAuthEnum", "contactsAuthEnum", "documentAuthEnum"), true, false), + PROJECT(3, "项目团队", Arrays.asList("milestoneAuthEnum", "taskAuthEnum", "documentAuthEnum", "disCussionAuthEnum"), true, false), + PRO_PROJECT(4, "产品项目团队", Arrays.asList("documentAuthEnum", "bugAuthEnum", "autoDataBaseAuthEnum", "moduleAuthEnum", "autoEnvironmentAuthEnum", + "autoMicroserviceAuthEnum", "autoServerAuthEnum", "autoApiAuthEnum", "autoVariableAuthEnum", "autoVersionAuthEnum", "autoDemandAuthEnum"), true, false); + + private Integer key; + + private String value; + + private List pageAuth; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamBusinessController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamBusinessController.java new file mode 100644 index 0000000..45fb0ea --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamBusinessController.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamBusiness; +import com.skyeye.team.service.TeamBusinessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TeamBusinessController + * @Description: 团队管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "业务对象团队管理", tags = "业务对象团队管理", modelName = "团队模块") +public class TeamBusinessController { + + @Autowired + private TeamBusinessService teamBusinessService; + + /** + * 根据团队模板生成团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "createTeamBusiness", value = "根据团队模板生成团队信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "teamTemplateId", name = "teamTemplateId", value = "团队模板id", required = "required"), + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "业务对象的key", required = "required")}) + @RequestMapping("/post/TeamBusinessController/createTeamBusiness") + public void createTeamBusiness(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.createTeamBusiness(inputObject, outputObject); + } + + /** + * 根据业务对象id获取团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTeamBusiness", value = "根据业务对象id获取团队信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象id", required = "required")}) + @RequestMapping("/post/TeamBusinessController/queryTeamBusiness") + public void queryTeamBusiness(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.queryTeamBusiness(inputObject, outputObject); + } + + /** + * 根据业务对象id删除团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTeamBusiness", value = "根据业务对象id删除团队信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象id", required = "required")}) + @RequestMapping("/post/TeamBusinessController/deleteTeamBusiness") + public void deleteTeamBusiness(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.deleteTeamBusiness(inputObject, outputObject); + } + + /** + * 编辑团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateTeamBusiness", value = "编辑团队信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TeamBusiness.class) + @RequestMapping("/post/TeamBusinessController/updateTeamBusiness") + public void updateTeamBusiness(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.updateEntity(inputObject, outputObject); + } + + /** + * 校验团队权限信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkTeamBusinessAuthPermission", value = "校验团队权限信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务对象id", required = "required"), + @ApiImplicitParam(id = "enumKey", name = "enumKey", value = "权限的枚举类短名称", required = "required"), + @ApiImplicitParam(id = "enumClassName", name = "enumClassName", value = "权限的枚举类className名称", required = "required")}) + @RequestMapping("/post/TeamBusinessController/checkTeamBusinessAuthPermission") + public void checkTeamBusinessAuthPermission(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.checkTeamBusinessAuthPermission(inputObject, outputObject); + } + + /** + * 获取我所在的团队对应的团队模板id + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getMyTeamIds", value = "获取我所在的团队对应的团队模板id", method = "GET", allUse = "2") + @RequestMapping("/post/TeamBusinessController/getMyTeamIds") + public void getMyTeamIds(InputObject inputObject, OutputObject outputObject) { + teamBusinessService.getMyTeamIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamObjectPermissionController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamObjectPermissionController.java new file mode 100644 index 0000000..413b4b8 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamObjectPermissionController.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.controller; + +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TeamObjectPermissionController + * @Description: 业务对象权限管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:38 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +public class TeamObjectPermissionController { + + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleController.java new file mode 100644 index 0000000..617a443 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleController.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamRole; +import com.skyeye.team.service.TeamRoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TeamRoleController + * @Description: 团队角色管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:32 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "团队角色管理", tags = "团队角色管理", modelName = "团队模块") +public class TeamRoleController { + + @Autowired + private TeamRoleService teamRoleService; + + /** + * 新增团队角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertTeamRole", value = "新增团队角色信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TeamRole.class) + @RequestMapping("/post/TeamRoleController/insertTeamRole") + public void insertTeamRole(InputObject inputObject, OutputObject outputObject) { + teamRoleService.createEntity(inputObject, outputObject); + } + + /** + * 删除团队角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTeamRoleById", value = "删除团队角色信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "团队角色id", required = "required")}) + @RequestMapping("/post/TeamRoleController/deleteTeamRoleById") + public void deleteTeamRoleById(InputObject inputObject, OutputObject outputObject) { + teamRoleService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleUserController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleUserController.java new file mode 100644 index 0000000..ee2f569 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamRoleUserController.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamRoleUser; +import com.skyeye.team.service.TeamRoleUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TeamRoleUserController + * @Description: 团队用户管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:28 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "团队用户管理", tags = "团队用户管理", modelName = "团队模块") +public class TeamRoleUserController { + + @Autowired + private TeamRoleUserService teamRoleUserService; + + /** + * 新增团队用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertTeamRoleUser", value = "新增团队用户信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TeamRoleUser.class) + @RequestMapping("/post/TeamRoleController/insertTeamRoleUser") + public void insertTeamRoleUser(InputObject inputObject, OutputObject outputObject) { + teamRoleUserService.createEntity(inputObject, outputObject); + } + + /** + * 删除团队用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTeamRoleUserById", value = "删除团队用户信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "团队用户id", required = "required")}) + @RequestMapping("/post/TeamRoleController/deleteTeamRoleUserById") + public void deleteTeamRoleUserById(InputObject inputObject, OutputObject outputObject) { + teamRoleUserService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamTemplateController.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamTemplateController.java new file mode 100644 index 0000000..a6339d3 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/controller/TeamTemplateController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamTemplate; +import com.skyeye.team.service.TeamTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TeamTemplateController + * @Description: 团队模板管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "团队模板管理", tags = "团队模板管理", modelName = "团队模块") +public class TeamTemplateController { + + @Autowired + private TeamTemplateService teamTemplateService; + + /** + * 查询团队模板列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTeamTemplate", value = "查询团队模板列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TeamTemplateController/queryTeamTemplate") + public void queryTeamTemplate(InputObject inputObject, OutputObject outputObject) { + teamTemplateService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑团队模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTeamTemplate", value = "新增/编辑团队模板信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TeamTemplate.class) + @RequestMapping("/post/TeamTemplateController/writeTeamTemplate") + public void writeTeamTemplate(InputObject inputObject, OutputObject outputObject) { + teamTemplateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除团队模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTeamTemplateById", value = "删除团队模板信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "团队模板id", required = "required")}) + @RequestMapping("/post/TeamTemplateController/deleteTeamTemplateById") + public void deleteTeamTemplateById(InputObject inputObject, OutputObject outputObject) { + teamTemplateService.deleteById(inputObject, outputObject); + } + + /** + * 查询团队模板详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTeamTemplateById", value = "查询团队模板详情信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "团队模板id", required = "required")}) + @RequestMapping("/post/TeamTemplateController/queryTeamTemplateById") + public void queryTeamTemplateById(InputObject inputObject, OutputObject outputObject) { + teamTemplateService.queryTeamMation(inputObject, outputObject); + } + + /** + * 根据受用对象查询已启用的团队模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnableTeamTemplateList", value = "根据受用对象查询已启用的团队模板列表", method = "GET", allUse = "2") + @RequestMapping("/post/TeamTemplateController/queryEnableTeamTemplateList") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectType", name = "objectType", value = "受用对象", required = "required,num")}) + public void queryEnableTeamTemplateList(InputObject inputObject, OutputObject outputObject) { + teamTemplateService.queryEnableTeamTemplateList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamBusinessDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamBusinessDao.java new file mode 100644 index 0000000..c02bb67 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamBusinessDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.entity.TeamBusiness; + +/** + * @ClassName: TeamBusinessDao + * @Description: 团队管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:36 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamBusinessDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamObjectPermissionDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamObjectPermissionDao.java new file mode 100644 index 0000000..c7914a2 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamObjectPermissionDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.entity.TeamObjectPermission; + +/** + * @ClassName: TeamObjectPermissionDao + * @Description: 业务对象权限管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:39 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamObjectPermissionDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleDao.java new file mode 100644 index 0000000..36b54e5 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.entity.TeamRole; + +/** + * @ClassName: TeamRoleDao + * @Description: 团队角色管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamRoleDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleUserDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleUserDao.java new file mode 100644 index 0000000..bf27019 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamRoleUserDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.entity.TeamRoleUser; + +/** + * @ClassName: TeamRoleUserDao + * @Description: 团队用户管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:29 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamRoleUserDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamTemplateDao.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamTemplateDao.java new file mode 100644 index 0000000..a5a4022 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/dao/TeamTemplateDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.entity.TeamTemplate; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TeamTemplateDao + * @Description: 团队模板管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamTemplateDao extends SkyeyeBaseMapper { + + List> queryList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/AbstractTeam.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/AbstractTeam.java new file mode 100644 index 0000000..824d2f7 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/AbstractTeam.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AbstractTeam + * @Description: 团队抽象实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class AbstractTeam extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @ApiModelProperty(value = "团队角色", required = "required,json") + private List teamRoleList; + + @TableField(exist = false) + @ApiModelProperty(value = "团队权限", required = "json") + private List teamObjectPermissionList; + + @TableField(value = "charge_user") + @ApiModelProperty(value = "团队经理", required = "required") + private String chargeUser; + + /** + * 团队经理信息 + */ + @TableField(exist = false) + private Map chargeUserMation; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamBusiness.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamBusiness.java new file mode 100644 index 0000000..aa7461d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamBusiness.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: TeamBusiness + * @Description: 团队实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"objectId", "objectKey"}) +@RedisCacheField(name = CacheConstants.TEAM_BUSINESS_CACHE_KEY, value = {"id", "objectId"}, cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "team_business") +@ApiModel("团队实体类") +public class TeamBusiness extends AbstractTeam { + + /** + * 名称 + */ + @TableField(exist = false) + private String name; + + @TableField(value = "object_id", fill = FieldFill.INSERT) + @ApiModelProperty(value = "业务对象id", required = "required") + private String objectId; + + @TableField(value = "object_key", fill = FieldFill.INSERT) + @ApiModelProperty(value = "业务对象的key", required = "required") + private String objectKey; + + @TableField(value = "team_template_id", fill = FieldFill.INSERT) + @ApiModelProperty(value = "团队模板id", required = "required") + private String teamTemplateId; + + /** + * 团队角色信息 + */ + @TableField(exist = false) + private List teamRoleList; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamObjectPermission.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamObjectPermission.java new file mode 100644 index 0000000..63c9cdd --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamObjectPermission.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: TeamObjectPermission + * @Description: 业务对象权限实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "team_object_permission") +@ApiModel("业务对象权限实体类") +public class TeamObjectPermission extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField("team_id") + @ApiModelProperty(value = "团队id,单独保存时必填(因为有和团队一起的保存)") + private String teamId; + + @TableField("team_key") + @ApiModelProperty(value = "团队类型,单独保存时必填(因为有和团队一起的保存)") + private String teamKey; + + @TableField("object_id") + @ApiModelProperty(value = "业务对象下面的子业务数据的id,例如:客户下的联系人,一般用于用户A给用户B赋权时有值") + private String objectId; + + @TableField("object_key") + @ApiModelProperty(value = "业务对象下面的子业务数据的key,例如:客户下的联系人,一般用于用户A给用户B赋权时有值") + private String objectKey; + + @TableField("permission_value") + @ApiModelProperty(value = "权限点,例如:联系人功能,添加,编辑等都是权限点", required = "required") + private String permissionValue; + + @TableField("permission_key") + @ApiModelProperty(value = "权限点的key", required = "required") + private String permissionKey; + + @TableField("owner_id") + @ApiModelProperty(value = "权限点拥有者id", required = "required") + private String ownerId; + + @TableField("owner_key") + @ApiModelProperty(value = "权限点拥有者的key,例如团队角色,用户等", required = "required") + private String ownerKey; + + @TableField("from_type") + @ApiModelProperty(value = "权限来源 参考:#ObjectPermissionFromType", required = "required,num") + private Integer fromType; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRole.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRole.java new file mode 100644 index 0000000..d8fcf7b --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRole.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: TeamRole + * @Description: 团队角色实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"teamId", "teamKey", "roleId"}) +@TableName(value = "team_role") +@ApiModel("团队角色实体类") +public class TeamRole extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + /** + * 角色名称 + */ + @TableField(exist = false) + private String name; + + /** + * 角色父id,这里为团队id + */ + @TableField(exist = false) + private String pId; + + @TableField("team_id") + @ApiModelProperty(value = "团队id,单独保存时必填(因为有和团队一起的保存)") + private String teamId; + + @TableField("team_key") + @ApiModelProperty(value = "团队类型,单独保存时必填(因为有和团队一起的保存)") + private String teamKey; + + @TableField("role_id") + @ApiModelProperty(value = "团队角色id(数据字典中的团队角色类型)", required = "required") + private String roleId; + + @TableField(exist = false) + @ApiModelProperty(value = "角色用户", required = "json") + private List teamRoleUserList; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRoleUser.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRoleUser.java new file mode 100644 index 0000000..14ffc8f --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamRoleUser.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: TeamRoleUser + * @Description: 团队用户实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"teamId", "teamKey", "userId"}) +@TableName(value = "team_role_user") +@ApiModel("团队用户实体类") +public class TeamRoleUser extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + /** + * 用户信息 + */ + @TableField(exist = false) + private Map userMation; + + @TableField("team_id") + @ApiModelProperty(value = "团队id,单独保存时必填(因为有和团队一起的保存)") + private String teamId; + + @TableField("team_key") + @ApiModelProperty(value = "团队类型,单独保存时必填(因为有和团队一起的保存)") + private String teamKey; + + @TableField("role_id") + @ApiModelProperty(value = "团队角色id(数据字典中的团队角色类型),单独保存时必填(因为有和团队一起的保存)") + private String roleId; + + @TableField("user_id") + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamTemplate.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamTemplate.java new file mode 100644 index 0000000..59bac1c --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/entity/TeamTemplate.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import lombok.Data; + +/** + * @ClassName: TeamTemplate + * @Description: 团队模板实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.TEAM_TEMPLATE_CACHE_KEY, cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "team_template") +@ApiModel("团队模板实体类") +public class TeamTemplate extends AbstractTeam { + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + /** + * 编码 + */ + @TableField("`code`") + private String code; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("object_type") + @ApiModelProperty(value = "该模板适用的对象类型,来源skyeye-pro#TeamObjectTypeEnum", required = "required,num") + private Integer objectType; + + @TableField("enabled") + @ApiModelProperty(value = "启用 1-启用 2-禁用", required = "required,num") + private Integer enabled; + + @TableField("is_used") + @Property(value = "是否使用中,参考#IsUsedEnum") + private Integer isUsed; + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/AbstractTeamService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/AbstractTeamService.java new file mode 100644 index 0000000..1052363 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/AbstractTeamService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AbstractTeamService + * @Description: 团队管理抽象类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:24 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AbstractTeamService extends SkyeyeBusinessService { + + void queryTeamMation(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamBusinessService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamBusinessService.java new file mode 100644 index 0000000..2d31b36 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamBusinessService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamBusiness; + +/** + * @ClassName: TeamBusinessService + * @Description: 团队管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:36 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamBusinessService extends AbstractTeamService { + + void createTeamBusiness(InputObject inputObject, OutputObject outputObject); + + void queryTeamBusiness(InputObject inputObject, OutputObject outputObject); + + void deleteTeamBusiness(InputObject inputObject, OutputObject outputObject); + + void checkTeamBusinessAuthPermission(InputObject inputObject, OutputObject outputObject); + + void getMyTeamIds(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamObjectPermissionService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamObjectPermissionService.java new file mode 100644 index 0000000..3999d99 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamObjectPermissionService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.team.entity.TeamObjectPermission; + +import java.util.List; + +/** + * @ClassName: TeamObjectPermissionService + * @Description: 业务对象权限管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:39 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamObjectPermissionService extends SkyeyeBusinessService { + + List queryPermissionByTeamId(String teamId, List ownerIds); + + void deletePermissionByTeamIds(String... teamIds); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleService.java new file mode 100644 index 0000000..1d5c7b8 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleService.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.team.entity.TeamRole; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TeamRoleService + * @Description: 团队角色管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamRoleService extends SkyeyeBusinessService { + + /** + * 根据团队id获取团队下的角色信息,并且包含角色下的用户信息 + * + * @param teamIds + * @return + */ + Map> queryTeamRoleByTeamIds(String... teamIds); + + /** + * 设置角色名称 + * + * @param teamRoleList + */ + void setUserRoleName(List teamRoleList); + + /** + * 根据团队id批量删除角色信息 + * + * @param teamIds + */ + void deleteRoleByTeamIds(String... teamIds); + + /** + * 根据角色id批量删除角色信息 + * + * @param roleIds + */ + void deleteRoleByRoleIds(String... roleIds); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleUserService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleUserService.java new file mode 100644 index 0000000..596b386 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamRoleUserService.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.team.entity.TeamRole; +import com.skyeye.team.entity.TeamRoleUser; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TeamRoleUserService + * @Description: 团队用户管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:29 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamRoleUserService extends SkyeyeBusinessService { + + /** + * 根据团队id查询该团队下的所有成员(结果的key为:团队id+角色id) + * + * @param teamIds + * @return + */ + Map> queryRoleUserByTeamIds(String... teamIds); + + /** + * 设置用户信息 + * + * @param teamRoleList + */ + void setUserName(List teamRoleList); + + /** + * 根据团队id批量删除用户信息 + * + * @param teamIds + */ + void deleteRoleUserByTeamIds(String... teamIds); + + /** + * 根据角色id批量删除用户信息 + * + * @param teamId + * @param roleIds + */ + void deleteRoleUserByRoleIds(String teamId, String... roleIds); + + /** + * 获取指定用户所在的团队 + * + * @param userId + * @return + */ + List getTeamIdsByUserId(String userId); + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamTemplateService.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamTemplateService.java new file mode 100644 index 0000000..d1286c9 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/TeamTemplateService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.team.entity.TeamTemplate; + +/** + * @ClassName: TeamTemplateService + * @Description: 团队模板管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:24 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TeamTemplateService extends AbstractTeamService { + + /** + * 设置为使用中 + * + * @param id + */ + void setUsed(String id); + + void queryEnableTeamTemplateList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/AbstractTeamServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/AbstractTeamServiceImpl.java new file mode 100644 index 0000000..2ca2615 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/AbstractTeamServiceImpl.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.team.classenum.ObjectPermissionFromType; +import com.skyeye.team.entity.AbstractTeam; +import com.skyeye.team.entity.TeamObjectPermission; +import com.skyeye.team.entity.TeamRole; +import com.skyeye.team.entity.TeamRoleUser; +import com.skyeye.team.service.AbstractTeamService; +import com.skyeye.team.service.TeamObjectPermissionService; +import com.skyeye.team.service.TeamRoleService; +import com.skyeye.team.service.TeamRoleUserService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AbstractTeamServiceImpl + * @Description: 团队管理抽象类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:24 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class AbstractTeamServiceImpl, T extends AbstractTeam> extends SkyeyeBusinessServiceImpl implements AbstractTeamService { + + @Autowired + protected TeamRoleService teamRoleService; + + @Autowired + protected TeamRoleUserService teamRoleUserService; + + @Autowired + protected TeamObjectPermissionService teamObjectPermissionService; + + @Override + public void createPostpose(T entity, String userId) { + String teamId = entity.getId(); + List teamRoleList = entity.getTeamRoleList(); + String serviceClassName = getServiceClassName(); + if (CollectionUtil.isNotEmpty(teamRoleList)) { + saveRole(userId, teamId, teamRoleList, serviceClassName); + } + // 修改团队用户信息 + updateRoleUser(userId, teamId, teamRoleList, serviceClassName, new ArrayList<>()); + + if (CollectionUtil.isNotEmpty(entity.getTeamObjectPermissionList())) { + saveTeamOwnerPermission(teamId, serviceClassName, userId, entity.getTeamObjectPermissionList()); + } + } + + @Override + public void updatePostpose(T entity, String userId) { + String teamId = entity.getId(); + List newTeamRoleList = entity.getTeamRoleList(); + if (CollectionUtil.isNotEmpty(newTeamRoleList)) { + String serviceClassName = getServiceClassName(); + T oldTeam = selectById(teamId); + List oldTeamRoleList = CollectionUtil.isEmpty(oldTeam.getTeamRoleList()) ? new ArrayList<>() : oldTeam.getTeamRoleList(); + List oldRoleKeys = oldTeamRoleList.stream().map(bean -> bean.getRoleId()).collect(Collectors.toList()); + // 修改角色信息 + updateRole(userId, teamId, newTeamRoleList, serviceClassName, oldTeamRoleList, oldRoleKeys); + + // 修改团队用户信息 + updateRoleUser(userId, teamId, newTeamRoleList, serviceClassName, oldTeamRoleList); + + // 修改权限信息 + updatePermission(entity.getTeamObjectPermissionList(), oldTeam.getTeamObjectPermissionList(), teamId, serviceClassName, userId); + } else { + // 如果团队角色集合为空,则删除旧的团队角色和用户数据 + // 1. 删除团队模板与角色的关系 + teamRoleService.deleteRoleByTeamIds(teamId); + // 2. 删除角色下的用户 + teamRoleUserService.deleteRoleUserByTeamIds(teamId); + // 3. 删除团队下的权限信息 + teamObjectPermissionService.deletePermissionByTeamIds(teamId); + } + } + + private void updateRole(String userId, String teamId, List newTeamRoleList, String serviceClassName, + List oldTeamRoleList, List oldRoleKeys) { + List newRoleKeys = newTeamRoleList.stream().map(bean -> bean.getRoleId()).collect(Collectors.toList()); + // (新数据 - 旧数据) 添加到数据库 + List addTeamRoleMaps = newTeamRoleList.stream() + .filter(item -> !oldRoleKeys.contains(item.getRoleId())).collect(Collectors.toList()); + // 新增 + if (CollectionUtil.isNotEmpty(addTeamRoleMaps)) { + saveRole(userId, teamId, addTeamRoleMaps, serviceClassName); + } + // (旧数据 - 新数据) 从数据库删除 + List deleteTeamRole = oldTeamRoleList.stream() + .filter(item -> !newRoleKeys.contains(item.getRoleId())).collect(Collectors.toList()); + List removeRoleIds = deleteTeamRole.stream().map(teamRole -> teamRole.getRoleId()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(removeRoleIds)) { + teamRoleService.deleteRoleByRoleIds(removeRoleIds.toArray(new String[]{})); + teamRoleUserService.deleteRoleUserByRoleIds(teamId, removeRoleIds.toArray(new String[]{})); + } + } + + private void updateRoleUser(String userId, String teamId, List newTeamRoleList, String serviceClassName, List oldTeamRole) { + // 新数据 - 旧数据 更新到数据库 + List newRoleUser = getTeamRoleUserList(newTeamRoleList); + List newRoleUserKeys = newRoleUser.stream().map(bean -> teamId + bean.getUserId()).collect(Collectors.toList()); + // 数据库里面的该团队模板下的用户信息 + List oldRoleUser = getTeamRoleUserList(oldTeamRole); + List oldRoleUserKeys = oldRoleUser.stream().map(bean -> teamId + bean.getUserId()).collect(Collectors.toList()); + // 需要新增的用户信息 + List addTeamRoleUser = newRoleUser.stream() + .filter(item -> !oldRoleUserKeys.contains(teamId + item.getUserId())).collect(Collectors.toList()); + addTeamRoleUser.forEach(p -> { + p.setId(null); + p.setTeamId(teamId); + p.setTeamKey(serviceClassName); + }); + if (CollectionUtil.isNotEmpty(addTeamRoleUser)) { + teamRoleUserService.createEntity(addTeamRoleUser, userId); + } + // 删除用户关联信息 + List deleteRoleUser = oldRoleUser.stream() + .filter(predicate -> !newRoleUserKeys.contains(teamId + predicate.getUserId())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(deleteRoleUser)) { + List deleteRoleUserLinkIds = deleteRoleUser.stream().map(TeamRoleUser::getId).collect(Collectors.toList()); + teamRoleUserService.deleteById(deleteRoleUserLinkIds); + } + } + + private void updatePermission(List newPermissionList, List oldPermissionList, String teamId, + String serviceClassName, String userId) { + // 只处理 团队统一赋权 操作的数据 + oldPermissionList = oldPermissionList.stream() + .filter(oldPermission -> oldPermission.getFromType().equals(ObjectPermissionFromType.TEAM_LINK.getKey())).collect(Collectors.toList()); + List newPermissionKeys = newPermissionList.stream().map(bean -> getPermissionKey(bean)).collect(Collectors.toList()); + List oldPermissionKeys = oldPermissionList.stream().map(bean -> getPermissionKey(bean)).collect(Collectors.toList()); + // 需要新增的 + List addPermission = newPermissionList.stream() + .filter(item -> !oldPermissionKeys.contains(getPermissionKey(item))).collect(Collectors.toList()); + saveTeamOwnerPermission(teamId, serviceClassName, userId, addPermission); + + // (旧数据 - 新数据) 从数据库删除 + List deletePermission = oldPermissionList.stream() + .filter(item -> !newPermissionKeys.contains(getPermissionKey(item))).collect(Collectors.toList()); + List removePermissionIds = deletePermission.stream().map(TeamObjectPermission::getId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(removePermissionIds)) { + teamObjectPermissionService.deleteById(removePermissionIds); + } + } + + private String getPermissionKey(TeamObjectPermission permission) { + return String.format(Locale.ROOT, "%s_%s_%s_%s", permission.getPermissionValue(), permission.getPermissionKey(), + permission.getOwnerId(), permission.getOwnerKey()); + } + + private List getTeamRoleUserList(List teamRoleList) { + if (CollectionUtil.isEmpty(teamRoleList)) { + return CollectionUtil.newArrayList(); + } + return teamRoleList.stream() + .filter(teamRole -> CollectionUtil.isNotEmpty(teamRole.getTeamRoleUserList())) + .flatMap(teamRole -> { + teamRole.getTeamRoleUserList().forEach(teamRoleUser -> { + teamRoleUser.setRoleId(teamRole.getRoleId()); + }); + return teamRole.getTeamRoleUserList().stream(); + }) + .filter(Objects::nonNull).collect(Collectors.toList()); + } + + public void saveTeamOwnerPermission(String teamId, String serviceClassName, String userId, List addPermission) { + addPermission.forEach(bean -> { + bean.setTeamId(teamId); + bean.setTeamKey(serviceClassName); + bean.setFromType(ObjectPermissionFromType.TEAM_LINK.getKey()); + }); + teamObjectPermissionService.createEntity(addPermission, userId); + } + + private void saveRole(String userId, String teamId, List teamRoleList, String serviceClassName) { + teamRoleList.forEach(teamRole -> { + teamRole.setTeamId(teamId); + teamRole.setTeamKey(serviceClassName); + }); + teamRoleService.createEntity(teamRoleList, userId); + } + + @Override + public T getDataFromDb(String id) { + T team = super.getDataFromDb(id); + Map> teamRoleMap = teamRoleService.queryTeamRoleByTeamIds(team.getId()); + team.setTeamRoleList(teamRoleMap.get(team.getId())); + List teamObjectPermissionList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(team.getTeamRoleList())) { + // 查询角色权限 + List ownerIds = team.getTeamRoleList().stream().map(TeamRole::getRoleId).collect(Collectors.toList()); + // 查询用户权限 + List userIds = team.getTeamRoleList().stream() + .filter(teamRole -> CollectionUtil.isNotEmpty(teamRole.getTeamRoleUserList())) + .flatMap(teamRole -> teamRole.getTeamRoleUserList().stream()) + .filter(bean -> !ToolUtil.isBlank(bean.getUserId())) + .map(bean -> bean.getUserId()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(userIds)) { + ownerIds.addAll(userIds); + } + List authermissionList = teamObjectPermissionService.queryPermissionByTeamId(team.getId(), ownerIds); + teamObjectPermissionList.addAll(authermissionList); + } + team.setTeamObjectPermissionList(teamObjectPermissionList); + return team; + } + + @Override + public void deletePostpose(String id) { + // 删除团队下的角色信息 + teamRoleService.deleteRoleByTeamIds(id); + // 删除团队下的用户信息 + teamRoleUserService.deleteRoleUserByTeamIds(id); + // 删除团队下的权限信息 + teamObjectPermissionService.deletePermissionByTeamIds(id); + } + + /** + * 查询团队模板详情信息 + * + * @param inputObject + * @param outputObject + */ + @Override + public void queryTeamMation(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + T team = super.selectById(id); + setOtherName(team); + team.setChargeUserMation(iAuthUserService.queryDataMationById(team.getChargeUser())); + outputObject.setBean(team); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + public void setOtherName(T team) { + teamRoleService.setUserRoleName(team.getTeamRoleList()); + teamRoleUserService.setUserName(team.getTeamRoleList()); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamBusinessServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamBusinessServiceImpl.java new file mode 100644 index 0000000..db0b439 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamBusinessServiceImpl.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.clazz.service.SkyeyeClassEnumService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.team.dao.TeamBusinessDao; +import com.skyeye.team.entity.TeamBusiness; +import com.skyeye.team.entity.TeamTemplate; +import com.skyeye.team.service.ITeamBusinessService; +import com.skyeye.team.service.TeamBusinessService; +import com.skyeye.team.service.TeamTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: TeamBusinessServiceImpl + * @Description: 团队管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:37 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "团队管理", groupName = "团队管理") +public class TeamBusinessServiceImpl extends AbstractTeamServiceImpl implements TeamBusinessService { + + @Autowired + private TeamTemplateService teamTemplateService; + + @Autowired + private ITeamBusinessService iTeamBusinessService; + + @Autowired + private SkyeyeClassEnumService skyeyeClassEnumService; + + /** + * 根据团队模板生成团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void createTeamBusiness(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String teamTemplateId = params.get("teamTemplateId").toString(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + TeamTemplate teamTemplate = teamTemplateService.selectById(teamTemplateId); + if (teamTemplate == null) { + throw new CustomException("该团队模板不存在."); + } + TeamBusiness teamBusiness = Convert.convert(TeamBusiness.class, teamTemplate); + teamBusiness.setTeamTemplateId(teamTemplateId); + teamBusiness.setObjectId(objectId); + teamBusiness.setObjectKey(objectKey); + String userId = inputObject.getLogParams().get("id").toString(); + createEntity(teamBusiness, userId); + // 设置该模板为启用中 + teamTemplateService.setUsed(teamTemplateId); + } + + /** + * 根据业务对象id获取团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryTeamBusiness(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + TeamBusiness teamBusiness = selectById(objectId); + if (teamBusiness == null) { + throw new CustomException("该团队不存在."); + } + setOtherName(teamBusiness); + // 设置名称 + TeamTemplate teamTemplate = teamTemplateService.selectById(teamBusiness.getTeamTemplateId()); + teamBusiness.setName(teamTemplate.getName()); + teamBusiness.setChargeUserMation(iAuthUserService.queryDataMationById(teamBusiness.getChargeUser())); + outputObject.setBean(teamBusiness); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据业务对象id删除团队信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void deleteTeamBusiness(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + TeamBusiness teamBusiness = selectById(objectId); + if (teamBusiness != null) { + deleteById(teamBusiness.getId()); + } + } + + /** + * 校验团队权限信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void checkTeamBusinessAuthPermission(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String enumKey = params.get("enumKey").toString(); + String enumClassName = params.get("enumClassName").toString(); + // 获取枚举类的数据 + List> enumDataList = skyeyeClassEnumService.queryEnumDataList(enumClassName, StrUtil.EMPTY, StrUtil.EMPTY); + List enumDataId = enumDataList.stream().map(bean -> bean.get(CommonConstants.ID).toString()).collect(Collectors.toList()); + + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + Map checkAuthPermission = iTeamBusinessService.checkAuthPermission(objectId, enumKey, enumDataId, userId); + outputObject.setBean(checkAuthPermission); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 获取我所在的团队对应的团队模板id + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getMyTeamIds(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + List teamIds = teamRoleUserService.getTeamIdsByUserId(userId); + // 根据团队id或者团队经理(当前登录用户)查询团队模板id + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(MybatisPlusUtil.toColumns(TeamBusiness::getTeamTemplateId)); + queryWrapper.and(wrapper -> { + wrapper.eq(MybatisPlusUtil.toColumns(TeamBusiness::getChargeUser), userId); + if (CollectionUtil.isNotEmpty(teamIds)) { + wrapper.or().in(CommonConstants.ID, teamIds); + } + }); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(TeamBusiness::getTeamTemplateId)); + List teamBusinessList = list(queryWrapper); + if (CollectionUtil.isEmpty(teamBusinessList)) { + return; + } + List teamTemplateIds = teamBusinessList.stream() + .map(TeamBusiness::getTeamTemplateId).collect(Collectors.toList()); + Map result = new HashMap<>(); + result.put("teamTemplateIds", teamTemplateIds); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} + diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamObjectPermissionServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamObjectPermissionServiceImpl.java new file mode 100644 index 0000000..c22918d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamObjectPermissionServiceImpl.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.team.dao.TeamObjectPermissionDao; +import com.skyeye.team.entity.TeamObjectPermission; +import com.skyeye.team.entity.TeamRoleUser; +import com.skyeye.team.service.TeamObjectPermissionService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @ClassName: TeamObjectPermissionServiceImpl + * @Description: 业务对象权限管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:40 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class TeamObjectPermissionServiceImpl extends SkyeyeBusinessServiceImpl implements TeamObjectPermissionService { + + @Override + public List queryPermissionByTeamId(String teamId, List ownerIds) { + if (ToolUtil.isBlank(teamId) || CollectionUtil.isEmpty(ownerIds)) { + return new ArrayList<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamObjectPermission::getTeamId), teamId); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamObjectPermission::getOwnerId), ownerIds); + List teamObjectPermissionList = super.list(queryWrapper); + return teamObjectPermissionList; + } + + /** + * 删除团队下的权限信息 + * + * @param teamIds + */ + @Override + public void deletePermissionByTeamIds(String... teamIds) { + List teamIdList = Arrays.asList(teamIds); + if (CollectionUtil.isEmpty(teamIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamObjectPermission::getTeamId), teamIdList); + remove(queryWrapper); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleServiceImpl.java new file mode 100644 index 0000000..fa3e1ab --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleServiceImpl.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.team.entity.TeamRole; +import com.skyeye.team.entity.TeamRoleUser; +import com.skyeye.team.dao.TeamRoleDao; +import com.skyeye.team.service.TeamRoleService; +import com.skyeye.team.service.TeamRoleUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: TeamRoleServiceImpl + * @Description: 团队角色管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class TeamRoleServiceImpl extends SkyeyeBusinessServiceImpl implements TeamRoleService { + + @Autowired + private TeamRoleUserService teamRoleUserService; + + /** + * 根据团队id获取团队下的角色信息,并且包含角色下的用户信息 + * + * @param teamIds + * @return + */ + @Override + public Map> queryTeamRoleByTeamIds(String... teamIds) { + List teamIdList = Arrays.asList(teamIds); + if (CollectionUtil.isEmpty(teamIdList)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRole::getTeamId), teamIdList); + List teamRoleList = super.list(queryWrapper); + if (CollectionUtil.isEmpty(teamRoleList)) { + return new HashMap<>(); + } + // 查询用户信息 + Map> roleUserMap = teamRoleUserService.queryRoleUserByTeamIds(teamIds); + for (TeamRole teamRole : teamRoleList) { + String key = String.format(Locale.ROOT, "%s_%s", teamRole.getTeamId(), teamRole.getRoleId()); + List roleUser = roleUserMap.get(key); + if (CollectionUtil.isEmpty(roleUser)) { + roleUser = new ArrayList<>(); + } + teamRole.setTeamRoleUserList(roleUser); + } + return teamRoleList.stream().collect(Collectors.groupingBy(TeamRole::getTeamId)); + } + + /** + * 设置角色名称 + * + * @param teamRoleList + */ + @Override + public void setUserRoleName(List teamRoleList) { + if (CollectionUtil.isEmpty(teamRoleList)) { + return; + } + List roleIds = teamRoleList.stream().map(TeamRole::getRoleId).collect(Collectors.toList()); + // 查询角色信息 + List> sysDictDataList = iSysDictDataService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(roleIds)); + Map> maps = sysDictDataList.stream() + .collect(Collectors.toMap(item -> item.get("id").toString(), Function.identity())); + // 循环设置角色名称 + teamRoleList.forEach(teamRole -> { + Map map = maps.get(teamRole.getRoleId()); + if (CollectionUtil.isNotEmpty(map)) { + teamRole.setName(map.get("dictName").toString()); + } + }); + } + + /** + * 根据团队id批量删除角色信息 + * + * @param teamIds + */ + @Override + public void deleteRoleByTeamIds(String... teamIds) { + List teamIdList = Arrays.asList(teamIds); + if (CollectionUtil.isEmpty(teamIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRole::getTeamId), teamIdList); + remove(queryWrapper); + } + + /** + * 根据角色id批量删除角色信息 + * + * @param roleIds + */ + @Override + public void deleteRoleByRoleIds(String... roleIds) { + List roleIdList = Arrays.asList(roleIds); + if (CollectionUtil.isEmpty(roleIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRole::getRoleId), roleIdList); + remove(queryWrapper); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleUserServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleUserServiceImpl.java new file mode 100644 index 0000000..146ba1b --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamRoleUserServiceImpl.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.team.dao.TeamRoleUserDao; +import com.skyeye.team.entity.TeamRole; +import com.skyeye.team.entity.TeamRoleUser; +import com.skyeye.team.service.TeamBusinessService; +import com.skyeye.team.service.TeamRoleUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: TeamRoleUserServiceImpl + * @Description: 团队用户管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class TeamRoleUserServiceImpl extends SkyeyeBusinessServiceImpl implements TeamRoleUserService { + + @Autowired + private TeamBusinessService teamBusinessService; + + /** + * 根据团队id查询该团队下的所有成员(结果的key为:团队id+角色id) + * + * @param teamIds + * @return + */ + @Override + public Map> queryRoleUserByTeamIds(String... teamIds) { + List teamIdList = Arrays.asList(teamIds); + if (CollectionUtil.isEmpty(teamIdList)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamId), teamIdList); + List teamRoleUserList = super.list(queryWrapper); + if (CollectionUtil.isEmpty(teamRoleUserList)) { + return new HashMap<>(); + } + return teamRoleUserList.stream() + .collect(Collectors.groupingBy(bean -> String.format(Locale.ROOT, "%s_%s", bean.getTeamId(), bean.getRoleId()))); + } + + /** + * 设置用户信息 + * + * @param teamRoleList + */ + @Override + public void setUserName(List teamRoleList) { + if (CollectionUtil.isEmpty(teamRoleList)) { + return; + } + List userIds = teamRoleList.stream() + .filter(teamRole -> CollectionUtil.isNotEmpty(teamRole.getTeamRoleUserList())) + .flatMap(teamRole -> teamRole.getTeamRoleUserList().stream()) + .filter(bean -> !ToolUtil.isBlank(bean.getUserId())) + .map(bean -> bean.getUserId()).collect(Collectors.toList()); + Map> userNameMap = iAuthUserService.queryUserNameList(userIds); + teamRoleList.forEach(teamRole -> { + teamRole.getTeamRoleUserList().forEach(teamRoleUser -> { + Map userMation = userNameMap.get(teamRoleUser.getUserId()); + teamRoleUser.setUserMation(CollectionUtil.isEmpty(userMation) ? new HashMap<>() : userMation); + }); + }); + } + + /** + * 根据团队id批量删除用户信息 + * + * @param teamIds + */ + @Override + public void deleteRoleUserByTeamIds(String... teamIds) { + List teamIdList = Arrays.asList(teamIds); + if (CollectionUtil.isEmpty(teamIdList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamId), teamIdList); + remove(queryWrapper); + } + + /** + * 根据角色id批量删除用户信息 + * + * @param teamId + * @param roleIds + */ + @Override + public void deleteRoleUserByRoleIds(String teamId, String... roleIds) { + List roleIdList = Arrays.asList(roleIds); + if (CollectionUtil.isEmpty(roleIdList) || ToolUtil.isBlank(teamId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(TeamRoleUser::getRoleId), roleIdList); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamId), teamId); + remove(queryWrapper); + } + + /** + * 获取指定用户所在的团队 + * + * @param userId + * @return + */ + @Override + public List getTeamIdsByUserId(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamId)); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamRoleUser::getUserId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamKey), teamBusinessService.getServiceClassName()); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(TeamRoleUser::getTeamId)); + List teamRoleUsers = list(queryWrapper); + if (CollectionUtil.isEmpty(teamRoleUsers)) { + return new ArrayList<>(); + } + return teamRoleUsers.stream().map(TeamRoleUser::getTeamId).collect(Collectors.toList()); + } +} diff --git a/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamTemplateServiceImpl.java b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamTemplateServiceImpl.java new file mode 100644 index 0000000..fc2cc0e --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/java/com/skyeye/team/service/impl/TeamTemplateServiceImpl.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.team.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.enumeration.IsUsedEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.coderule.service.ICodeRuleService; +import com.skyeye.team.dao.TeamTemplateDao; +import com.skyeye.team.entity.TeamTemplate; +import com.skyeye.team.service.TeamTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TeamTemplateServiceImpl + * @Description: 团队模板管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/13 19:24 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "团队模板管理", groupName = "团队管理") +public class TeamTemplateServiceImpl extends AbstractTeamServiceImpl implements TeamTemplateService { + + @Autowired + private TeamTemplateDao teamTemplateDao; + + @Autowired + private ICodeRuleService iCodeRuleService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = teamTemplateDao.queryList(commonPageInfo); + iAuthUserService.setNameForMap(beans, "chargeUser", "chargeUserName"); + return beans; + } + + @Override + public void createPrepose(TeamTemplate entity) { + String code = iCodeRuleService.getNextCodeByClassName(this.getServiceClassName(), BeanUtil.beanToMap(entity)); + entity.setCode(code); + } + + /** + * 设置为使用中 + * + * @param id + */ + @Override + public void setUsed(String id) { + TeamTemplate teamTemplate = super.selectById(id); + if (teamTemplate.getIsUsed() == null || teamTemplate.getIsUsed() == IsUsedEnum.NOT_USED.getKey()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + TeamTemplate template = new TeamTemplate(); + template.setIsUsed(IsUsedEnum.IN_USE.getKey()); + String userId = InputObject.getLogParamsStatic().get(CommonConstants.ID).toString(); + DataCommonUtil.setCommonLastUpdateDataByGenericity(template, userId); + skyeyeBaseMapper.update(template, updateWrapper); + + refreshCache(id); + } + } + + /** + * 查询已启用的团队模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnableTeamTemplateList(InputObject inputObject, OutputObject outputObject) { + String objectType = inputObject.getParams().get("objectType").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamTemplate::getObjectType), objectType); + queryWrapper.eq(MybatisPlusUtil.toColumns(TeamTemplate::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List teamTemplateList = list(queryWrapper); + outputObject.setBeans(teamTemplateList); + outputObject.settotal(teamTemplateList.size()); + } + +} diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/catalog/CatalogMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/catalog/CatalogMapper.xml new file mode 100644 index 0000000..468010d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/catalog/CatalogMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/contacts/ContactsMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/contacts/ContactsMapper.xml new file mode 100644 index 0000000..6fc857d --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/contacts/ContactsMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + UPDATE skyeye_contacts + + is_default = ${isDefault} + + WHERE object_id = #{objectId} + + + + UPDATE skyeye_contacts + + is_default = ${isDefault} + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionMapper.xml new file mode 100644 index 0000000..65eda48 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionMapper.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionReplyMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionReplyMapper.xml new file mode 100644 index 0000000..22dc9d8 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/discussion/DiscussionReplyMapper.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/document/DocumentMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/document/DocumentMapper.xml new file mode 100644 index 0000000..fb5d49c --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/document/DocumentMapper.xml @@ -0,0 +1,39 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/enclosure/SysEnclosureMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/enclosure/SysEnclosureMapper.xml new file mode 100644 index 0000000..1d1c9cc --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/enclosure/SysEnclosureMapper.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamBusinessMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamBusinessMapper.xml new file mode 100644 index 0000000..f966011 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamBusinessMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamObjectPermissionMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamObjectPermissionMapper.xml new file mode 100644 index 0000000..ba06df7 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamObjectPermissionMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleMapper.xml new file mode 100644 index 0000000..caa3ae8 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleUserMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleUserMapper.xml new file mode 100644 index 0000000..9753c38 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamRoleUserMapper.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamTemplateMapper.xml b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamTemplateMapper.xml new file mode 100644 index 0000000..092d916 --- /dev/null +++ b/skyeye-promote/skyeye-base-server/src/main/resources/mapper/team/TeamTemplateMapper.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/skyeye-promote/skyeye-code-doc/.gitignore b/skyeye-promote/skyeye-code-doc/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-code-doc/.project b/skyeye-promote/skyeye-code-doc/.project new file mode 100644 index 0000000..42cdc33 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/.project @@ -0,0 +1,23 @@ + + + skyeye-code-doc + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-code-doc/pom.xml b/skyeye-promote/skyeye-code-doc/pom.xml new file mode 100644 index 0000000..c8ca7e8 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + + com.skyeye + skyeye-promote + 0.0.1-SNAPSHOT + + + skyeye-code-doc + skyeye-code-doc + http://maven.apache.org + + + UTF-8 + + + + + + + com.skyeye + skyeye-entity + 0.0.1-SNAPSHOT + + + + + diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelController.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelController.java new file mode 100644 index 0000000..0fb7e78 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.codedoc.model.CodeModelQueryDo; +import com.skyeye.eve.service.CodeModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CodeModelController + * @Description: 代码模板管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/6 10:03 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "代码模板管理", tags = "代码模板管理", modelName = "代码生成器") +public class CodeModelController { + + @Autowired + private CodeModelService codeModelService; + + /** + * 获取模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "codemodel006", value = "获取模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CodeModelQueryDo.class) + @RequestMapping("/post/CodeModelController/queryCodeModelList") + public void queryCodeModelList(InputObject inputObject, OutputObject outputObject) { + codeModelService.queryCodeModelList(inputObject, outputObject); + } + + /** + * 新增模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelController/insertCodeModelMation") + public void insertCodeModelMation(InputObject inputObject, OutputObject outputObject) { + codeModelService.insertCodeModelMation(inputObject, outputObject); + } + + /** + * 删除模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelController/deleteCodeModelById") + public void deleteCodeModelById(InputObject inputObject, OutputObject outputObject) { + codeModelService.deleteCodeModelById(inputObject, outputObject); + } + + /** + * 编辑模板信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelController/queryCodeModelMationToEditById") + public void queryCodeModelMationToEditById(InputObject inputObject, OutputObject outputObject) { + codeModelService.queryCodeModelMationToEditById(inputObject, outputObject); + } + + /** + * 编辑模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelController/editCodeModelMationById") + public void editCodeModelMationById(InputObject inputObject, OutputObject outputObject) { + codeModelService.editCodeModelMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelGroupController.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelGroupController.java new file mode 100644 index 0000000..cc18c41 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelGroupController.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.CodeModelGroup; +import com.skyeye.eve.service.CodeModelGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CodeModelGroupController + * @Description: 模板分组管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/6 9:46 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "模板分组", tags = "模板分组", modelName = "代码生成器") +public class CodeModelGroupController { + + @Autowired + private CodeModelGroupService codeModelGroupService; + + @ApiOperation(id = "codemodel001", value = "获取模板分组列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CodeModelGroupController/queryCodeModelGroupList") + public void queryCodeModelGroupList(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeCodeModelGroup", value = "新增/编辑模板分组", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CodeModelGroup.class) + @RequestMapping("/post/CodeModelGroupController/writeCodeModelGroup") + public void writeCodeModelGroup(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "deleteCodeModelGroupById", value = "根据id删除模板分组信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CodeModelGroupController/deleteCodeModelGroupById") + public void deleteCodeModelGroupById(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "codemodel011", value = "根据表名获取表的相关信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "tableName", name = "tableName", value = "表名", required = "required")}) + @RequestMapping("/post/CodeModelGroupController/queryTableParameterByTableName") + public void queryTableParameterByTableName(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.queryTableParameterByTableName(inputObject, outputObject); + } + + @ApiOperation(id = "codemodel012", value = "根据表名获取表的相关转换信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "tableName", name = "tableName", value = "表名", required = "required")}) + @RequestMapping("/post/CodeModelGroupController/queryTableMationByTableName") + public void queryTableMationByTableName(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.queryTableMationByTableName(inputObject, outputObject); + } + + @ApiOperation(id = "codemodel013", value = "根据分组id获取模板列表", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "groupId", name = "groupId", value = "分组id", required = "required")}) + @RequestMapping("/post/CodeModelGroupController/queryCodeModelListByGroupId") + public void queryCodeModelListByGroupId(InputObject inputObject, OutputObject outputObject) { + codeModelGroupService.queryCodeModelListByGroupId(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelHistoryController.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelHistoryController.java new file mode 100644 index 0000000..0229702 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/controller/CodeModelHistoryController.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.codedoc.history.CodeModelHistoryQueryDo; +import com.skyeye.eve.service.CodeModelHistoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CodeModelHistoryController + * @Description: 代码生成历史管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/6 10:03 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "代码生成历史", tags = "代码生成历史", modelName = "代码生成器") +public class CodeModelHistoryController { + + @Autowired + private CodeModelHistoryService codeModelHistoryService; + + /** + * 获取模板生成历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "codemodel015", value = "获取模板生成历史列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CodeModelHistoryQueryDo.class) + @RequestMapping("/post/CodeModelHistoryController/queryCodeModelHistoryList") + public void queryCodeModelHistoryList(InputObject inputObject, OutputObject outputObject) { + codeModelHistoryService.queryCodeModelHistoryList(inputObject, outputObject); + } + + /** + * 重新生成文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelHistoryController/insertCodeModelHistoryCreate") + public void insertCodeModelHistoryCreate(InputObject inputObject, OutputObject outputObject) { + codeModelHistoryService.insertCodeModelHistoryCreate(inputObject, outputObject); + } + + /** + * 下载文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CodeModelHistoryController/downloadCodeModelHistory") + public void downloadCodeModelHistory(InputObject inputObject, OutputObject outputObject) { + codeModelHistoryService.downloadCodeModelHistory(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelDao.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelDao.java new file mode 100644 index 0000000..cbe6de6 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelDao.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.codedoc.model.CodeModelQueryDo; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CodeModelDao + * @Description: 模板信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeModelDao { + + List> queryCodeModelList(CodeModelQueryDo codeModelQuery); + + Map queryCodeModelMationByName(Map map); + + int insertCodeModelMation(Map map); + + int deleteCodeModelById(Map map); + + Map queryCodeModelMationToEditById(Map map); + + Map queryCodeModelMationByIdAndName(Map map); + + int editCodeModelMationById(Map map); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelGroupDao.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelGroupDao.java new file mode 100644 index 0000000..12152d3 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelGroupDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.CodeModelGroup; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CodeModelGroupDao + * @Description: 模板分组管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeModelGroupDao extends SkyeyeBaseMapper { + + Map queryCodeModelNumById(@Param("groupId") String groupId); + + List> queryTableParameterByTableName(Map map); + + List> queryCodeModelListByGroupId(Map map); + + Map queryTableBzByTableName(Map map); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelHistoryDao.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelHistoryDao.java new file mode 100644 index 0000000..0cb015f --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/dao/CodeModelHistoryDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.codedoc.history.CodeModelHistoryQueryDo; + +import java.util.List; +import java.util.Map; + +public interface CodeModelHistoryDao { + + List> queryCodeModelHistoryList(CodeModelHistoryQueryDo codeModelHistoryQuery); + + List> queryCodeModelHistoryListByFilePath(Map map); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/entity/CodeModelGroup.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/entity/CodeModelGroup.java new file mode 100644 index 0000000..31c6add --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/entity/CodeModelGroup.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: CodeModelGroup + * @Description: 模板分组实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/9 20:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "code_model_group") +@ApiModel("模板分组实体类") +public class CodeModelGroup extends BaseGeneralInfo { + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @Property(value = "分组编码", fuzzyLike = true) + private String codeNum; + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelGroupService.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelGroupService.java new file mode 100644 index 0000000..422420d --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelGroupService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.CodeModelGroup; + +/** + * @ClassName: CodeModelGroupService + * @Description: 模板分组服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/9 20:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeModelGroupService extends SkyeyeBusinessService { + + void queryTableParameterByTableName(InputObject inputObject, OutputObject outputObject); + + void queryTableMationByTableName(InputObject inputObject, OutputObject outputObject); + + void queryCodeModelListByGroupId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelHistoryService.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelHistoryService.java new file mode 100644 index 0000000..8e8bbd3 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelHistoryService.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CodeModelHistoryService { + + void queryCodeModelHistoryList(InputObject inputObject, OutputObject outputObject); + + void insertCodeModelHistoryCreate(InputObject inputObject, OutputObject outputObject); + + void downloadCodeModelHistory(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelService.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelService.java new file mode 100644 index 0000000..55836e4 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/CodeModelService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CodeModelService { + + void queryCodeModelList(InputObject inputObject, OutputObject outputObject); + + void insertCodeModelMation(InputObject inputObject, OutputObject outputObject); + + void deleteCodeModelById(InputObject inputObject, OutputObject outputObject); + + void queryCodeModelMationToEditById(InputObject inputObject, OutputObject outputObject); + + void editCodeModelMationById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelGroupServiceImpl.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelGroupServiceImpl.java new file mode 100644 index 0000000..bb04b31 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelGroupServiceImpl.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CodeModelGroupDao; +import com.skyeye.eve.entity.CodeModelGroup; +import com.skyeye.eve.service.CodeModelGroupService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CodeModelGroupServiceImpl + * @Description: 模板分组管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "模板分组", groupName = "代码生成器") +public class CodeModelGroupServiceImpl extends SkyeyeBusinessServiceImpl implements CodeModelGroupService { + + @Autowired + private CodeModelGroupDao codeModelGroupDao; + + @Value("${jdbc.database.name}") + private String dbName; + + @Override + public void createPrepose(CodeModelGroup entity) { + entity.setCodeNum(String.valueOf(ToolUtil.card())); + } + + @Override + public void deletePreExecution(String id) { + Map bean = codeModelGroupDao.queryCodeModelNumById(id); + if (CollectionUtil.isNotEmpty(bean)) { + if (Integer.parseInt(bean.get("modelNum").toString()) > 0) { + // 该模板分组下存在模板 + throw new CustomException("该模板分组下存在模板,无法删除。"); + } + } + } + + /** + * 根据表名获取表的相关信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryTableParameterByTableName(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("dbName", dbName); + List> beans = codeModelGroupDao.queryTableParameterByTableName(map); + if (beans != null) { + beans.forEach(bean -> { + // 设置字段转Java对象字段的值 + setLowerColumnName(bean); + // 设置必填属性 + setRef(bean); + }); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + private void setRef(Map bean) { + String isNullable = bean.get("isNullable").toString(); + String ref = ""; + if ("YES".equals(isNullable)) { + ref += "required"; + } + bean.put("ref", ref); + } + + private void setLowerColumnName(Map bean) { + String columnName = bean.get("columnName").toString(); + columnName = ToolUtil.replaceUnderLineAndUpperCase(columnName); + columnName = ToolUtil.toLowerCaseFirstOne(columnName); + bean.put("lowerColumnName", columnName); + } + + /** + * 根据表名获取表的相关转换信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryTableMationByTableName(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = new HashMap<>(); + String tableName = ToolUtil.replaceUnderLineAndUpperCase(map.get("tableName").toString()); + map.put("dbName", dbName); + Map tableBz = codeModelGroupDao.queryTableBzByTableName(map); + // 表备注 + bean.put("tableBzName", tableBz.get("tableComment")); + // 将表名转化为Controller名 + bean.put("tableName", tableName); + // 表名首字母小写 + bean.put("tableFirstISlowerName", ToolUtil.toLowerCaseFirstOne(tableName)); + // 表名全部小写 + bean.put("tableISlowerName", tableName.toLowerCase()); + bean.put("currentTime", DateUtil.getTimeAndToString()); + bean.put("table", map.get("tableName").toString()); + // 包名 + bean.put("ControllerPackageName", "com.skyeye." + tableName.toLowerCase() + ".controller"); + bean.put("ServicePackageName", "com.skyeye." + tableName.toLowerCase() + ".service"); + bean.put("ServiceImplPackageName", "com.skyeye." + tableName.toLowerCase() + ".service.impl"); + bean.put("DaoPackageName", "com.skyeye." + tableName.toLowerCase() + ".dao"); + outputObject.setBean(bean); + } + + /** + * 根据分组id获取模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCodeModelListByGroupId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = codeModelGroupDao.queryCodeModelListByGroupId(map); + if (beans != null) { + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelHistoryServiceImpl.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelHistoryServiceImpl.java new file mode 100644 index 0000000..0fc970a --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelHistoryServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.eve.dao.CodeModelHistoryDao; +import com.skyeye.eve.entity.codedoc.history.CodeModelHistoryQueryDo; +import com.skyeye.eve.service.CodeModelHistoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.*; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +@Service +public class CodeModelHistoryServiceImpl implements CodeModelHistoryService { + + @Autowired + private CodeModelHistoryDao codeModelHistoryDao; + + @Value("${IMAGES_PATH}") + private String tPath; + + /** + * 获取模板生成历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCodeModelHistoryList(InputObject inputObject, OutputObject outputObject) { + CodeModelHistoryQueryDo codeModelHistoryQuery = inputObject.getParams(CodeModelHistoryQueryDo.class); + Page pages = PageHelper.startPage(codeModelHistoryQuery.getPage(), codeModelHistoryQuery.getLimit()); + List> beans = codeModelHistoryDao.queryCodeModelHistoryList(codeModelHistoryQuery); + String basePath = tPath + FileConstants.FileUploadPath.CODE_GENERATOR.getSavePath(); + for (Map bean : beans) { + File file = new File(basePath + "/" + bean.get("filePath").toString()); + if (!file.exists()) { + bean.put("isExist", "否"); + } else { + bean.put("isExist", "是"); + } + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 重新生成文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertCodeModelHistoryCreate(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String basePath = tPath + FileConstants.FileUploadPath.CODE_GENERATOR.getSavePath(); + FileUtil.createDirs(basePath); + String strZipPath = basePath + "/" + map.get("filePath").toString(); + File zipFile = new File(strZipPath); + if (zipFile.exists()) { + outputObject.setreturnMessage("该文件已存在,生成失败。"); + } else { + ZipOutputStream out = null; + try { + out = new ZipOutputStream(new FileOutputStream(strZipPath)); + byte[] buffer = new byte[1024]; + List> beans = codeModelHistoryDao.queryCodeModelHistoryListByFilePath(map); + for (Map bean : beans) { + //加入压缩包 + ByteArrayInputStream stream = new ByteArrayInputStream(bean.get("content").toString().getBytes()); + out.putNextEntry(new ZipEntry(bean.get("fileName").toString() + "." + bean.get("fileType").toString().toLowerCase())); + int len; + // 读入需要下载的文件的内容,打包到zip文件 + while ((len = stream.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + out.closeEntry(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + FileUtil.close(out); + } + } + } + + /** + * 下载文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void downloadCodeModelHistory(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String basePath = tPath + FileConstants.FileUploadPath.CODE_GENERATOR.getSavePath(); + String strZipPath = basePath + "/" + map.get("filePath").toString(); + InputStream bis = null; + BufferedOutputStream out = null; + try { + // 获取输入流 + bis = new BufferedInputStream(new FileInputStream(new File(strZipPath))); + PutObject.getResponse().setHeader("REQUESTMATION", "DOWNLOAD"); + // 转码,免得文件名中文乱码 + String filename = URLEncoder.encode(map.get("filePath").toString(), "UTF-8"); + // 设置文件下载头 + PutObject.getResponse().addHeader("Content-Disposition", "attachment;filename=" + filename); + // 1.设置文件ContentType类型,这样设置,会自动判断下载文件类型 + PutObject.getResponse().setContentType("multipart/form-data"); + out = new BufferedOutputStream(PutObject.getResponse().getOutputStream()); + int len = 0; + while ((len = bis.read()) != -1) { + out.write(len); + out.flush(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + FileUtil.close(bis); + FileUtil.close(out); + } + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelServiceImpl.java b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelServiceImpl.java new file mode 100644 index 0000000..21d8624 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/java/com/skyeye/eve/service/impl/CodeModelServiceImpl.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.dao.CodeModelDao; +import com.skyeye.eve.entity.codedoc.model.CodeModelQueryDo; +import com.skyeye.eve.service.CodeModelService; +import com.skyeye.eve.service.IAuthUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CodeModelServiceImpl + * @Description: 模板信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CodeModelServiceImpl implements CodeModelService { + + @Autowired + private CodeModelDao codeModelDao; + + @Autowired + private IAuthUserService iAuthUserService; + + /** + * 获取模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCodeModelList(InputObject inputObject, OutputObject outputObject) { + CodeModelQueryDo codeModelQuery = inputObject.getParams(CodeModelQueryDo.class); + Page pages = PageHelper.startPage(codeModelQuery.getPage(), codeModelQuery.getLimit()); + List> beans = codeModelDao.queryCodeModelList(codeModelQuery); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertCodeModelMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map checkBean = codeModelDao.queryCodeModelMationByName(map); + if (CollectionUtil.isEmpty(checkBean)) { + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + codeModelDao.insertCodeModelMation(map); + } else { + outputObject.setreturnMessage("该模板已存在,请更换。"); + } + } + + /** + * 删除模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteCodeModelById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + codeModelDao.deleteCodeModelById(map); + } + + /** + * 编辑模板信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCodeModelMationToEditById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = codeModelDao.queryCodeModelMationToEditById(map); + outputObject.setBean(bean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 编辑模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editCodeModelMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map checkBean = codeModelDao.queryCodeModelMationByIdAndName(map); + if (CollectionUtil.isEmpty(checkBean)) { + Map user = inputObject.getLogParams(); + map.put("lastUpdateId", user.get("id")); + map.put("lastUpdateTime", DateUtil.getTimeAndToString()); + codeModelDao.editCodeModelMationById(map); + } else { + outputObject.setreturnMessage("该模板已存在,请更换。"); + } + } + +} diff --git a/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelGroupMapper.xml b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelGroupMapper.xml new file mode 100644 index 0000000..38136c0 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelGroupMapper.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelHistoryMapper.xml b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelHistoryMapper.xml new file mode 100644 index 0000000..9934571 --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelHistoryMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelMapper.xml b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelMapper.xml new file mode 100644 index 0000000..f349efc --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/resources/mapper/codedoc/CodeModelMapper.xml @@ -0,0 +1,93 @@ + + + + + + + + + + INSERT into code_model + (id, group_id, model_name, model_content, model_text, model_type, + create_id, create_time, last_update_id, last_update_time) + VALUES + (#{id}, #{groupId}, #{modelName}, #{modelContent}, #{modelText}, #{modelType}, + #{createId}, #{createTime}, #{createId}, #{createTime}) + + + + DELETE + FROM + code_model + WHERE id = #{id} + + + + + + + + UPDATE code_model + + + model_name = #{modelName}, + + + model_content = #{modelContent}, + + + model_text = #{modelText}, + + model_type = #{modelType}, + last_update_id = #{lastUpdateId}, + last_update_time = #{lastUpdateTime} + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-code-doc/src/main/resources/reqmapping/mapping/codedoc.xml b/skyeye-promote/skyeye-code-doc/src/main/resources/reqmapping/mapping/codedoc.xml new file mode 100644 index 0000000..58e8ecc --- /dev/null +++ b/skyeye-promote/skyeye-code-doc/src/main/resources/reqmapping/mapping/codedoc.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/.gitignore b/skyeye-promote/skyeye-common/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-common/.project b/skyeye-promote/skyeye-common/.project new file mode 100644 index 0000000..a1d11c4 --- /dev/null +++ b/skyeye-promote/skyeye-common/.project @@ -0,0 +1,23 @@ + + + skyeye-common + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-common/pom.xml b/skyeye-promote/skyeye-common/pom.xml new file mode 100644 index 0000000..d61da2c --- /dev/null +++ b/skyeye-promote/skyeye-common/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + + skyeye-common + + skyeye-common + http://www.example.com + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + cn.hutool + hutool-all + 5.8.32 + + + io.minio + minio + 8.5.7 + + + + com.github.binarywang + weixin-java-pay + ${weixin-java.version} + + + com.github.binarywang + wx-java-mp-spring-boot-starter + ${weixin-java.version} + + + com.github.binarywang + wx-java-miniapp-spring-boot-starter + ${weixin-java.version} + + + + + diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/controller/ApplicationController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/controller/ApplicationController.java new file mode 100644 index 0000000..a1869d6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/controller/ApplicationController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.application.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.application.entity.Application; +import com.skyeye.application.service.ApplicationService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ApplicationController + * @Description: 应用管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/13 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "应用管理", tags = "应用管理", modelName = "系统公共模块") +public class ApplicationController { + + @Autowired + private ApplicationService applicationService; + + /** + * 应用注册 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "registerApplication", value = "应用注册", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = Application.class) + @RequestMapping("/post/SkyeyeClassServiceBeanController/registerApplication") + public void registerApplication(InputObject inputObject, OutputObject outputObject) { + applicationService.registerApplication(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/dao/ApplicationDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/dao/ApplicationDao.java new file mode 100644 index 0000000..b9194cc --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/dao/ApplicationDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.application.dao; + +import com.skyeye.application.entity.Application; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ApplicationDao + * @Description: 应用管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/13 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ApplicationDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/entity/Application.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/entity/Application.java new file mode 100644 index 0000000..22a6d81 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/entity/Application.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.application.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: Application + * @Description: 应用实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_application", autoResultMap = true) +@ApiModel("应用实体类") +public class Application extends CommonInfo { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField("app_id") + @ApiModelProperty(value = "应用的appId", required = "required") + private String appId; + + @TableField("app_name") + @ApiModelProperty(value = "应用名称", required = "required") + private String appName; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/ApplicationService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/ApplicationService.java new file mode 100644 index 0000000..e2ad00e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/ApplicationService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.application.service; + +import com.skyeye.application.entity.Application; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ApplicationService + * @Description: 应用管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/13 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ApplicationService extends SkyeyeBusinessService { + + void registerApplication(InputObject inputObject, OutputObject outputObject); + + List> queryApplicationList(); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/impl/ApplicationServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/impl/ApplicationServiceImpl.java new file mode 100644 index 0000000..e4acad3 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/application/service/impl/ApplicationServiceImpl.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.application.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.application.dao.ApplicationDao; +import com.skyeye.application.entity.Application; +import com.skyeye.application.service.ApplicationService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ApplicationServiceImpl + * @Description: 应用管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/13 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ApplicationServiceImpl extends SkyeyeBusinessServiceImpl implements ApplicationService { + + /** + * 应用注册 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void registerApplication(InputObject inputObject, OutputObject outputObject) { + Application application = inputObject.getParams(Application.class); + + // 根据appId删除之前注册的 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(Application::getAppId), application.getAppId()); + remove(wrapper); + + // 新增 + createEntity(application, StrUtil.EMPTY); + } + + @Override + public List> queryApplicationList() { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(Application::getAppId)); + List applicationList = super.list(wrapper); + if (CollectionUtil.isEmpty(applicationList)) { + return new ArrayList<>(); + } + return applicationList.stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/Alignment.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/Alignment.java new file mode 100644 index 0000000..492755b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/Alignment.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: Alignment + * @Description: 对齐方式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum Alignment implements SkyeyeEnumClass { + LEFT("left", "左对齐", true, true), + CENTER("center", "居中对齐", true, false), + RIGHT("right", "右对齐", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/AttrKeyDataType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/AttrKeyDataType.java new file mode 100644 index 0000000..d8d9884 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/AttrKeyDataType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AttrKeyDataType + * @Description: 属性关联的数据类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/23 15:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AttrKeyDataType implements SkyeyeEnumClass { + + CUSTOM(1, "自定义JSON串", true, false), + ENUM_DATA(2, "枚举类型", true, false), + DICT_DATA(3, "数据字典类型", true, false), + CUSTOM_API(4, "自定义API", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/ButtonColorType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/ButtonColorType.java new file mode 100644 index 0000000..576baa0 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/ButtonColorType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ButtonColorType + * @Description: 操作按钮颜色枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ButtonColorType implements SkyeyeEnumClass { + + PRIMARY("layui-btn-primary", "原始", true, false), + DEFAULT("default", "默认", true, false), + NORMAL("layui-btn-normal", "百搭", true, true), + WARM("layui-btn-warm", "暖色", true, false), + DANGER("layui-btn-danger", "警告", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/DsFormShowType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/DsFormShowType.java new file mode 100644 index 0000000..f659662 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/DsFormShowType.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DsFormShowType + * @Description: 组件展示类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DsFormShowType implements SkyeyeEnumClass { + + CUSTOMER(-1, "自定义", true, false), + TEXT(1, "文本展示", true, false), + ENCLOSURE(2, "附件展示", true, false), + RICH_TEXT(3, "富文本展示", true, false), + PICTURE(4, "图片展示", true, false), + TABLE(5, "表格展示", true, false), + VOUCHER(6, "凭证展示", true, false), + SCRIPT(7, "脚本展示", true, false), + ID_TURN_MATION(8, "Id转Mation取值转换", true, false), + ERP_SKU(9, "ERP商品规格", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/WidthScale.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/WidthScale.java new file mode 100644 index 0000000..d417021 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/classenum/WidthScale.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: WidthScale + * @Description: 宽度比例枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum WidthScale implements SkyeyeEnumClass { + ONE("layui-col-xs12", "整行铺满", true, true), + THREE_FOURTHS("layui-col-xs9", "四分之三", true, false), + A_HALF("layui-col-xs6", "二分之一", true, false), + ONE_THIRD("layui-col-xs4", "三分之一", true, false), + QUARTER("layui-col-xs3", "四分之一", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionController.java new file mode 100644 index 0000000..97ac628 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionController.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.attr.service.AttrDefinitionService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AttrDefinitionController + * @Description: 服务类属性管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "属性管理", tags = "属性管理", modelName = "系统公共模块") +public class AttrDefinitionController { + + @Autowired + private AttrDefinitionService attrDefinitionService; + + /** + * 根据service的className获取属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAttrDefinitionList", value = "根据service的className获取属性信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required")}) + @RequestMapping("/post/AttrDefinitionController/queryAttrDefinitionList") + public void queryAttrDefinitionList(InputObject inputObject, OutputObject outputObject) { + attrDefinitionService.queryAttrDefinitionList(inputObject, outputObject); + } + + /** + * 获取子属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryChildAttrDefinitionList", value = "获取子属性信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "attrKey", name = "attrKey", value = "属性", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required")}) + @RequestMapping("/post/AttrDefinitionController/queryChildAttrDefinitionList") + public void queryChildAttrDefinitionList(InputObject inputObject, OutputObject outputObject) { + attrDefinitionService.queryChildAttrDefinitionList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionCustomController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionCustomController.java new file mode 100644 index 0000000..ef8e335 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/controller/AttrDefinitionCustomController.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.attr.entity.AttrDefinitionCustom; +import com.skyeye.attr.service.AttrDefinitionCustomService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AttrDefinitionCustomController + * @Description: 用户自定义服务类属性控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/30 11:01 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "自定义属性管理", tags = "自定义属性管理", modelName = "系统公共模块") +public class AttrDefinitionCustomController { + + @Autowired + private AttrDefinitionCustomService attrDefinitionCustomService; + + /** + * 获取属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAttrDefinitionCustom", value = "获取属性信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "attrKey", name = "attrKey", value = "属性", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required")}) + @RequestMapping("/post/AttrDefinitionCustomController/queryAttrDefinitionCustom") + public void queryAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject) { + attrDefinitionCustomService.queryAttrDefinitionCustom(inputObject, outputObject); + } + + /** + * 保存自定义属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "saveAttrDefinitionCustom", value = "保存自定义属性信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AttrDefinitionCustom.class) + @RequestMapping("/post/AttrDefinitionCustomController/saveAttrDefinitionCustom") + public void saveAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject) { + attrDefinitionCustomService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除自定义属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAttrDefinitionCustom", value = "删除自定义属性信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "attrKey", name = "attrKey", value = "属性", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required")}) + @RequestMapping("/post/AttrDefinitionCustomController/deleteAttrDefinitionCustom") + public void deleteAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject) { + attrDefinitionCustomService.deleteAttrDefinitionCustom(inputObject, outputObject); + } + + /** + * 根据组件id查询正在使用该组件的服务类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAttrByComponentId", value = "根据组件id查询正在使用该组件的服务类信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "componentId", name = "componentId", value = "组件id", required = "required")}) + @RequestMapping("/post/AttrDefinitionCustomController/queryAttrByComponentId") + public void queryAttrByComponentId(InputObject inputObject, OutputObject outputObject) { + attrDefinitionCustomService.queryAttrByComponentId(inputObject, outputObject); + } + + /** + * 根据id删除自定义属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAttrDefinitionCustomById", value = "根据id删除自定义属性信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AttrDefinitionCustomController/deleteAttrDefinitionCustomById") + public void deleteAttrDefinitionCustomById(InputObject inputObject, OutputObject outputObject) { + attrDefinitionCustomService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionCustomDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionCustomDao.java new file mode 100644 index 0000000..4e36a83 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionCustomDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.dao; + +import com.skyeye.attr.entity.AttrDefinitionCustom; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AttrDefinitionCustomDao + * @Description: 用户自定义服务类属性数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/30 10:55 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AttrDefinitionCustomDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionDao.java new file mode 100644 index 0000000..88810b8 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/dao/AttrDefinitionDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.dao; + +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: AttrDefinitionDao + * @Description: 服务类属性管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AttrDefinitionDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinition.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinition.java new file mode 100644 index 0000000..bc48a7c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinition.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: AttrDefinition + * @Description: 服务类属性实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_attr_definition", autoResultMap = true) +@ApiModel("服务类属性实体类") +public class AttrDefinition extends CommonInfo { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField(exist = false) + @Property("自定义属性信息") + private AttrDefinitionCustom attrDefinitionCustom; + + /** + * 应用的APPID + */ + @TableField("app_id") + private String appId; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField("attr_key") + @ApiModelProperty(value = "字段名", required = "required") + private String attrKey; + + @TableField("attr_type") + @ApiModelProperty(value = "字段类型", required = "required") + private String attrType; + + @TableField("`name`") + @ApiModelProperty(value = "属性名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "属性描述") + private String remark; + + @TableField("whether_input_params") + @ApiModelProperty(value = "是否可以作为入参", required = "required") + private Boolean whetherInputParams; + + @TableField("required") + @ApiModelProperty(value = "属性限制条件") + private String required; + + @TableField("model_attribute") + @ApiModelProperty(value = "是否是模型属性", required = "required") + private Boolean modelAttribute; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinitionCustom.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinitionCustom.java new file mode 100644 index 0000000..67bcbd2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/entity/AttrDefinitionCustom.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.server.entity.ServiceBean; +import lombok.Data; + +/** + * @ClassName: AttrDefinitionCustom + * @Description: 用户自定义服务类属性实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"className", "attrKey"}) +@TableName(value = "skyeye_attr_definition_custom", autoResultMap = true) +@ApiModel("用户自定义服务类属性实体类") +public class AttrDefinitionCustom extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("app_id") + @ApiModelProperty(value = "应用的appId", required = "required") + private String appId; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField(exist = false) + @Property(value = "服务类信息") + private ServiceBean serviceBean; + + @TableField("attr_key") + @ApiModelProperty(value = "字段名", required = "required") + private String attrKey; + + @TableField("`name`") + @ApiModelProperty(value = "属性名称", required = "required") + private String name; + + @TableField("component_id") + @ApiModelProperty(value = "组件id") + private String componentId; + + @TableField(exist = false) + @Property(value = "自定义属性关联的组件") + private DsFormComponent dsFormComponent; + + @TableField("min_length") + @ApiModelProperty(value = "最小长度") + private Integer minLength; + + @TableField("max_length") + @ApiModelProperty(value = "最大长度") + private Integer maxLength; + + @TableField("remark") + @ApiModelProperty(value = "属性描述") + private String remark; + + @TableField(exist = false) + @Property(value = "是否可以作为入参,数据来源:属性原始信息") + private Boolean whetherInputParams; + + @TableField(value = "data_type", updateStrategy = FieldStrategy.IGNORED) + @ApiModelProperty(value = "数据类型,参考#AttrKeyDataType", required = "num") + private Integer dataType; + + @TableField("default_data") + @ApiModelProperty(value = "数据类型为1时,默认数据,需要是json字符串", required = "json") + private String defaultData; + + @TableField("object_id") + @ApiModelProperty(value = "数据类型为其他时,数据的id") + private String objectId; + + @TableField(exist = false) + @ApiModelProperty(value = "dataType=4时,自定义api接口的请求", required = "json") + private BusinessApi businessApi; + + @TableField(exist = false) + @Property(value = "是否可以删除") + private Boolean whetherDelete; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionCustomService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionCustomService.java new file mode 100644 index 0000000..9935d0e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionCustomService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.service; + +import com.skyeye.attr.entity.AttrDefinitionCustom; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AttrDefinitionCustomService + * @Description: 用户自定义服务类属性服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/30 10:56 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AttrDefinitionCustomService extends SkyeyeBusinessService { + + List queryAttrDefinitionCustomList(String appId, String className, List attrKey); + + Map queryAttrDefinitionCustomMap(String appId, String className, List attrKey); + + AttrDefinitionCustom queryAttrDefinitionCustom(String appId, String className, String attrKey); + + void queryAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject); + + void deleteAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject); + + void setDsFormComponentUseNum(List> beans); + + void queryAttrByComponentId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionService.java new file mode 100644 index 0000000..0e03a7b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/AttrDefinitionService.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.service; + +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AttrDefinitionService + * @Description: 服务类属性管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AttrDefinitionService extends SkyeyeBusinessService { + + /** + * 系统启动时,批量扫描业务对象属性入库 + * + * @param appId + * @param attrDefinitionList + */ + void saveBarchAttrDefinition(String appId, List attrDefinitionList); + + void queryAttrDefinitionList(InputObject inputObject, OutputObject outputObject); + + void queryChildAttrDefinitionList(InputObject inputObject, OutputObject outputObject); + + /** + * 批量获取业务对象指定的属性信息 + * + * @param className + * @param attrKey + * @return + */ + List queryAttrDefinitionList(String appId, String className, List attrKey); + + Map queryAttrDefinitionMap(String appId, String className, List attrKey); + + AttrDefinition queryAttrDefinition(String appId, String className, String attrKey); + + Map> queryAttrDefinitionList(List classNameList); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionCustomServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionCustomServiceImpl.java new file mode 100644 index 0000000..b543ee6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionCustomServiceImpl.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.attr.classenum.AttrKeyDataType; +import com.skyeye.attr.dao.AttrDefinitionCustomDao; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.attr.entity.AttrDefinitionCustom; +import com.skyeye.attr.service.AttrDefinitionCustomService; +import com.skyeye.attr.service.AttrDefinitionService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.business.service.BusinessApiService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.dsform.service.DsFormComponentService; +import com.skyeye.server.entity.ServiceBean; +import com.skyeye.server.service.ServiceBeanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AttrDefinitionCustomServiceImpl + * @Description: 用户自定义服务类属性服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/12/30 10:57 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class AttrDefinitionCustomServiceImpl extends SkyeyeBusinessServiceImpl implements AttrDefinitionCustomService { + + @Autowired + private AttrDefinitionService attrDefinitionService; + + @Autowired + private DsFormComponentService dsFormComponentService; + + @Autowired + private BusinessApiService businessApiService; + + @Autowired + private ServiceBeanService serviceBeanService; + + @Override + public void writePostpose(AttrDefinitionCustom entity, String userId) { + super.writePostpose(entity, userId); + businessApiService.deleteByObjectId(entity.getId()); + if (entity.getDataType() != null && entity.getDataType().equals(AttrKeyDataType.CUSTOM_API.getKey())) { + // 保存属性关联的自定义的api接口 + BusinessApi businessApi = entity.getBusinessApi(); + businessApi.setObjectId(entity.getId()); + businessApi.setObjectKey(getServiceClassName()); + businessApiService.createEntity(businessApi, userId); + } + } + + @Override + public List queryAttrDefinitionCustomList(String appId, String className, List attrKey) { + if (CollectionUtil.isEmpty(attrKey)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getClassName), className); + wrapper.in(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getAttrKey), attrKey); + List attrDefinitionCustomList = list(wrapper); + // 获取关联的组件信息 + List componentIdList = attrDefinitionCustomList.stream() + .filter(attrDefinitionCustom -> StrUtil.isNotEmpty(attrDefinitionCustom.getComponentId())) + .map(AttrDefinitionCustom::getComponentId).distinct().collect(Collectors.toList()); + Map componentMap = dsFormComponentService.selectMapByIds(componentIdList); + attrDefinitionCustomList.forEach(attrDefinitionCustom -> { + if (StrUtil.isNotEmpty(attrDefinitionCustom.getComponentId())) { + attrDefinitionCustom.setDsFormComponent(componentMap.get(attrDefinitionCustom.getComponentId())); + } + }); + // 查询属性关联的自定义的api接口 + List ids = attrDefinitionCustomList.stream() + .filter(bean -> bean.getDataType() != null && bean.getDataType().equals(AttrKeyDataType.CUSTOM_API.getKey())) + .map(AttrDefinitionCustom::getId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ids)) { + Map businessApiMap = businessApiService.selectByObjectIds(ids); + attrDefinitionCustomList.forEach(attrDefinitionCustom -> { + if (attrDefinitionCustom.getDataType() != null && attrDefinitionCustom.getDataType().equals(AttrKeyDataType.CUSTOM_API.getKey())) { + attrDefinitionCustom.setBusinessApi(businessApiMap.get(attrDefinitionCustom.getId())); + } + }); + } + return attrDefinitionCustomList; + } + + @Override + public Map queryAttrDefinitionCustomMap(String appId, String className, List attrKey) { + List attrDefinitionCustomList = queryAttrDefinitionCustomList(appId, className, attrKey); + return attrDefinitionCustomList.stream().collect(Collectors.toMap(AttrDefinitionCustom::getAttrKey, item -> item)); + } + + @Override + public AttrDefinitionCustom queryAttrDefinitionCustom(String appId, String className, String attrKey) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getClassName), className); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getAttrKey), attrKey); + AttrDefinitionCustom attrDefinitionCustom = getOne(wrapper); + if (ObjectUtil.isNotEmpty(attrDefinitionCustom) && StrUtil.isNotEmpty(attrDefinitionCustom.getComponentId())) { + // 查询组件信息 + DsFormComponent dsFormComponent = dsFormComponentService.selectById(attrDefinitionCustom.getComponentId()); + attrDefinitionCustom.setDsFormComponent(dsFormComponent); + // 查询属性关联的自定义的api接口 + if (attrDefinitionCustom.getDataType() != null && attrDefinitionCustom.getDataType().equals(AttrKeyDataType.CUSTOM_API.getKey())) { + attrDefinitionCustom.setBusinessApi(businessApiService.selectByObjectId(attrDefinitionCustom.getId())); + } + } + return attrDefinitionCustom; + } + + @Override + public void queryAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String attrKey = params.get("attrKey").toString(); + String appId = params.get("appId").toString(); + // 获取属性的原始信息 + AttrDefinition attrDefinition = attrDefinitionService.queryAttrDefinition(appId, className, attrKey); + // 获取属性的自定义信息 + AttrDefinitionCustom attrDefinitionCustom = queryAttrDefinitionCustom(appId, className, attrKey); + if (ObjectUtil.isEmpty(attrDefinitionCustom)) { + attrDefinitionCustom = new AttrDefinitionCustom(); + attrDefinitionCustom.setName(attrDefinition.getName()); + attrDefinitionCustom.setRemark(attrDefinition.getRemark()); + attrDefinitionCustom.setAttrKey(attrDefinition.getAttrKey()); + } + attrDefinitionCustom.setWhetherInputParams(attrDefinition.getWhetherInputParams()); + outputObject.setBean(attrDefinitionCustom); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 删除自定义属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteAttrDefinitionCustom(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String attrKey = params.get("attrKey").toString(); + String appId = params.get("appId").toString(); + + AttrDefinitionCustom attrDefinitionCustom = queryAttrDefinitionCustom(appId, className, attrKey); + if (ObjectUtil.isEmpty(attrDefinitionCustom)) { + return; + } + // 删除属性关联的自定义的api接口 + if (attrDefinitionCustom.getDataType() != null && attrDefinitionCustom.getDataType().equals(AttrKeyDataType.CUSTOM_API.getKey())) { + businessApiService.deleteByObjectId(attrDefinitionCustom.getId()); + } + removeById(attrDefinitionCustom.getId()); + } + + @Override + public void setDsFormComponentUseNum(List> beans) { + List dsFormComponentId = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(dsFormComponentId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getComponentId), dsFormComponentId); + queryWrapper.select(CommonConstants.ID, MybatisPlusUtil.toColumns(AttrDefinitionCustom::getComponentId)); + List list = list(queryWrapper); + Map collect = list.stream().collect(Collectors.groupingBy(AttrDefinitionCustom::getComponentId, Collectors.counting())); + beans.forEach(bean -> { + String id = bean.get("id").toString(); + bean.put("attrUseNum", collect.get(id)); + }); + } + + /** + * 根据组件id查询正在使用该组件的服务类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAttrByComponentId(InputObject inputObject, OutputObject outputObject) { + String componentId = inputObject.getParams().get("componentId").toString(); + if (StrUtil.isEmpty(componentId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AttrDefinitionCustom::getComponentId), componentId); + List attrDefinitionCustoms = list(queryWrapper); + List classNames = attrDefinitionCustoms.stream().map(bean -> bean.getAppId() + bean.getClassName()).collect(Collectors.toList()); + // 查询服务类信息 + Map serviceBeanMap = serviceBeanService.queryServiceClass(classNames); + attrDefinitionCustoms.forEach(attrDefinitionCustom -> { + String className = attrDefinitionCustom.getAppId() + attrDefinitionCustom.getClassName(); + ServiceBean serviceBean = serviceBeanMap.get(className); + if (ObjectUtil.isEmpty(serviceBean)) { + attrDefinitionCustom.setWhetherDelete(true); + return; + } + // 判断属性是否在服务类的原始属性中,如果不在,则说明该自定义属性可以删除 + List attrKeyList = serviceBean.getAttrDefinitionList().stream().map(AttrDefinition::getAttrKey) + .distinct().collect(Collectors.toList()); + if (attrKeyList.contains(attrDefinitionCustom.getAttrKey())) { + attrDefinitionCustom.setWhetherDelete(false); + } else { + attrDefinitionCustom.setWhetherDelete(true); + } + attrDefinitionCustom.setServiceBean(serviceBean); + }); + outputObject.setBeans(attrDefinitionCustoms); + outputObject.settotal(attrDefinitionCustoms.size()); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionServiceImpl.java new file mode 100644 index 0000000..a332608 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/attr/service/impl/AttrDefinitionServiceImpl.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.attr.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.attr.dao.AttrDefinitionDao; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.attr.entity.AttrDefinitionCustom; +import com.skyeye.attr.service.AttrDefinitionCustomService; +import com.skyeye.attr.service.AttrDefinitionService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.server.entity.ServiceBean; +import com.skyeye.server.service.ServiceBeanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AttrDefinitionServiceImpl + * @Description: 服务类属性管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class AttrDefinitionServiceImpl extends SkyeyeBusinessServiceImpl implements AttrDefinitionService { + + @Autowired + private ServiceBeanService skyeyeClassServiceBeanService; + + @Autowired + private AttrDefinitionCustomService attrDefinitionCustomService; + + /** + * 系统启动时,批量扫描业务对象属性入库 + * + * @param appId + * @param attrDefinitionList + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void saveBarchAttrDefinition(String appId, List attrDefinitionList) { + // 获取数据库中的数据 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getModelAttribute), true); + List oldList = super.list(wrapper); + List oldKeys = oldList.stream().map(bean -> getKey(bean)).collect(Collectors.toList()); + + List newKeys = attrDefinitionList.stream().map(bean -> getKey(bean)).collect(Collectors.toList()); + + // (旧数据 - 新数据) 从数据库删除 + List deleteBeans = oldList.stream() + .filter(item -> !newKeys.contains(getKey(item))).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(deleteBeans)) { + List ids = deleteBeans.stream().map(AttrDefinition::getId).collect(Collectors.toList()); + deleteById(ids); + } + + // (新数据 - 旧数据) 添加到数据库 + List addBeans = attrDefinitionList.stream() + .filter(item -> !oldKeys.contains(getKey(item))).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(addBeans)) { + addBeans.forEach(attrDefinition -> { + attrDefinition.setAppId(appId); + attrDefinition.setModelAttribute(true); + }); + // 新增模型属性 + createEntity(addBeans, StrUtil.EMPTY); + } + + // 新数据与旧数据取交集 编辑 + List editBeans = oldList.stream() + .filter(item -> newKeys.contains(getKey(item))).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(editBeans)) { + Map collect = attrDefinitionList.stream().collect(Collectors.toMap(bean -> getKey(bean), item -> item)); + if (CollectionUtil.isEmpty(collect)) { + return; + } + editBeans.forEach(bean -> { + String key = getKey(bean); + AttrDefinition attrDefinition = collect.get(key); + if (attrDefinition == null) { + return; + } + bean.setRemark(attrDefinition.getRemark()); + bean.setRequired(attrDefinition.getRequired()); + bean.setWhetherInputParams(attrDefinition.getWhetherInputParams()); + }); + updateEntity(editBeans, StrUtil.EMPTY); + } + } + + private String getKey(AttrDefinition attrDefinition) { + return String.format(Locale.ROOT, "%s:%s", attrDefinition.getClassName(), attrDefinition.getAttrKey()); + } + + /** + * 根据service的className获取属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAttrDefinitionList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String appId = params.get("appId").toString(); + List attrDefinitionList = getAttrDefinitions(appId, className); + setCustomDefinition(appId, className, attrDefinitionList); + + attrDefinitionList = attrDefinitionList.stream() + .sorted(Comparator.comparing(AttrDefinition::getWhetherInputParams, Comparator.reverseOrder())).collect(Collectors.toList()); + outputObject.setBeans(attrDefinitionList); + outputObject.settotal(attrDefinitionList.size()); + } + + private void setCustomDefinition(String appId, String className, List attrDefinitionList) { + // 获取自定义属性id + List attrKey = attrDefinitionList.stream().map(AttrDefinition::getAttrKey).collect(Collectors.toList()); + Map attrDefinitionCustomMap = attrDefinitionCustomService.queryAttrDefinitionCustomMap(appId, className, attrKey); + attrDefinitionList.forEach(attrDefinition -> { + AttrDefinitionCustom attrDefinitionCustom = attrDefinitionCustomMap.get(attrDefinition.getAttrKey()); + attrDefinition.setAttrDefinitionCustom(attrDefinitionCustom); + }); + } + + private List getAttrDefinitions(String appId, String className) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getClassName), className); + List attrDefinitionList = list(wrapper); + return attrDefinitionList; + } + + /** + * 获取子属性信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryChildAttrDefinitionList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String attrKey = params.get("attrKey").toString(); + String appId = params.get("appId").toString(); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getClassName), className); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAttrKey), attrKey); + AttrDefinition attrDefinition = getOne(wrapper); + if (attrDefinition == null) { + return; + } + + ServiceBean service = skyeyeClassServiceBeanService.getByEntityClassName(attrDefinition.getAttrType()); + if (service == null) { + return; + } + List attrDefinitionList = getAttrDefinitions(appId, service.getClassName()); + setCustomDefinition(appId, service.getClassName(), attrDefinitionList); + outputObject.setBeans(attrDefinitionList); + outputObject.settotal(attrDefinitionList.size()); + } + + /** + * 批量获取业务对象指定的属性信息 + * + * @param className + * @param attrKey + * @return + */ + @Override + public List queryAttrDefinitionList(String appId, String className, List attrKey) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getClassName), className); + wrapper.in(MybatisPlusUtil.toColumns(AttrDefinition::getAttrKey), attrKey); + List attrDefinitionList = list(wrapper); + setCustomDefinition(appId, className, attrDefinitionList); + return attrDefinitionList; + } + + /** + * 批量获取业务对象指定的属性信息 + * + * @param className + * @param attrKey + * @return + */ + @Override + public Map queryAttrDefinitionMap(String appId, String className, List attrKey) { + List attrDefinitionList = queryAttrDefinitionList(appId, className, attrKey); + return attrDefinitionList.stream().collect(Collectors.toMap(AttrDefinition::getAttrKey, item -> item)); + } + + /** + * 获取属性信息 + * + * @param className + * @param attrKey + * @return + */ + @Override + public AttrDefinition queryAttrDefinition(String appId, String className, String attrKey) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAppId), appId); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getClassName), className); + wrapper.eq(MybatisPlusUtil.toColumns(AttrDefinition::getAttrKey), attrKey); + AttrDefinition attrDefinition = getOne(wrapper); + setCustomDefinition(appId, className, attrDefinition); + return attrDefinition; + } + + private void setCustomDefinition(String appId, String className, AttrDefinition attrDefinition) { + // 获取自定义属性id + AttrDefinitionCustom attrDefinitionCustom = attrDefinitionCustomService.queryAttrDefinitionCustom(appId, className, attrDefinition.getAttrKey()); + attrDefinition.setAttrDefinitionCustom(attrDefinitionCustom); + } + + @Override + public Map> queryAttrDefinitionList(List classNameList) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.in("CONCAT(" + MybatisPlusUtil.toColumns(AttrDefinition::getAppId) + ", " + MybatisPlusUtil.toColumns(AttrDefinition::getClassName) + ")", classNameList); + List list = list(wrapper); + Map> map = list.stream().collect(Collectors.groupingBy(AttrDefinition::getClassName)); + return map; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/dao/BusinessApiDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/dao/BusinessApiDao.java new file mode 100644 index 0000000..b17b610 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/dao/BusinessApiDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.business.entity.BusinessApi; + +/** + * @ClassName: BusinessApiDao + * @Description: 业务对象对应的接口信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BusinessApiDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/entity/BusinessApi.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/entity/BusinessApi.java new file mode 100644 index 0000000..36be009 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/entity/BusinessApi.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: BusinessApi + * @Description: 业务对象对应的接口信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_business_api", autoResultMap = true) +@ApiModel("业务对象对应的接口信息实体类") +public class BusinessApi extends OperatorUserInfo { + + @TableId("id") + @Property(value = "主键id") + private String id; + + @TableField("object_id") + @Property(value = "业务对象的id") + private String objectId; + + @TableField("object_key") + @Property(value = "业务对象的key") + private String objectKey; + + @TableField("service_str") + @ApiModelProperty(value = "接口对应的服务,由前端进行配置,方便前端解析", required = "required") + private String serviceStr; + + @TableField("api") + @ApiModelProperty(value = "接口地址", required = "required") + private String api; + + @TableField("method") + @ApiModelProperty(value = "请求方式", required = "required") + private String method; + + @TableField(value = "params", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "请求参数,数据格式:{入参key: 需要解析的属性key}", required = "json") + private Map params; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/BusinessApiService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/BusinessApiService.java new file mode 100644 index 0000000..17abcb1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/BusinessApiService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.business.entity.BusinessApi; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: BusinessApiService + * @Description: 业务对象对应的接口信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BusinessApiService extends SkyeyeBusinessService { + + void deleteByObjectId(String objectId); + + BusinessApi selectByObjectId(String objectId); + + Map selectByObjectIds(List objectIds); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/impl/BusinessApiServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/impl/BusinessApiServiceImpl.java new file mode 100644 index 0000000..ac0fb6f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/business/service/impl/BusinessApiServiceImpl.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.business.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.business.dao.BusinessApiDao; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.business.service.BusinessApiService; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: BusinessApiServiceImpl + * @Description: 业务对象对应的接口信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class BusinessApiServiceImpl extends SkyeyeBusinessServiceImpl implements BusinessApiService { + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = {Exception.class}) + public String createEntity(BusinessApi entity, String userId) { + if (StrUtil.isEmpty(entity.getObjectId())) { + throw new CustomException("关联信息id为空,请确认."); + } + deleteByObjectId(entity.getObjectId()); + return super.createEntity(entity, userId); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = {Exception.class}) + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BusinessApi::getObjectId), objectId); + remove(queryWrapper); + } + + @Override + public BusinessApi selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BusinessApi::getObjectId), objectId); + return getOne(queryWrapper); + } + + @Override + public Map selectByObjectIds(List objectIds) { + if (CollectionUtil.isEmpty(objectIds)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(BusinessApi::getObjectId), objectIds); + List businessApiList = list(queryWrapper); + return businessApiList.stream().collect(Collectors.toMap(BusinessApi::getObjectId, bean -> bean)); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/controller/SkyeyeClassEnumController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/controller/SkyeyeClassEnumController.java new file mode 100644 index 0000000..f7d7706 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/controller/SkyeyeClassEnumController.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.clazz.entity.classenum.SkyeyeClassEnumApiMation; +import com.skyeye.clazz.service.SkyeyeClassEnumService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SkyeyeClassEnumController + * @Description: 基本框架---具备某个特征的枚举类管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 19:50 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "枚举类管理", tags = "枚举类管理", modelName = "系统公共模块") +public class SkyeyeClassEnumController { + + @Autowired + private SkyeyeClassEnumService skyeyeClassEnumService; + + /** + * 批量新增枚举类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeClassEnum", value = "批量新增枚举类", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = SkyeyeClassEnumApiMation.class) + @RequestMapping("/post/SkyeyeClassEnumController/writeClassEnum") + public void writeClassEnum(InputObject inputObject, OutputObject outputObject) { + skyeyeClassEnumService.writeClassEnum(inputObject, outputObject); + } + + /** + * 根据className获取可以展示在界面上的枚举数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getEnumDataByClassName", value = "根据className获取可以展示在界面上的枚举数据信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "className", required = "required"), + @ApiImplicitParam(id = "filterKey", name = "filterKey", value = "指定需要匹配的key"), + @ApiImplicitParam(id = "filterValue", name = "filterValue", value = "需要过滤出来的指定的枚举数据,多个逗号隔开")}) + @RequestMapping("/post/SkyeyeClassEnumController/getEnumDataByClassName") + public void getEnumDataByClassName(InputObject inputObject, OutputObject outputObject) { + skyeyeClassEnumService.getEnumDataByClassName(inputObject, outputObject); + } + + /** + * 根据className获取可以展示在界面上的枚举数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getEnumDataMapByClassName", value = "根据className获取可以展示在界面上的枚举数据信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "classNameList", name = "classNameList", value = "className的集合", required = "required")}) + @RequestMapping("/post/SkyeyeClassEnumController/getEnumDataMapByClassName") + public void getEnumDataMapByClassName(InputObject inputObject, OutputObject outputObject) { + skyeyeClassEnumService.getEnumDataMapByClassName(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/dao/SkyeyeClassEnumDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/dao/SkyeyeClassEnumDao.java new file mode 100644 index 0000000..7ea002b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/dao/SkyeyeClassEnumDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.clazz.entity.classenum.SkyeyeClassEnumMation; + +/** + * @ClassName: SkyeyeClassEnumDao + * @Description: 基本框架---具备某个特征的枚举类管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 19:51 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SkyeyeClassEnumDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumApiMation.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumApiMation.java new file mode 100644 index 0000000..a77bc58 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumApiMation.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.entity.classenum; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SkyeyeClassEnumApiMation + * @Description: 具备某个特征的枚举类表对应的实体类BOX + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 23:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("具备某个特征的枚举类表对应的实体类BOX") +public class SkyeyeClassEnumApiMation implements Serializable { + + /** + * 服务的APPID + */ + @ApiModelProperty(value = "服务的APPID", required = "required") + private String appId; + + /** + * 枚举信息 + */ + @ApiModelProperty(value = "枚举信息", required = "required") + private Map>> valueList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumMation.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumMation.java new file mode 100644 index 0000000..947932b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/entity/classenum/SkyeyeClassEnumMation.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.entity.classenum; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SkyeyeClassEnumMation + * @Description: 具备某个特征的枚举类表对应的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 23:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName(value = "skyeye_class_enum", autoResultMap = true) +@ApiModel("具备某个特征的枚举类表对应的实体类") +public class SkyeyeClassEnumMation extends OperatorUserInfo implements Serializable { + + @TableId("id") + @Property("主键id") + private String id; + + /** + * 服务的APPID + */ + @TableField("app_id") + private String appId; + + /** + * 枚举类的className + */ + @TableField("class_name") + private String className; + + /** + * 枚举对应的值 + */ + @TableField(value = "value_list", typeHandler = JacksonTypeHandler.class) + private List> valueList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/SkyeyeClassEnumService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/SkyeyeClassEnumService.java new file mode 100644 index 0000000..36186f4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/SkyeyeClassEnumService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.skyeye.clazz.entity.classenum.SkyeyeClassEnumMation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SkyeyeClassEnumService + * @Description: 基本框架---具备某个特征的枚举类管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 19:52 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SkyeyeClassEnumService extends IService { + + void writeClassEnum(InputObject inputObject, OutputObject outputObject); + + void getEnumDataByClassName(InputObject inputObject, OutputObject outputObject); + + List> queryEnumDataList(String className, String filterKey, String filterValue); + + void getEnumDataMapByClassName(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/impl/SkyeyeClassEnumServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/impl/SkyeyeClassEnumServiceImpl.java new file mode 100644 index 0000000..cc679a7 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/clazz/service/impl/SkyeyeClassEnumServiceImpl.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.clazz.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.skyeye.clazz.dao.SkyeyeClassEnumDao; +import com.skyeye.clazz.entity.classenum.SkyeyeClassEnumApiMation; +import com.skyeye.clazz.entity.classenum.SkyeyeClassEnumMation; +import com.skyeye.clazz.service.SkyeyeClassEnumService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SkyeyeClassEnumServiceImpl + * @Description: 基本框架---具备某个特征的枚举类管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/11 20:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SkyeyeClassEnumServiceImpl extends ServiceImpl implements SkyeyeClassEnumService { + + @Autowired + private SkyeyeClassEnumDao skyeyeClassEnumDao; + + /** + * 批量新增枚举类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void writeClassEnum(InputObject inputObject, OutputObject outputObject) { + SkyeyeClassEnumApiMation skyeyeClassEnumApiMation = inputObject.getParams(SkyeyeClassEnumApiMation.class); + + // 根据服务名删除枚举信息 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(SkyeyeClassEnumMation::getAppId), skyeyeClassEnumApiMation.getAppId()); + remove(wrapper); + + // 解析数据并添加 + List skyeyeClassEnumMationList = new ArrayList<>(); + skyeyeClassEnumApiMation.getValueList().forEach((className, enumDto) -> { + SkyeyeClassEnumMation skyeyeClassEnumMation = new SkyeyeClassEnumMation(); + skyeyeClassEnumMation.setClassName(className); + skyeyeClassEnumMation.setValueList(enumDto); + skyeyeClassEnumMation.setAppId(skyeyeClassEnumApiMation.getAppId()); + DataCommonUtil.setCommonDataByGenericity(skyeyeClassEnumMation, CommonConstants.ADMIN_USER_ID); + DataCommonUtil.setId(skyeyeClassEnumMation); + skyeyeClassEnumMationList.add(skyeyeClassEnumMation); + }); + + saveBatch(skyeyeClassEnumMationList); + } + + /** + * 根据className获取可以展示在界面上的枚举数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getEnumDataByClassName(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String filterKey = params.get("filterKey").toString(); + String filterValue = params.get("filterValue").toString(); + List> skyeyeEnumDtoList = queryEnumDataList(className, filterKey, filterValue); + + outputObject.setBeans(skyeyeEnumDtoList); + outputObject.settotal(skyeyeEnumDtoList.size()); + } + + @Override + public List> queryEnumDataList(String className, String filterKey, String filterValue) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SkyeyeClassEnumMation::getClassName), className); + SkyeyeClassEnumMation skyeyeClassEnumMation = skyeyeClassEnumDao.selectOne(queryWrapper); + // 只加载可以展示的数据 + List> skyeyeEnumDtoList = skyeyeClassEnumMation.getValueList() + .stream().filter(bean -> filterSkyeyeEnumDto(bean, filterKey, filterValue)).collect(Collectors.toList()); + return skyeyeEnumDtoList; + } + + private Boolean filterSkyeyeEnumDto(Map enumValueMap, String filterKey, String filterValue) { + Boolean show = (Boolean) enumValueMap.get("show"); + if (ToolUtil.isBlank(filterValue)) { + return show; + } + List filterValueList = Arrays.asList(filterValue.split(CommonCharConstants.COMMA_MARK)); + // 需要过滤出来的数据并且是可以显示的数据 + if (filterValueList.contains(String.valueOf(enumValueMap.get(filterKey))) && show) { + return true; + } + return false; + } + + @Override + public void getEnumDataMapByClassName(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + List classNameList = JSONUtil.toList(params.get("classNameList").toString(), null); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(SkyeyeClassEnumMation::getClassName), classNameList); + List enumMationList = skyeyeClassEnumDao.selectList(queryWrapper); + // 只加载可以展示的数据 + Map>> result = new HashMap<>(); + enumMationList.forEach(enumMation -> { + List> skyeyeEnumDtoList = enumMation.getValueList() + .stream().filter(bean -> filterSkyeyeEnumDto(bean, StrUtil.EMPTY, StrUtil.EMPTY)).collect(Collectors.toList()); + result.put(enumMation.getClassName(), skyeyeEnumDtoList); + }); + + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/controller/CodeRuleController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/controller/CodeRuleController.java new file mode 100644 index 0000000..738a272 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/controller/CodeRuleController.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.coderule.entity.CodeMation; +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.coderule.service.CodeRuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CodeRuleController + * @Description: 编码规则管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "编码管理", tags = "编码管理", modelName = "系统公共模块") +public class CodeRuleController { + + @Autowired + private CodeRuleService codeRuleService; + + /** + * 获取编码规则列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCodeRuleList", value = "获取编码规则列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CodeRuleController/queryCodeRuleList") + public void queryCodeRuleList(InputObject inputObject, OutputObject outputObject) { + codeRuleService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑编码规则 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCodeRuleMation", value = "新增/编辑编码规则", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CodeRule.class) + @RequestMapping("/post/CodeRuleController/writeCodeRuleMation") + public void writeCodeRuleMation(InputObject inputObject, OutputObject outputObject) { + codeRuleService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID获取编码规则信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCodeRuleMationById", value = "根据ID获取编码规则信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CodeRuleController/queryCodeRuleMationById") + public void queryCodeRuleMationById(InputObject inputObject, OutputObject outputObject) { + codeRuleService.selectById(inputObject, outputObject); + } + + /** + * 根据ID删除编码规则 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCodeRuleMationById", value = "根据ID删除编码规则", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CodeRuleController/deleteCodeRuleMationById") + public void deleteCodeRuleMationById(InputObject inputObject, OutputObject outputObject) { + codeRuleService.deleteById(inputObject, outputObject); + } + + /** + * 获取编码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getNextCodes", value = "获取编码", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CodeMation.class) + @RequestMapping("/post/CodeRuleController/getNextCodes") + public void getNextCodes(InputObject inputObject, OutputObject outputObject) { + codeRuleService.getNextCodes(inputObject, outputObject); + } + + /** + * 获取所有的编码规则 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getAllCodeRuleList", value = "获取所有的编码规则", method = "GET", allUse = "2") + @RequestMapping("/post/CodeRuleController/getAllCodeRuleList") + public void getAllCodeRuleList(InputObject inputObject, OutputObject outputObject) { + codeRuleService.getAllCodeRuleList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeMaxSerialDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeMaxSerialDao.java new file mode 100644 index 0000000..67073c2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeMaxSerialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.coderule.entity.CodeMaxSerial; + +/** + * @ClassName: CodeMaxSerialDao + * @Description: 编码规则最大序列值管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeMaxSerialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeRuleDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeRuleDao.java new file mode 100644 index 0000000..503d4ee --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/dao/CodeRuleDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.dao; + +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CodeRuleDao + * @Description: 编码规则管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeRuleDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeMaxSerial.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeMaxSerial.java new file mode 100644 index 0000000..dfae0c5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeMaxSerial.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: CodeMaxSerial + * @Description: 编码最大序列值实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_code_max_serial", autoResultMap = true) +@ApiModel("编码最大序列值实体类") +public class CodeMaxSerial extends OperatorUserInfo implements Serializable { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField("code_rule_id") + @ApiModelProperty("编码规则实体类ID") + private String codeRuleId; + + @TableField("feature_code") + @ApiModelProperty("特征码") + private String featureCode; + + @TableField("serial_code") + @ApiModelProperty("流水码") + private String serialCode; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeRule.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeRule.java new file mode 100644 index 0000000..a46b8f1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/CodeRule.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: CodeRule + * @Description: 编码规则实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = CacheConstants.CODE_RULE_CACHE_KEY, value = {"id", "codeNum"}) +@TableName(value = "skyeye_code_rule", autoResultMap = true) +@ApiModel("编码规则实体类") +public class CodeRule extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("code_num") + @ApiModelProperty(value = "编码", required = "required", fuzzyLike = true) + private String codeNum; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField("pattern") + @ApiModelProperty(value = "命名模式", required = "required") + private String pattern; + + @TableField("ignore_chars") + @ApiModelProperty(value = "忽略字符") + private String ignoreChars; + + @TableField("feature_script") + @ApiModelProperty(value = "特征码变量扩展规则") + private String featureScript; + + @TableField("pattern_list") + @ApiModelProperty(value = "使用到的编码规则列表", required = "required") + private String patternList; + + @TableField("alarm") + @ApiModelProperty(value = "是否告警:0不告警1告警 默认0,编码使用超90%告警", required = "required,num") + private Integer alarm; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePattern.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePattern.java new file mode 100644 index 0000000..21be562 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePattern.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity.util; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.skyeye.exception.CustomException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @ClassName: CodePattern + * @Description: 编码规则 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class CodePattern { + + private boolean isValid = false; + + private int datePatternSize = 0; + + private int serialNumPatternSize = 0; + + /** + * 序列码位数 + */ + private int serialNumDigits = 0; + + private String pattern; + + private String dateSubPattern = ""; + + private List nodes = new ArrayList<>(); + + private static List rules = new ArrayList<>(4); + + + static { + rules.add(new NodePatten(CodePatternNode.Type.CONSTANT.name(), Pattern.compile("^\".*?\""))); + rules.add(new NodePatten(CodePatternNode.Type.VARIABLE.name(), Pattern.compile("^\\{.*?\\}"))); + rules.add(new NodePatten(CodePatternNode.Type.DATE.name(), Pattern.compile("^yyyyMMddHHmmss|^yyyyMMddHHmm|^yyyyMMddHH|^yyyyMMdd|^yyyyMM|^yyyy"))); + rules.add(new NodePatten(CodePatternNode.Type.SERIAL_NUM.name(), Pattern.compile("^n+"))); + } + + public boolean isValid() { + return isValid; + } + + public int getSerialNumDigits() { + return serialNumDigits; + } + + public List getNodes() { + return nodes; + } + + + @Override + public String toString() { + return "CodePattern{" + + "isValid=" + isValid + + ", serialNumDigits=" + serialNumDigits + + ", pattern='" + pattern + '\'' + + ", nodes=" + nodes + + '}'; + } + + public CodePattern(String pattern) { + this.pattern = pattern; + parseCodePattern(); + } + + private void parseCodePattern() { + String temp = pattern; + boolean anyMatch; + do { + anyMatch = false; + for (NodePatten nodePatten : rules) { + Matcher matcher = nodePatten.pattern.matcher(temp); + if (matcher.find(0)) { + anyMatch = true; + String group = matcher.group(); + nodes.add(new CodePatternNode(group, CodePatternNode.Type.valueOf(nodePatten.type))); + if (CodePatternNode.Type.SERIAL_NUM.name().equals(nodePatten.type)) { + serialNumDigits = group.length(); + serialNumPatternSize++; + } else if (CodePatternNode.Type.DATE.name().equals(nodePatten.type)) { + dateSubPattern = group; + datePatternSize++; + } + int end = matcher.end(); + temp = temp.substring(end); + } + } + } while (anyMatch); + + if (temp.length() == 0 && serialNumDigits > 0) { + isValid = true; + } + } + + /** + * 规则节点值解析 + * + * @param featureCodeMap 特征码map + * @param featureScript 特征码脚本规则 + */ + public void setFeatureCode(Map featureCodeMap, String featureScript) { + log.debug("setFeatureCode() featureCodeMap=======" + featureCodeMap); + //验证输入编码是否符合规则。lov格式跳过--前面已经验证,此处不进行验证 + for (CodePatternNode patternNode : this.nodes) { + if (CodePatternNode.Type.DATE.equals(patternNode.getType())) { + patternNode.setValue(DateUtil.format(new Date(), patternNode.getPattern())); + } else if (CodePatternNode.Type.CONSTANT.equals(patternNode.getType())) { + patternNode.setValue(patternNode.getPattern().replaceAll("\"", "")); + } else if (CodePatternNode.Type.VARIABLE.equals(patternNode.getType())) { + String regex = "\\{(.*?)}"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(patternNode.getPattern()); + if (!matcher.find()) { + break; + } + String cPattern = matcher.group(1); + String feature = getMapFeatureVal(featureCodeMap, cPattern); + feature = getFeatureVal(cPattern, feature, featureScript); + patternNode.setValue(feature); + } else { + + } + } + } + + + private String getFeatureVal(String key, String value, String featureScript) { + if (StringUtils.isBlank(featureScript)) { + return value; + } + JSONObject jsonObject = JSONUtil.parseObj(featureScript); + if (jsonObject.containsKey(key)) { + JSONObject obj = jsonObject.getJSONObject(key); + String type = obj.getStr("type"); + if ("map".equalsIgnoreCase(type)) { + if (obj.getJSONObject("content").containsKey(value)) { + return obj.getJSONObject("content").getStr(value); + } else { + return value; + } + } else { + return FeatureScriptUtil.invokeScript(obj.getStr("content"), key, value); + } + } else { + return value; + } + } + + /** + * 获取特征码值(只针对流水码判断忽略字符) + * + * @param featureCodeMap 特征码表 + * @param key 特征码key + * @return 值 + */ + private String getMapFeatureVal(Map featureCodeMap, String key) { + String featureValue; + if (CollectionUtils.isEmpty(featureCodeMap)) { + return StringUtils.EMPTY; + } + if (featureCodeMap.get(key) != null) { + featureValue = StringUtils.EMPTY + featureCodeMap.get(key); + return featureValue; + } + return StringUtils.EMPTY; + + } + + public String getFeatureCode() { + StringBuilder sb = new StringBuilder(); + this.nodes.forEach(item -> { + if (CodePatternNode.Type.SERIAL_NUM.equals(item.getType())) { + sb.append("{serialNo}"); + } else { + sb.append(item.getValue()); + } + }); + return sb.toString(); + } + + public String getDateSubPattern() { + return this.dateSubPattern; + } + + /** + * 根据流水码,获取完整编码 + * + * @param serialCode 流水码 + * @return 完整编码 + */ + public String getCode(long serialCode) { + StringBuilder sb = new StringBuilder(); + sb.append(StringUtils.EMPTY); + this.nodes.forEach(item -> { + if (CodePatternNode.Type.SERIAL_NUM.equals(item.getType())) { + int patternLength = item.getPattern().length(); + sb.append(String.format("%0" + patternLength + "d", serialCode)); + } else { + sb.append(item.getValue()); + } + }); + return sb.toString(); + } + + public static void validationCodeRulePatten(String pattern) { + CodePattern codePattern = new CodePattern(pattern); + if (!codePattern.isValid) { + throw new CustomException("规则无法解析完成或规则中不包含序列码规则"); + } + if (codePattern.serialNumPatternSize != 1) { + throw new CustomException("规则中必须且只能包含一个序列码规则"); + } + if (codePattern.datePatternSize > 1) { + throw new CustomException("规则中最多只能包含一个日期规则"); + } + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePatternNode.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePatternNode.java new file mode 100644 index 0000000..cd7dc90 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/CodePatternNode.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity.util; + +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: CodePatternNode + * @Description: 编码节点对象 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class CodePatternNode { + + /** + * 编码流水号模式 + */ + private String pattern = ""; + /** + * 编码值(流水码或日期模式生成的值) + */ + private String value = ""; + /** + * 编码规则节点类型枚举 + */ + private Type type; + + + public CodePatternNode() { + } + + public CodePatternNode(String pattern, Type type) { + this.pattern = pattern; + this.type = type; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + @Override + public String toString() { + return "CodePatternNode{" + + "pattern='" + pattern + '\'' + + ", value='" + value + '\'' + + ", type=" + type + + '}'; + } + + /** + * 编码规则节点类型枚举 + */ + enum Type { + /** + * 常量 + */ + CONSTANT, + /** + * 变量 + */ + VARIABLE, + /** + * 时间格式 + */ + DATE, + /** + * 序列码 + */ + SERIAL_NUM + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/FeatureScriptUtil.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/FeatureScriptUtil.java new file mode 100644 index 0000000..96d6941 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/FeatureScriptUtil.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity.util; + +import com.skyeye.common.script.ScriptUtil; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: FeatureScriptUtil + * @Description: 校验工具类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class FeatureScriptUtil { + + public static String invokeScript(String script, String key, Object value) { + String fullScript = "function coed_feature_conversion(key,value){ " + script + " }"; + Object invoke = ScriptUtil.invoke(fullScript, "coed_feature_conversion", key, value); + return null == invoke ? "" : invoke.toString(); + } + + public static boolean testScript(String script) { + try { + invokeScript(script, "Test", "00"); + } catch (Exception e) { + log.error("测试js脚本出错: ", e); + return false; + } + return true; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/NodePatten.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/NodePatten.java new file mode 100644 index 0000000..6c837ce --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/entity/util/NodePatten.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.entity.util; + +import java.util.regex.Pattern; + +/** + * @ClassName: NodePatten + * @Description: 规则 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class NodePatten { + String type; + Pattern pattern; + + public NodePatten(String type, Pattern pattern) { + this.type = type; + this.pattern = pattern; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/CodeRuleService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/CodeRuleService.java new file mode 100644 index 0000000..8892b10 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/CodeRuleService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: CodeRuleService + * @Description: 编码规则管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CodeRuleService extends SkyeyeBusinessService { + + void getNextCodes(InputObject inputObject, OutputObject outputObject); + + void getAllCodeRuleList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/impl/CodeRuleServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/impl/CodeRuleServiceImpl.java new file mode 100644 index 0000000..4ed54e8 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/coderule/service/impl/CodeRuleServiceImpl.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coderule.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.coderule.dao.CodeMaxSerialDao; +import com.skyeye.coderule.dao.CodeRuleDao; +import com.skyeye.coderule.entity.CodeMaxSerial; +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.coderule.entity.util.CodePattern; +import com.skyeye.coderule.entity.util.FeatureScriptUtil; +import com.skyeye.coderule.service.CodeRuleService; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.coderule.entity.CodeMation; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.util.RedisLock; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.concurrent.Executor; + +/** + * @ClassName: CodeRuleServiceImpl + * @Description: 编码规则管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/16 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "编码规则管理", groupName = "系统设置") +public class CodeRuleServiceImpl extends SkyeyeBusinessServiceImpl implements CodeRuleService { + + private static final Logger LOGGER = LoggerFactory.getLogger(CodeRuleServiceImpl.class); + + @Autowired + private CodeRuleDao codeRuleDao; + + @Autowired + private CodeMaxSerialDao codeMaxSerialDao; + + private static final int SERIAL_NO_MAX_SIZE = 5000; + + private static final int SERIAL_NO_MIN_SIZE = 1; + + @Autowired + private RedisCache redisCache; + + @Autowired + private Executor codeRuleExecutor; + + @Override + public void validatorEntity(CodeRule entity) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(CodeRule::getCodeNum), entity.getCodeNum()) + .or().eq(MybatisPlusUtil.toColumns(CodeRule::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(CodeRule::getPattern), entity.getPattern())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + CodeRule checkCodeRule = codeRuleDao.selectOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkCodeRule)) { + throw new CustomException("this 【名称/编码/命名模式】 is exist."); + } + CodePattern.validationCodeRulePatten(entity.getPattern()); + this.validFeatureScript(entity.getFeatureScript()); + } + + private void validFeatureScript(String featureScript) { + if (StringUtils.isNotBlank(featureScript)) { + if (!JSONUtil.isJsonObj(featureScript)) { + throw new CustomException("特征码附加脚本格式错误,未成功解析成json"); + } + JSONObject parse = JSONUtil.parseObj(featureScript); + parse.keySet().forEach(key -> { + JSONObject jsonObject = parse.getJSONObject(key); + if (!jsonObject.containsKey("type")) { + throw new CustomException("特征码附加脚本中未包含脚本类型"); + } + String type = jsonObject.getStr("type"); + if ("map".equalsIgnoreCase(type)) { + String content = jsonObject.getStr("content"); + if (!JSONUtil.isJsonObj(content)) { + throw new CustomException("特征码扩展脚本map映射内容错误"); + } + } else if ("javaScript".equalsIgnoreCase(type)) { + String content = jsonObject.getStr("content"); + if (!FeatureScriptUtil.testScript(content)) { + throw new CustomException("特征码扩展脚本JavaScript脚本内容错误"); + } + } else { + throw new CustomException("特征码扩展脚本中不包含" + type + "的实现"); + } + }); + } + } + + /** + * 获取编码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getNextCodes(InputObject inputObject, OutputObject outputObject) { + CodeMation codeMation = inputObject.getParams(CodeMation.class); + List codes = this.getNextCodes(codeMation.getRuleCode(), codeMation.getBusinessData(), codeMation.getSize()); + Map result = new HashMap<>(); + result.put("list", codes); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private List getNextCodes(String ruleCode, Map businessData, int size) { + if (size < SERIAL_NO_MIN_SIZE) { + size = SERIAL_NO_MIN_SIZE; + } + if (size > SERIAL_NO_MAX_SIZE) { + size = SERIAL_NO_MAX_SIZE; + } + CodeRule codeRuleMation = selectById(ruleCode); + if (codeRuleMation == null) { + throw new CustomException("未找到命名规则或附加关系"); + } + // 解析编码规则 + CodePattern codePattern = new CodePattern(codeRuleMation.getPattern()); + if (!codePattern.isValid()) { + throw new CustomException("解析命名规则模式失败"); + } + + // 设置特征码 + codePattern.setFeatureCode(businessData, codeRuleMation.getFeatureScript()); + return getCodeByFeature(codePattern, codeRuleMation.getId(), size); + } + + /** + * 根据特征码获取编号 + * + * @param codePattern 命名规则生成器 + * @param nameRuleId 编码规则id + * @param size 获取的序列码数量 + * @return list + */ + private List getCodeByFeature(CodePattern codePattern, String nameRuleId, int size) { + List codes = new ArrayList<>(size); + String featureCode = codePattern.getFeatureCode(); + LOGGER.info(">>>>>>>>>>featureCode==== " + featureCode); + // 初始redis没有值时,获取数据库值或插入数据到数据库。如果有值,则直接获取序列号且加一。 如果初始没值且高并发,在循环中处理,避免重复 + long serialCode = getMaxSerialCode(featureCode, nameRuleId, size); + LOGGER.info("serialCode===========" + serialCode); + for (long i = serialCode - size + 1; i <= serialCode; i++) { + String code = codePattern.getCode(i); + codes.add(code); + } + return codes; + } + + private long getMaxSerialCode(String featureCode, String relationId, int size) { + Long serialCode = null; + String lockKey = ""; + RedisLock lock = new RedisLock(lockKey); + try { + if (!lock.lock()) { + // 加锁失败 + throw new CustomException("当前并发量较大,请稍后再次尝试."); + } + Map codeMaxSerial = this.getCodeMaxSerial(featureCode, relationId); + if (CollectionUtils.isEmpty(codeMaxSerial)) { + // 创建maxSerial数据 + serialCode = (long) size; + this.saveCodeMaxSerial(featureCode, relationId, size); + } else { + serialCode = Long.parseLong(codeMaxSerial.get("serialCode").toString()) + size; + } + // 刷新缓存 + this.refresh(featureCode, relationId, String.valueOf(serialCode)); + } catch (Exception ex) { + LOGGER.error("查询最大序列码出错!", ex); + throw new CustomException("获取编码失败"); + } finally { + lock.unlock(); + } + return serialCode; + } + + private void saveCodeMaxSerial(String featureCode, String relationId, int size) { + CodeMaxSerial codeMaxSerialMation = new CodeMaxSerial(); + codeMaxSerialMation.setFeatureCode(featureCode); + codeMaxSerialMation.setCodeRuleId(relationId); + codeMaxSerialMation.setSerialCode(String.valueOf(size)); + DataCommonUtil.setCommonDataByGenericity(codeMaxSerialMation, CommonConstants.ADMIN_USER_ID); + DataCommonUtil.setId(codeMaxSerialMation); + codeMaxSerialDao.insert(codeMaxSerialMation); + } + + private Map getCodeMaxSerial(String featureCode, String relationId) { + String cacheKey = getCacheKey(featureCode, relationId); + return redisCache.getMap(cacheKey, key -> { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(CodeMaxSerial::getFeatureCode), featureCode); + wrapper.eq(MybatisPlusUtil.toColumns(CodeMaxSerial::getCodeRuleId), relationId); + return codeMaxSerialDao.selectOne(wrapper); + }, RedisConstants.THIRTY_DAY_SECONDS); + } + + private void refresh(String featureCode, String relationId, String serialCode) { + // 异步更新数据库 + codeRuleExecutor.execute(() -> { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set(MybatisPlusUtil.toColumns(CodeMaxSerial::getSerialCode), serialCode); + updateWrapper.set(MybatisPlusUtil.toColumns(CodeMaxSerial::getLastUpdateTime), DateUtil.getTimeAndToString()); + updateWrapper.eq(MybatisPlusUtil.toColumns(CodeMaxSerial::getCodeRuleId), relationId); + updateWrapper.eq(MybatisPlusUtil.toColumns(CodeMaxSerial::getFeatureCode), featureCode); + codeMaxSerialDao.update(null, updateWrapper); + }); + + // 更新缓存 + CodeMaxSerial codeMaxSerialMation = new CodeMaxSerial(); + codeMaxSerialMation.setFeatureCode(featureCode); + codeMaxSerialMation.setCodeRuleId(relationId); + codeMaxSerialMation.setSerialCode(serialCode); + String cacheKey = getCacheKey(featureCode, relationId); + jedisClientService.set(cacheKey, JSON.toJSONString(codeMaxSerialMation), RedisConstants.THIRTY_DAY_SECONDS); + } + + private String getCacheKey(String featureCode, String relationId) { + String cacheKey = String.format(Locale.ROOT, "%s:maxSerial:%s_%s", CacheConstants.CODE_RULE_CACHE_KEY, featureCode, relationId); + return cacheKey; + } + + /** + * 获取所有的编码规则 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getAllCodeRuleList(InputObject inputObject, OutputObject outputObject) { + List codeRuleMationList = list(); + outputObject.setBeans(codeRuleMationList); + outputObject.settotal(codeRuleMationList.size()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/SkyeyeViewEnum.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/SkyeyeViewEnum.java new file mode 100644 index 0000000..05a06e0 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/SkyeyeViewEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SkyeyeViewEnum + * @Description: 前台视图的枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/17 23:04 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SkyeyeViewEnum implements SkyeyeEnumClass { + + WIN_10("../../tpl/index/index.html", "WIN10 桌面", true, true), + TRADITION_PAGE("../../tpl/traditionpage/index.html", "传统风格", true, false); + + private String path; + + private String name; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/Constants.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/Constants.java new file mode 100644 index 0000000..ca3c1dc --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/Constants.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.constans; + +/** + * @ClassName: Constants + * @Description: 系统公共常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 23:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class Constants { + + /** + * 保存模板说明的redis的key + */ + public static final String REDIS_CODEMODEL_EXPLAIN_EXEXPLAIN = "exexplaintocodemodel"; + + public static String getSysExplainExexplainRedisKey(Integer type) { + return REDIS_CODEMODEL_EXPLAIN_EXEXPLAIN + "_" + type; + } + + // win系统桌面图片列表的redis的key + public static final String SYS_WIN_BG_PIC_REDIS_KEY = "sys_win_bg_pic_redis_key"; + + // win系统锁屏桌面图片列表的redis的key + public static final String SYS_WIN_LOCK_BG_PIC_REDIS_KEY = "sys_win_lock_bg_pic_redis_key"; + + // win系统主题颜色列表的redis的key + public static final String SYS_WIN_THEME_COLOR_REDIS_KEY = "sys_win_theme_color_redis_key"; + + // 聊天获取当前登陆用户信息在redis中的key + public static final String SYS_TALK_USER_THIS_MATN_MATION = "sys_talk_user_this_matn_mation_"; + + public static String getSysTalkUserThisMainMationById(String id) { + return SYS_TALK_USER_THIS_MATN_MATION + id; + } + + // 聊天获取当前登陆用户拥有的群组列表在redis中的key + public static final String SYS_TALK_USER_HAS_GROUP_LIST_MATION = "sys_talk_user_has_group_list_mation_"; + + public static String getSysTalkUserHasGroupListMationById(String id) { + return SYS_TALK_USER_HAS_GROUP_LIST_MATION + id; + } + + // 聊天获取分组下的用户列表信息在redis中的key + public static final String SYS_TALK_GROUP_USER_LIST_MATION = "sys_talk_group_user_list_mation_"; + + public static String getSysTalkGroupUserListMationById(String id) { + return SYS_TALK_GROUP_USER_LIST_MATION + id; + } + + // 获取群组成员列表 + public static final String SYS_EVE_TALK_GROUP_USER_LIST = "sys_eve_talk_group_user_list_"; + + public static String checkSysEveTalkGroupUserListByGroupId(String groupId) { + return SYS_EVE_TALK_GROUP_USER_LIST + groupId; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/ForumConstants.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/ForumConstants.java new file mode 100644 index 0000000..477cd70 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/ForumConstants.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.constans; + +/** + * @ClassName: ForumConstants + * @Description: 论坛系统常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/15 21:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class ForumConstants { + + // 获取论坛帖子浏览量的redis的key(实时的) + public static final String FORUM_BROWSE_NUMS_BYFORUMID = "forum_browse_nums_by_"; + + public static String forumBrowseNumsByForumId(String forumId) { + return FORUM_BROWSE_NUMS_BYFORUMID + forumId; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/SocketConstants.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/SocketConstants.java new file mode 100644 index 0000000..f1015f5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/SocketConstants.java @@ -0,0 +1,170 @@ +package com.skyeye.common.constans; + +import cn.hutool.json.JSONObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; + +import java.util.HashMap; +import java.util.Map; + +public class SocketConstants { + + public static enum MessageType { + First(1, "上线通知", ""), + Second(2, "下线通知", ""), + Third(3, "获取在线名单通知", ""), + Fourth(4, "聊天普通消息通知", ""), + Fifth(5, "系统消息通知", ""), + Sixth(6, "全体消息通知", ""), + Seventh(7, "群组邀请消息通知", ""), + Eighth(8, "隐身消息通知", ""), + Ninth(9, "隐身上线消息通知", ""), + Tenth(10, "搜索账号入群审核同意后通知用户加载群信息通知", ""), + Eleventh(11, "群聊消息通知", ""), + Twelfth(12, "退出群聊通知", ""), + Thirteenth(13, "解散群聊通知", ""); + + private int type; + private String title; + private String method; + + MessageType(int type, String title, String method) { + this.type = type; + this.title = title; + this.method = method; + } + + public static String getMethod(int type) { + for (MessageType q : MessageType.values()) { + if (q.getType() == type) { + return q.getMethod(); + } + } + return ""; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + } + + /** + * 发送普通消息 + * + * @param jsonObject + * @return + */ + public static Map sendOrdinaryMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("avatar", jsonObject.getStr("avatar"));//头像 + map.put("textMessage", jsonObject.getStr("message"));//消息 + map.put("username", jsonObject.getStr("username"));//收件人名称 + map.put("fromId", jsonObject.getStr("userId"));//发件人id + map.put("toId", jsonObject.getStr("to"));//收件人id + map.put("messageType", jsonObject.getInt("type"));//消息类型 + map.put("createTime", DateUtil.getTimeAndToString()); + map.put("dataId", ToolUtil.getSurFaceId()); + return map; + } + + /** + * 发送全体消息 + * + * @param jsonObject + * @return + */ + public static Map sendAllPeopleMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("avatar", jsonObject.getStr("avatar"));//头像 + map.put("textMessage", jsonObject.getStr("message"));//消息 + map.put("username", jsonObject.getStr("username"));//收件人名称 + map.put("fromId", jsonObject.getStr("userId"));//发件人id + map.put("messageType", jsonObject.getInt("type"));//消息类型 + map.put("tousername", "所有人"); + return map; + } + + /** + * 发送群组聊天消息 + * + * @param jsonObject + * @return + */ + public static Map sendGroupTalkPeopleMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("avatar", jsonObject.getStr("avatar"));//头像 + map.put("textMessage", jsonObject.getStr("message"));//消息 + map.put("username", jsonObject.getStr("username"));//发消息人名称 + map.put("id", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map.put("userId", jsonObject.getStr("userId"));//群聊消息不发送给自己 + map.put("messageType", jsonObject.getInt("type"));//消息类型 + return map; + } + + /** + * 搜索账号入群审核同意后通知用户加载群信息 + * + * @param jsonObject + * @return + */ + public static Map sendAgreeJoinGroupMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("avatar", jsonObject.getStr("avatar"));//头像 + map.put("groupname", jsonObject.getStr("groupname"));//群聊名称 + map.put("id", jsonObject.getStr("id"));//群聊id + map.put("toId", jsonObject.getStr("to"));//收件人id + map.put("messageType", jsonObject.getInt("type"));//消息类型 + return map; + } + + /** + * 退出群聊--创建人接收消息 + * + * @param jsonObject + * @return + */ + public static Map sendOutGroupToCreaterMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("groupId", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map.put("userName", jsonObject.getStr("userName"));//退群人名称 + map.put("userId", jsonObject.getStr("userId"));//群聊消息不发送给自己 + map.put("messageType", jsonObject.getInt("type"));//消息类型 + return map; + } + + /** + * 解散群聊--所有人接收消息 + * + * @param jsonObject + * @return + */ + public static Map sendDisbandGroupToAllMsg(JSONObject jsonObject) { + Map map = new HashMap<>(); + map.put("id", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map.put("userName", jsonObject.getStr("userName"));//群主 + map.put("userId", jsonObject.getStr("userId"));//群主id + map.put("messageType", jsonObject.getInt("type"));//消息类型 + return map; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/WxchatUtil.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/WxchatUtil.java new file mode 100644 index 0000000..97804d1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/common/constans/WxchatUtil.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.constans; + +public class WxchatUtil { + + // 微信用户在redis中的存储key + private static final String WECHAT_USER_OPENID = "wechat_user_openid_"; + + public static String getWechatUserOpenIdMation(String openId) { + return WECHAT_USER_OPENID + openId; + } + + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentApplyRange.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentApplyRange.java new file mode 100644 index 0000000..0daca2b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentApplyRange.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ComponentApplyRange + * @Description: 组件适用范围类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/18 18:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ComponentApplyRange implements SkyeyeEnumClass { + + GLOBALLY_APPLICABLE(1, "全局适用", true, true), + LOCAL_APPLICATION(2, "局部适用", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentAttr.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentAttr.java new file mode 100644 index 0000000..476c30e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentAttr.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ComponentAttr + * @Description: 组件关联的属性 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/28 11:05 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ComponentAttr implements SkyeyeEnumClass { + + ATTR_KEY("attrKeyBox", "关联属性", false, true, false), + TITLE("titleBox", "标题", false, true, false), + PLACEHOLDER("placeholderBox", "提示语", false, true, false), + REMARK("remarkBox", "备注", false, true, false), + CLASS_NAME("classNameBox", "class属性", false, true, false), + REQUIRE("requireBox", "限制条件", false, true, false), + WIDTH("widthBox", "宽度", true, true, true), + PRE_ATTRIBUTE("preAttributeBox", "前置属性", false, true, false), + POST_ATTRIBUTE("postAttributeBox", "后置属性", false, true, false), + DEFAULT_VALUE("defaultValueBox", "默认值", false, true, false), + UPLOAD_DATA_TYPE("uploadDataTypeBox", "文件后缀类型", false, true, false), + UPLOAD_TYPE("uploadTypeBox", "文件上传类型", false, true, false), + UPLOAD_NUM("uploadNumBox", "文件数量", false, true, false), + DATA_SHOW_TYPE("dataShowTypeBox", "枚举/数据字典展示类型", false, true, false), + TEAM_OBJECT_TYPE("teamObjectTypeBox", "团队适用对象", false, true, false), + IS_EDIT("isEditBox", "是否可以编辑", false, true, false), + DATE_TIME_TYPE("dateTimeTypeBox", "日期类型", false, true, false), + USER_SEL("userSelBox", "用户选择配置", false, true, false), + USER_SEL_TYPE_BOX("userSelTypeBox", "单选/多选配置", false, true, false), + TABLE_ATTR("tableAttrBox", "表格属性配置", false, true, false), + MIN_DATA("minDataBox", "表格组件最小数据行数", false, true, false), + DELETE_ROW_CALLBACK("deleteRowCallbackBox", "删除行之后的回调函数", false, true, false), + ADD_ROW_CALLBACK("addRowCallbackBox", "新增行之后的回调函数", false, true, false), + BEFORE_SCRIPT("beforeScriptBox", "组件加载前执行的脚本", false, true, false), + AFTER_SCRIPT("afterScriptBox", "组件加载完成后执行的脚本", false, true, false), + EDIT_ECHO_SCRIPT("editEchoScriptBox", "数据编辑回显时执行的脚本", false, true, false), + DATA_ECHO_AFTER_SCRIPT("dataEchoAfterScriptBox", "数据回显完之后执行的脚本", false, true, false), + AFTER_HTML("afterHtmlBox", "组件加载完成后执行的HTML脚本", false, true, false), + DATA_CHANGE("dataChangeBox", "数据变化监听的JS", false, true, false); + + private String key; + + private String value; + + /** + * 必选(默认选中,不可取消) + */ + private Boolean disabled; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentValueMergType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentValueMergType.java new file mode 100644 index 0000000..d5712c5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/ComponentValueMergType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ComponentValueMergType + * @Description: 组件获取的值的合入接口入参的方式 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/25 12:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ComponentValueMergType implements SkyeyeEnumClass { + + SIMPLE("simple", "普通", true, true), + EXTEND("extend", "扩展", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DateTimeType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DateTimeType.java new file mode 100644 index 0000000..1f13c9f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DateTimeType.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DateTimeType + * @Description: 日期类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/3/5 18:02 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DateTimeType implements SkyeyeEnumClass { + + YEAR("year", "年", true, false), + MONTH("month", "年-月", true, false), + DATE("date", "年-月-日", true, false), + TIME("time", "时:分:秒", true, false), + DATETIME("datetime", "年-月-日 时:分:秒", true, true), + TIMEMINUTE("timeminute", "时:分", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DsFormPageType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DsFormPageType.java new file mode 100644 index 0000000..5b03ad7 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/DsFormPageType.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: IsDefaultEnum + * @Description: 表单布局类型 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/5 23:51 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DsFormPageType implements SkyeyeEnumClass { + + CREATE("create", "创建布局", true, false), + EDIT("edit", "编辑布局", true, false), + DETAILS("details", "详情布局", true, false), + SIMPLE_TABLE("simpleTable", "基础表格", true, false), + PROCESS_ATTR("processAttr", "流程属性布局", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/FixedType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/FixedType.java new file mode 100644 index 0000000..4d20fca --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/FixedType.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FixedType + * @Description: 表格列固定位置枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FixedType implements SkyeyeEnumClass { + LEFT("left", "固定在左", true, false), + RIGHT("right", "固定在右", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/SimpleTableWhetherChoose.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/SimpleTableWhetherChoose.java new file mode 100644 index 0000000..fd4a063 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/classenum/SimpleTableWhetherChoose.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SimpleTableWhetherChoose + * @Description: 表格类型的布局是否开启选择功能 + * @author: skyeye云系列--卫志强 + * @date: 2023/6/11 21:51 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SimpleTableWhetherChoose implements SkyeyeEnumClass { + + CLOSE("close", "关闭", true, true), + RADIO("radio", "单选", true, false), + CHECKBOX("checkbox", "多选", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormComponentController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormComponentController.java new file mode 100644 index 0000000..23c5c46 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormComponentController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.dsform.service.DsFormComponentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DsFormComponentController + * @Description: 表单组件管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/24 18:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本组件仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "表单组件管理", tags = "表单组件管理", modelName = "动态表单模块") +public class DsFormComponentController { + + @Autowired + private DsFormComponentService dsFormComponentService; + + /** + * 获取动态表单组件列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDsFormComponentList", value = "获取动态表单组件列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DsFormComponentController/queryDsFormComponentList") + public void queryDsFormComponentList(InputObject inputObject, OutputObject outputObject) { + dsFormComponentService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑表单组件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDsFormComponent", value = "添加/编辑表单组件", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DsFormComponent.class) + @RequestMapping("/post/DsFormComponentController/writeDsFormComponent") + public void writeDsFormComponent(InputObject inputObject, OutputObject outputObject) { + dsFormComponentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除动态表单组件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDsFormComponentMationById", value = "删除动态表单组件信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DsFormComponentController/deleteDsFormComponentMationById") + public void deleteDsFormComponentMationById(InputObject inputObject, OutputObject outputObject) { + dsFormComponentService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取动态表单组件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDsFormComponentMationById", value = "根据id获取动态表单组件信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DsFormComponentController/queryDsFormComponentMationById") + public void queryDsFormComponentMationById(InputObject inputObject, OutputObject outputObject) { + dsFormComponentService.selectById(inputObject, outputObject); + } + + /** + * 获取所有的动态表单组件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllDsFormComponentList", value = "获取所有的动态表单组件", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "业务对象的服务层className", required = "required")}) + @RequestMapping("/post/DsFormComponentController/queryAllDsFormComponentList") + public void queryAllDsFormComponentList(InputObject inputObject, OutputObject outputObject) { + dsFormComponentService.queryAllDsFormComponentList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormDisplayTemplateController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormDisplayTemplateController.java new file mode 100644 index 0000000..cd2d9f5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormDisplayTemplateController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormDisplayTemplate; +import com.skyeye.dsform.service.DsFormDisplayTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DsFormDisplayTemplateController + * @Description: 表单数据展示模板管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/6 9:48 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "表单数据展示模板管理", tags = "表单数据展示模板管理", modelName = "动态表单模块") +public class DsFormDisplayTemplateController { + + @Autowired + private DsFormDisplayTemplateService dsFormDisplayTemplateService; + + /** + * 获取动态表单数据展示模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformdisplaytemplate001", value = "获取动态表单数据展示模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DsFormDisplayTemplateController/queryDsFormDisplayTemplateList") + public void queryDsFormDisplayTemplateList(InputObject inputObject, OutputObject outputObject) { + dsFormDisplayTemplateService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑表单数据展示模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDsFormDisplayTemplate", value = "添加/编辑表单数据展示模板", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DsFormDisplayTemplate.class) + @RequestMapping("/post/DsFormDisplayTemplateController/writeDsFormDisplayTemplate") + public void writeDsFormDisplayTemplate(InputObject inputObject, OutputObject outputObject) { + dsFormDisplayTemplateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除动态表单数据展示模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformdisplaytemplate003", value = "删除动态表单数据展示模板信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键ID", required = "required")}) + @RequestMapping("/post/DsFormDisplayTemplateController/deleteDsFormDisplayTemplateMationById") + public void deleteDsFormDisplayTemplateMationById(InputObject inputObject, OutputObject outputObject) { + dsFormDisplayTemplateService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取数据展示模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformdisplaytemplate004", value = "根据id获取数据展示模板信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键ID", required = "required")}) + @RequestMapping("/post/DsFormDisplayTemplateController/queryDsFormDisplayTemplateMationToEditById") + public void queryDsFormDisplayTemplateMationToEditById(InputObject inputObject, OutputObject outputObject) { + dsFormDisplayTemplateService.selectById(inputObject, outputObject); + } + + /** + * 获取动态表单数据展示模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformdisplaytemplate006", value = "获取动态表单数据展示模板", method = "GET", allUse = "2") + @RequestMapping("/post/DsFormDisplayTemplateController/queryDisplayTemplateListToShow") + public void queryDisplayTemplateListToShow(InputObject inputObject, OutputObject outputObject) { + dsFormDisplayTemplateService.queryDisplayTemplateListToShow(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormPageController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormPageController.java new file mode 100644 index 0000000..e336652 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/controller/DsFormPageController.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.dsform.entity.DsFormPageContentVo; +import com.skyeye.dsform.entity.TableColumnVo; +import com.skyeye.dsform.service.DsFormPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DsFormPageController + * @Description: 表单布局管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/24 18:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本组件仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "表单布局管理", tags = "表单布局管理", modelName = "动态表单模块") +public class DsFormPageController { + + @Autowired + private DsFormPageService dsFormPageService; + + /** + * 获取表单布局列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDsFormPageList", value = "获取表单布局列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required")}) + @RequestMapping("/post/DsFormPageController/queryDsFormPageList") + public void queryDsFormPageList(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.queryDsFormPageList(inputObject, outputObject); + } + + /** + * 新增/编辑表单布局 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDsFormPage", value = "新增/编辑表单布局", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DsFormPage.class) + @RequestMapping("/post/DsFormPageController/writeDsFormPage") + public void writeDsFormPage(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除表单布局 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDsFormPage", value = "删除表单布局", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DsFormPageController/deleteDsFormPage") + public void deleteDsFormPage(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查找表单布局 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformpage006", value = "根据id查找表单布局", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DsFormPageController/selectDsFormPageById") + public void selectDsFormPageById(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.selectById(inputObject, outputObject); + } + + /** + * 根据业务对象的serviceClassName和流程模型id查找表单布局 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDsFormPageForProcess", value = "根据业务对象的serviceClassName和流程模型id查找表单布局", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "serviceClassName", name = "serviceClassName", value = "业务对象的serviceClassName", required = "required"), + @ApiImplicitParam(id = "actFlowId", name = "actFlowId", value = "流程模型id", required = "required")}) + @RequestMapping("/post/DsFormPageController/queryDsFormPageForProcess") + public void queryDsFormPageForProcess(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.queryDsFormPageForProcess(inputObject, outputObject); + } + + /** + * 保存表单布局关联的组件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDsFormPageContent", value = "保存表单布局关联的组件信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = DsFormPageContentVo.class) + @RequestMapping("/post/DsFormPageController/writeDsFormPageContent") + public void writeDsFormPageContent(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.writeDsFormPageContent(inputObject, outputObject); + } + + /** + * 保存表格类型的布局的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDsFormPageTable", value = "保存表格类型的布局的信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TableColumnVo.class) + @RequestMapping("/post/DsFormPageController/writeDsFormPageTable") + public void writeDsFormPageTable(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.writeDsFormPageTable(inputObject, outputObject); + } + + /** + * 根据业务数据id获取业务数据信息 + * 该接口因为要跨微服务获取数据,性能可能受限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBusinessDataByObject", value = "根据业务数据id获取业务数据信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "所属第三方业务数据id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "所属第三方业务数据的key", required = "required")}) + @RequestMapping("/post/DsFormPageController/queryBusinessDataByObject") + public void queryBusinessDataByObject(InputObject inputObject, OutputObject outputObject) { + dsFormPageService.queryBusinessDataByObject(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormComponentDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormComponentDao.java new file mode 100644 index 0000000..e0b08d2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormComponentDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.dao; + +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DsFormComponentDao + * @Description: 组件管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/1 21:55 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface DsFormComponentDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormDisplayTemplateDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormDisplayTemplateDao.java new file mode 100644 index 0000000..a21484e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormDisplayTemplateDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.dao; + +import com.skyeye.dsform.entity.DsFormDisplayTemplate; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DsFormDisplayTemplateDao + * @Description: 动态表单数据展示模板管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DsFormDisplayTemplateDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageContentDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageContentDao.java new file mode 100644 index 0000000..496a037 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageContentDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.dao; + +import com.skyeye.dsform.entity.DsFormPageContent; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DsFormPageContentDao + * @Description: 动态表单页面内容项数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/8 16:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DsFormPageContentDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageDao.java new file mode 100644 index 0000000..ac646bb --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/DsFormPageDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.dao; + +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DsFormPageDao + * @Description: 表单布局管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:33 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DsFormPageDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/TableColumnDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/TableColumnDao.java new file mode 100644 index 0000000..d271b28 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/dao/TableColumnDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.dao; + +import com.skyeye.dsform.entity.TableColumn; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: TableColumnDao + * @Description: 表格布局的列属性数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/5 20:43 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TableColumnDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTable.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTable.java new file mode 100644 index 0000000..e29de31 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTable.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.business.entity.BusinessApi; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: AttrTransformTable + * @Description: 表格模型属性 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("表格模型属性") +public class AttrTransformTable implements Serializable { + + @ApiModelProperty(value = "字段名,相当于表格中的field", required = "required") + private String attrKey; + + @ApiModelProperty(value = "显示名称") + private String name; + + @ApiModelProperty(value = "对齐方式,可参考#Alignment枚举类,相当于表格中的align", required = "required") + private String align; + + @ApiModelProperty(value = "排序,值越大越往后", required = "required,num") + private Integer orderBy; + + @ApiModelProperty(value = "宽度,相当于表格中的width", required = "required,num") + private Integer width; + + @ApiModelProperty(value = "组件限制条件") + private List require; + + @ApiModelProperty(value = "显示方式", required = "required") + private String showType; + + @ApiModelProperty(value = "数据类型,参考#AttrKeyDataType", required = "num") + private Integer dataType; + + @ApiModelProperty(value = "数据类型为1时,默认数据,需要是json字符串", required = "json") + private String defaultData; + + @ApiModelProperty(value = "数据类型为其他时,数据的id") + private String objectId; + + @ApiModelProperty(value = "dataType=4时,自定义api接口的请求", required = "json") + private BusinessApi businessApi; + + @ApiModelProperty(value = "表单监听Filter") + private String layFilter; + + @ApiModelProperty(value = "默认值") + private String value; + + @ApiModelProperty(value = "额外的class属性") + private String className; + + @ApiModelProperty(value = "当formType为chooseInput时,指定的icon图标的class属性") + private String iconClassName; + + @ApiModelProperty(value = "列内容展示的脚本,相当于表格中的templet") + private String templet; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTableListTypeHandler.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTableListTypeHandler.java new file mode 100644 index 0000000..b5af748 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/AttrTransformTableListTypeHandler.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.alibaba.fastjson.TypeReference; +import com.skyeye.common.util.mybatisplus.ListTypeHandler; + +import java.util.List; + +/** + * @ClassName: SkyeyeClassFlowableLinkListenerListTypeHandler + * @Description: 工作流业务对象服务对应的监听器集合转换处理类 + * @author: skyeye云系列--卫志强 + * @date: 2022/10/18 23:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class AttrTransformTableListTypeHandler extends ListTypeHandler { + + @Override + protected TypeReference> specificType() { + return new TypeReference>() { + }; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormComponent.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormComponent.java new file mode 100644 index 0000000..f8a4e1c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormComponent.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.IconOrImgInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: DsFormComponent + * @Description: 表单组件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 20:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"numCode"}) +@RedisCacheField(name = "dsForm:component") +@TableName(value = "ds_form_component", autoResultMap = true) +@ApiModel("表单组件实体类") +public class DsFormComponent extends IconOrImgInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("num_code") + @ApiModelProperty(value = "组件编码", required = "required", fuzzyLike = true) + private String numCode; + + @TableField("`name`") + @ApiModelProperty(value = "组件名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("type_id") + @ApiModelProperty(value = "组件分类", required = "required") + private String typeId; + + @TableField(exist = false) + @Property("组件分类名称") + private String typeName; + + @TableField("show_type") + @ApiModelProperty(value = "显示类型,参考#DsFormShowType", required = "required,num") + private Integer showType; + + @TableField("html_content") + @ApiModelProperty(value = "html内容", required = "required") + private String htmlContent; + + @TableField("html_data_from") + @ApiModelProperty(value = "数据展示来源的加载脚本") + private String htmlDataFrom; + + @TableField("js_content") + @ApiModelProperty(value = "组件初始化脚本") + private String jsContent; + + @TableField("js_value") + @ApiModelProperty(value = "获取值的脚本") + private String jsValue; + + @TableField("js_display_value") + @ApiModelProperty(value = "获取显示值的脚本") + private String jsDisplayValue; + + @TableField("js_fit_value") + @ApiModelProperty(value = "设置值的脚本") + private String jsFitValue; + + @TableField("linked_data") + @ApiModelProperty(value = "关联数据 1.是 2.否", required = "required,num") + private Integer linkedData; + + @TableField(value = "attr_keys", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "组件关联的属性,可参考#ComponentAttr", required = "json") + private List attrKeys; + + @TableField("apply_range") + @ApiModelProperty(value = "适用范围,参考#ComponentApplyRange", required = "required,num") + private Integer applyRange; + + @TableField(value = "apply_object", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "局部适用对象", required = "json") + private List applyObject; + + @TableField("value_merg_type") + @ApiModelProperty(value = "组件获取的值的合入接口入参的方式,参考#ComponentValueMergType", required = "required") + private String valueMergType; + + @TableField("detail_html_content") + @ApiModelProperty(value = "详情页面(showType=0):组件的html内容") + private String detailHtmlContent; + + @TableField("detail_js_content") + @ApiModelProperty(value = "详情页面(showType=0):组件的js脚本") + private String detailJsContent; + + @TableField("remark") + @ApiModelProperty(value = "组件备注") + private String remark; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormDisplayTemplate.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormDisplayTemplate.java new file mode 100644 index 0000000..6314b9b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormDisplayTemplate.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: DsFormDisplayTemplate + * @Description: 动态表单数据展示模板实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/10 17:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "dsForm:displayTemplate") +@TableName(value = "ds_form_display_template") +@ApiModel("动态表单数据展示模板实体类") +public class DsFormDisplayTemplate extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "模板名称", required = "required", fuzzyLike = true) + private String name; + + @TableField("content") + @ApiModelProperty(value = "模板脚本", required = "required") + private String content; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPage.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPage.java new file mode 100644 index 0000000..184ac2f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPage.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.operate.entity.Operate; +import com.skyeye.server.entity.ServiceBeanCustom; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: DsFormPage + * @Description: 表单布局实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/10 17:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField({"name", "className"}) +@RedisCacheField(name = "dsForm:page", value = {"id", "numCode"}, cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "ds_form_page", autoResultMap = true) +@ApiModel("表单布局实体类") +public class DsFormPage extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "简介") + private String remark; + + @TableField("num_code") + @Property("页面编码") + private String numCode; + + @TableField("`type`") + @ApiModelProperty(value = "表单布局的类型,可以参考#DsFormPageType", required = "required") + private String type; + + @TableField(value = "app_id") + @ApiModelProperty(value = "应用的appId", required = "required") + private String appId; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField("is_page") + @ApiModelProperty(value = "表格时拥有,是否分页,参考#WhetherEnum") + private Integer isPage; + + @TableField("search_tips") + @ApiModelProperty(value = "表格时拥有,搜索框提示语") + private String searchTips; + + @TableField(exist = false) + @Property(value = "服务类的信息") + private ServiceBeanCustom serviceBeanCustom; + + @TableField(exist = false) + @ApiModelProperty(value = "表单布局关联的接口信息", required = "required,json") + private BusinessApi businessApi; + + @TableField(exist = false) + @Property("表单布局关联的组件信息,非列表布局才拥有关联的组件信息") + private List dsFormPageContents; + + @TableField(exist = false) + @Property("表单布局关联的操作按钮信息,列表布局才拥有操作按钮信息") + private List operateList; + + @TableField(exist = false) + @Property("表单布局(表格类型关联的列信息)") + private List tableColumnList; + + @TableField("whether_choose") + @ApiModelProperty(value = "表格类型的布局是否开启选择功能") + private String whetherChoose; + + @TableField(value = "operate_id_list", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "页面关联的操作信息,可为空", required = "json") + private List operateIdList; + + @TableField("is_data_auth") + @ApiModelProperty(value = "表格时拥有,是否开启数据权限,参考#WhetherEnum") + private Integer isDataAuth; + + @TableField("data_auth_point_num") + @ApiModelProperty(value = "开启数据权限后,需要填写权限点编号(列表接口的权限点编号)") + private String dataAuthPointNum; + + @TableField("act_flow_id") + @ApiModelProperty(value = "工作流模型id") + private String actFlowId; + + @TableField("is_flowable") + @ApiModelProperty(value = "是否开启工作流,只有开启了工作流的业务对象可以设置这个字段,参考#WhetherEnum", required = "num") + private Integer isFlowable; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContent.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContent.java new file mode 100644 index 0000000..6e199cf --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContent.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: DsFormPageContent + * @Description: 表单布局关联的组件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/10 17:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "ds_form_page_content", autoResultMap = true) +@ApiModel("表单布局关联的组件实体类") +public class DsFormPageContent extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("title") + @ApiModelProperty(value = "左侧标题,例如:姓名") + private String title; + + @TableField("placeholder") + @ApiModelProperty(value = "文本提示语") + private String placeholder; + + @TableField(value = "`require`", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "组件限制条件") + private List require; + + @TableField("default_value") + @ApiModelProperty(value = "默认值") + private String defaultValue; + + @TableField("width") + @ApiModelProperty(value = "宽度", required = "required") + private String width; + + @TableField("pre_attribute") + @ApiModelProperty(value = "前置属性") + private String preAttribute; + + @TableField("post_attribute") + @ApiModelProperty(value = "后置属性") + private String postAttribute; + + @TableField("form_content_id") + @ApiModelProperty(value = "动态表单组件id", required = "required") + private String formContentId; + + @TableField(exist = false) + @Property("表单布局内的组件信息") + private DsFormComponent dsFormComponent; + + @TableField("page_id") + @Property("表单布局id") + private String pageId; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField("attr_key") + @ApiModelProperty(value = "属性key") + private String attrKey; + + @TableField(exist = false) + @Property("属性信息") + private AttrDefinition attrDefinition; + + @TableField("upload_num") + @ApiModelProperty(value = "限制上传的文件数量", required = "num") + private Integer uploadNum; + + @TableField(value = "upload_data_type", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "文件上传类型", required = "json") + private List uploadDataType; + + @TableField(value = "upload_type") + @ApiModelProperty(value = "文件上传类型", required = "num") + private Integer uploadType; + + @TableField(value = "data_show_type") + @ApiModelProperty(value = "枚举/数据字典类的数据展示类型") + private String dataShowType; + + @TableField(value = "team_object_type") + @ApiModelProperty(value = "团队适用对象(团队组件拥有)") + private String teamObjectType; + + @TableField("is_edit") + @ApiModelProperty(value = "是否可以编辑,参考#WhetherEnum") + private Integer isEdit; + + @TableField("date_time_type") + @ApiModelProperty(value = "日期组件的类型,参考#DateTimeType") + private String dateTimeType; + + @TableField("choose_or_not_my") + @ApiModelProperty(value = "人员列表中是否包含自己--1.包含;其他参数不包含") + private Integer chooseOrNotMy; + + @TableField("choose_or_not_email") + @ApiModelProperty(value = "人员列表中是否必须绑定邮箱--1.必须;其他参数没必要") + private Integer chooseOrNotEmail; + + @TableField("check_type") + @ApiModelProperty(value = "人员选择类型,1.多选;其他。单选") + private Integer checkType; + + @TableField(value = "attr_transform_table_list", typeHandler = AttrTransformTableListTypeHandler.class) + @ApiModelProperty(value = "展示类型为表格展示时的表格数据", required = "json") + private List attrTransformTableList; + + @TableField("min_data") + @ApiModelProperty(value = "表格组件最小数据行数") + private Integer minData; + + @TableField("delete_row_callback") + @ApiModelProperty(value = "删除行之后的回调函数") + private String deleteRowCallback; + + @TableField("add_row_callback") + @ApiModelProperty(value = "新增行之后的回调函数") + private String addRowCallback; + + @TableField("before_script") + @ApiModelProperty(value = "组件加载前执行的脚本") + private String beforeScript; + + @TableField("after_script") + @ApiModelProperty(value = "组件加载完成后执行的脚本") + private String afterScript; + + @TableField("after_html") + @ApiModelProperty(value = "组件加载完成后执行的HTML脚本") + private String afterHtml; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("class_name") + @ApiModelProperty(value = "class属性") + private String className; + + @TableField("edit_echo_script") + @ApiModelProperty(value = "数据编辑回显时执行的脚本") + private String editEchoScript; + + @TableField("data_change") + @ApiModelProperty(value = "数据变化监听的JS") + private String dataChange; + + @TableField("data_echo_after_script") + @ApiModelProperty(value = "数据回显完之后执行的脚本") + private String dataEchoAfterScript; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContentVo.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContentVo.java new file mode 100644 index 0000000..9ec111f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/DsFormPageContentVo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: DsFormPageContentVo + * @Description: 表单布局关联的组件保存接口的入参 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 16:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("表单布局关联的组件保存接口的入参") +public class DsFormPageContentVo implements Serializable { + + @ApiModelProperty(value = "表单布局id", required = "required") + private String pageId; + + @ApiModelProperty(value = "表单布局内的组件信息", required = "json") + private List dsFormPageContentList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumn.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumn.java new file mode 100644 index 0000000..b3c9101 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumn.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: TableColumn + * @Description: 表格布局的列属性 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/5 17:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"pageId", "attrKey"}) +@TableName(value = "ds_form_table_column") +@ApiModel("表格布局的列属性") +public class TableColumn extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("attr_key") + @ApiModelProperty(value = "属性key", required = "required") + private String attrKey; + + @TableField(exist = false) + @Property("属性信息") + private AttrDefinition attrDefinition; + + @TableField("width") + @ApiModelProperty(value = "宽度", required = "required") + private String width; + + @TableField("align") + @ApiModelProperty(value = "对其方式,参考#Alignment", required = "required") + private String align; + + @TableField("fixed") + @ApiModelProperty(value = "固定位置,参考#FixedType") + private String fixed; + + @TableField("hide") + @ApiModelProperty(value = "是否初始隐藏,参考#WhetherEnum") + private Integer hide; + + @TableField("templet") + @ApiModelProperty(value = "列内容展示的脚本,相当于表格中的templet") + private String templet; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField("page_id") + @Property("表单布局id") + private String pageId; + + @TableField("page_key") + @ApiModelProperty("布局类型") + private String pageKey; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumnVo.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumnVo.java new file mode 100644 index 0000000..2212b8a --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/entity/TableColumnVo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: TableColumnVo + * @Description: 表格布局的列属性保存接口的入参 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/5 17:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("表格布局的列属性保存接口的入参") +public class TableColumnVo implements Serializable { + + @ApiModelProperty(value = "表单布局id", required = "required") + private String pageId; + + @ApiModelProperty(value = "表单布局内的组件信息", required = "json") + private List tableColumnList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormComponentService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormComponentService.java new file mode 100644 index 0000000..d4df53d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormComponentService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormComponent; + +public interface DsFormComponentService extends SkyeyeBusinessService { + + void queryAllDsFormComponentList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormDisplayTemplateService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormDisplayTemplateService.java new file mode 100644 index 0000000..282ae05 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormDisplayTemplateService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormDisplayTemplate; + +public interface DsFormDisplayTemplateService extends SkyeyeBusinessService { + + void queryDisplayTemplateListToShow(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageContentService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageContentService.java new file mode 100644 index 0000000..e3af2e5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageContentService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.dsform.entity.DsFormPageContent; + +import java.util.List; + +/** + * @ClassName: DsFormPageContentService + * @Description: 动态表单页面内容项服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/8 16:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DsFormPageContentService extends SkyeyeBusinessService { + + /** + * 根据动态表单pageId获取动态表单的内容项 + * + * @param pageId 动态表单pageId + * @return 动态表单的内容项 + */ + List getDsFormPageContentByPageId(String pageId); + + void deleteDsFormContentByPageId(String pageId); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageService.java new file mode 100644 index 0000000..0683011 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/DsFormPageService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.entity.DsFormPage; + +public interface DsFormPageService extends SkyeyeBusinessService { + + void queryDsFormPageList(InputObject inputObject, OutputObject outputObject); + + void writeDsFormPageContent(InputObject inputObject, OutputObject outputObject); + + void writeDsFormPageTable(InputObject inputObject, OutputObject outputObject); + + void queryBusinessDataByObject(InputObject inputObject, OutputObject outputObject); + + void queryDsFormPageForProcess(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/TableColumnService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/TableColumnService.java new file mode 100644 index 0000000..beffbec --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/TableColumnService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.dsform.entity.TableColumn; + +import java.util.List; + +/** + * @ClassName: TableColumnService + * @Description: 表格布局的列属性服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/5 20:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TableColumnService extends SkyeyeBusinessService { + + List getTableColumnByPageId(String pageId, String pageKey); + + void createList(List entitys, String userId, String pageId, String pageKey); + + + void deleteByPageId(String pageId, String pageKey); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormComponentServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormComponentServiceImpl.java new file mode 100644 index 0000000..bdc1682 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormComponentServiceImpl.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.tree.Tree; +import com.google.common.base.Joiner; +import com.skyeye.attr.service.AttrDefinitionCustomService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.classenum.ComponentApplyRange; +import com.skyeye.dsform.dao.DsFormComponentDao; +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.dsform.service.DsFormComponentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DsFormComponentServiceImpl + * @Description: 表单组件管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本组件仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DsFormComponentServiceImpl extends SkyeyeBusinessServiceImpl implements DsFormComponentService { + + @Autowired + private AttrDefinitionCustomService attrDefinitionCustomService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + attrDefinitionCustomService.setDsFormComponentUseNum(beans); + return beans; + } + + /** + * 获取动态表单组件供展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllDsFormComponentList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String serviceClassName = params.get("serviceClassName").toString(); + + List formComponentList = list(); + // 过滤数据 + formComponentList = formComponentList.stream() + .filter(component -> { + if (component.getApplyRange().equals(ComponentApplyRange.GLOBALLY_APPLICABLE.getKey()) + || (component.getApplyRange().equals(ComponentApplyRange.LOCAL_APPLICATION.getKey()) && + CollectionUtil.isNotEmpty(component.getApplyObject()) && component.getApplyObject().indexOf(serviceClassName) >= 0)) { + // 适配全局对象适用并且局部范围内适用包含指定serviceClassName的 + return true; + } + return false; + }).collect(Collectors.toList()); + // 获取组件的详细信息 + List componentIds = formComponentList.stream() + .map(DsFormComponent::getId).collect(Collectors.toList()); + formComponentList = selectByIds(componentIds.toArray(new String[]{})); + iSysDictDataService.setName(formComponentList, "typeId", "typeName"); + + List> treeNodes = convertToTree(formComponentList); + + Map> result = formComponentList.stream() + .collect(Collectors.groupingBy(DsFormComponent::getTypeName)); + outputObject.setBean(result); + outputObject.setBeans(treeNodes); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private List> convertToTree(List formComponentList) { + // 批量获取数据字典类型 + Map> typeIdMap = formComponentList.stream() + .collect(Collectors.groupingBy(DsFormComponent::getTypeId)); + Map> dictDataMap = iSysDictDataService.queryDataMationForMapByIds( + Joiner.on(CommonCharConstants.COMMA_MARK).join(typeIdMap.keySet())); + // 转为树 + List> treeNodes = new ArrayList<>(); + typeIdMap.forEach((typeId, dsFormComponentList) -> { + Tree tree = new Tree<>(); + tree.setId(typeId); + tree.setName(dictDataMap.get(typeId).get("dictName").toString()); + tree.setParentId(String.valueOf(CommonNumConstants.NUM_ZERO)); + tree.putExtra("disabled", true); + + List> chiledren = new ArrayList<>(); + dsFormComponentList.forEach(dsFormComponent -> { + Tree componentNode = new Tree<>(); + componentNode.setId(dsFormComponent.getId()); + componentNode.setName(dsFormComponent.getName()); + componentNode.setParentId(dsFormComponent.getTypeId()); + componentNode.putExtra("disabled", false); + componentNode.putExtra("linkedData", dsFormComponent.getLinkedData()); + componentNode.putExtra("htmlDataFrom", dsFormComponent.getHtmlDataFrom()); + chiledren.add(componentNode); + }); + tree.setChildren(chiledren); + treeNodes.add(tree); + }); + return treeNodes; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormDisplayTemplateServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormDisplayTemplateServiceImpl.java new file mode 100644 index 0000000..5471905 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormDisplayTemplateServiceImpl.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service.impl; + +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dsform.dao.DsFormDisplayTemplateDao; +import com.skyeye.dsform.entity.DsFormDisplayTemplate; +import com.skyeye.dsform.service.DsFormDisplayTemplateService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DsFormDisplayTemplateServiceImpl + * @Description: 动态表单数据展示模板管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DsFormDisplayTemplateServiceImpl extends SkyeyeBusinessServiceImpl implements DsFormDisplayTemplateService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + /** + * 获取动态表单数据展示模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDisplayTemplateListToShow(InputObject inputObject, OutputObject outputObject) { + List beans = list(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageContentServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageContentServiceImpl.java new file mode 100644 index 0000000..679f510 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageContentServiceImpl.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.dao.DsFormPageContentDao; +import com.skyeye.dsform.entity.DsFormComponent; +import com.skyeye.dsform.entity.DsFormPageContent; +import com.skyeye.dsform.service.DsFormComponentService; +import com.skyeye.dsform.service.DsFormPageContentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DsFormPageContentServiceImpl + * @Description: 动态表单页面内容项服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/8 16:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class DsFormPageContentServiceImpl extends SkyeyeBusinessServiceImpl implements DsFormPageContentService { + + @Autowired + private RedisCache redisCache; + + @Autowired + private DsFormComponentService dsFormComponentService; + + /** + * 根据表单布局id获取组件列表 + * + * @param pageId 动态表单pageId + * @return 动态表单的内容项 + */ + @Override + public List getDsFormPageContentByPageId(String pageId) { + String cacheKey = getCacheKeyByPageId(pageId); + List dsFormPageContentList = redisCache.getList(cacheKey, key -> { + // 查询该表单布局绑定的组件信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(DsFormPageContent::getOrderBy)); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPageContent::getPageId), pageId); + return list(queryWrapper); + }, RedisConstants.ALL_USE_TIME, DsFormPageContent.class); + + // 获取组件信息 + List componentIds = dsFormPageContentList.stream().map(DsFormPageContent::getFormContentId).distinct().collect(Collectors.toList()); + Map dsFormComponentMap = dsFormComponentService.selectMapByIds(componentIds); + dsFormPageContentList.forEach(dsFormPageData -> { + dsFormPageData.setDsFormComponent(dsFormComponentMap.get(dsFormPageData.getFormContentId())); + }); + return dsFormPageContentList; + } + + @Override + public void deleteDsFormContentByPageId(String pageId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPageContent::getPageId), pageId); + remove(queryWrapper); + String cacheKey = getCacheKeyByPageId(pageId); + jedisClientService.del(cacheKey); + } + + private String getCacheKeyByPageId(String pageId) { + return String.format(Locale.ROOT, "skyeye:pageContent:pageId:%s", pageId); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageServiceImpl.java new file mode 100644 index 0000000..38275a6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/DsFormPageServiceImpl.java @@ -0,0 +1,279 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.attr.service.AttrDefinitionService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.business.service.BusinessApiService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.classenum.DsFormPageType; +import com.skyeye.dsform.dao.DsFormPageDao; +import com.skyeye.dsform.entity.*; +import com.skyeye.dsform.service.DsFormPageContentService; +import com.skyeye.dsform.service.DsFormPageService; +import com.skyeye.dsform.service.TableColumnService; +import com.skyeye.exception.CustomException; +import com.skyeye.operate.entity.Operate; +import com.skyeye.operate.service.OperateService; +import com.skyeye.sdk.data.service.IDataService; +import com.skyeye.server.entity.ServiceBeanCustom; +import com.skyeye.server.service.ServiceBeanCustomService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: DsFormPageServiceImpl + * @Description: 表单布局管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "表单布局管理", groupName = "动态表单") +public class DsFormPageServiceImpl extends SkyeyeBusinessServiceImpl implements DsFormPageService { + + @Autowired + private DsFormPageContentService dsFormPageContentService; + + @Autowired + private AttrDefinitionService attrDefinitionService; + + @Autowired + private OperateService operateService; + + @Autowired + private ServiceBeanCustomService serviceBeanCustomService; + + @Autowired + private BusinessApiService businessApiService; + + @Autowired + private TableColumnService tableColumnService; + + @Autowired + private IDataService iDataService; + + @Override + public void queryDsFormPageList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String appId = params.get("appId").toString(); + ServiceBeanCustom serviceBeanCustom = serviceBeanCustomService.selectServiceBeanCustom(appId, className); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(DsFormPage::getClassName), className); + wrapper.orderByDesc(MybatisPlusUtil.toColumns(DsFormPage::getCreateTime)); + List dsFormPageList = list(wrapper); + iAuthUserService.setName(dsFormPageList, "createId", "createName"); + iAuthUserService.setName(dsFormPageList, "lastUpdateId", "lastUpdateName"); + dsFormPageList.forEach(dsFormPage -> { + dsFormPage.setServiceBeanCustom(serviceBeanCustom); + }); + outputObject.setBeans(dsFormPageList); + outputObject.settotal(dsFormPageList.size()); + } + + @Override + public void validatorEntity(DsFormPage entity) { + super.validatorEntity(entity); + if (entity.getType().equals(DsFormPageType.PROCESS_ATTR.getKey())) { + if (StrUtil.isEmpty(entity.getActFlowId())) { + throw new CustomException("Process information cannot be empty."); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPage::getClassName), entity.getClassName()); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPage::getActFlowId), entity.getActFlowId()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + DsFormPage dsFormPage = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(dsFormPage)) { + throw new CustomException("the process has been bound to layout."); + } + } + } + + @Override + public void createPrepose(DsFormPage entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + entity.setNumCode(oddNumber); + } + + @Override + public void writePostpose(DsFormPage entity, String userId) { + super.writePostpose(entity, userId); + // 保存请求事件 + BusinessApi businessApi = entity.getBusinessApi(); + businessApi.setObjectId(entity.getId()); + businessApi.setObjectKey(getServiceClassName()); + businessApiService.createEntity(businessApi, userId); + } + + @Override + public void deletePostpose(DsFormPage dsFormPage) { + if (StrUtil.equals(dsFormPage.getType(), DsFormPageType.SIMPLE_TABLE.getKey())) { + // 删除页面内容项信息 + dsFormPageContentService.deleteDsFormContentByPageId(dsFormPage.getId()); + } else { + // 删除表单布局(表格类型关联的列信息) + tableColumnService.deleteByPageId(dsFormPage.getId(), getServiceClassName()); + } + } + + @Override + public DsFormPage selectById(String id) { + DsFormPage dsFormPage = super.selectById(id); + if (!StrUtil.equals(dsFormPage.getType(), DsFormPageType.SIMPLE_TABLE.getKey())) { + // 查询表单布局的内容信息 + selectPageContent(dsFormPage); + } else { + // 查询表格的字段列信息 + selectTableColumn(dsFormPage); + } + if (CollectionUtil.isNotEmpty(dsFormPage.getOperateIdList())) { + // 获取操作信息 + List operateList = operateService.getOperatesByClassName(dsFormPage.getAppId(), dsFormPage.getClassName()); + operateList = operateList.stream().filter(operate -> dsFormPage.getOperateIdList().contains(operate.getId())).collect(Collectors.toList()); + dsFormPage.setOperateList(operateList); + } + + // 接口信息 + BusinessApi businessApi = businessApiService.selectByObjectId(dsFormPage.getId()); + dsFormPage.setBusinessApi(businessApi); + + // 服务类的信息 + ServiceBeanCustom serviceBeanCustom = serviceBeanCustomService.selectServiceBeanCustom(dsFormPage.getAppId(), dsFormPage.getClassName()); + dsFormPage.setServiceBeanCustom(serviceBeanCustom); + + return dsFormPage; + } + + private void selectPageContent(DsFormPage dsFormPage) { + List dsFormPageContents = dsFormPageContentService.getDsFormPageContentByPageId(dsFormPage.getId()); + dsFormPage.setDsFormPageContents(dsFormPageContents); + // 获取属性信息 + List attrKeys = dsFormPageContents.stream().filter(bean -> StrUtil.isNotEmpty(bean.getAttrKey())).map(DsFormPageContent::getAttrKey).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(attrKeys)) { + Map attrDefinitionMap = attrDefinitionService.queryAttrDefinitionMap(dsFormPage.getAppId(), dsFormPage.getClassName(), attrKeys); + dsFormPageContents.forEach(dsFormPageContent -> { + if (StrUtil.isNotEmpty(dsFormPageContent.getAttrKey())) { + dsFormPageContent.setAttrDefinition(attrDefinitionMap.get(dsFormPageContent.getAttrKey())); + } + }); + } + } + + private void selectTableColumn(DsFormPage dsFormPage) { + List tableColumnList = tableColumnService.getTableColumnByPageId(dsFormPage.getId(), getServiceClassName()); + // 获取属性信息 + List attrKeys = tableColumnList.stream().map(TableColumn::getAttrKey).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(attrKeys)) { + Map attrDefinitionMap = attrDefinitionService.queryAttrDefinitionMap(dsFormPage.getAppId(), dsFormPage.getClassName(), attrKeys); + tableColumnList.forEach(tableColumn -> { + tableColumn.setAttrDefinition(attrDefinitionMap.get(tableColumn.getAttrKey())); + }); + } + dsFormPage.setTableColumnList(tableColumnList); + } + + /** + * 保存表单布局关联的组件信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void writeDsFormPageContent(InputObject inputObject, OutputObject outputObject) { + DsFormPageContentVo dsFormPageContentVo = inputObject.getParams(DsFormPageContentVo.class); + List dsFormPageContentList = dsFormPageContentVo.getDsFormPageContentList(); + dsFormPageContentList.forEach(dsFormPageContent -> { + dsFormPageContent.setPageId(dsFormPageContentVo.getPageId()); + }); + // 删除之前已经保存的 + dsFormPageContentService.deleteDsFormContentByPageId(dsFormPageContentVo.getPageId()); + // 保存新的组件关联信息 + String userId = inputObject.getLogParams().get("id").toString(); + dsFormPageContentService.createEntity(dsFormPageContentList, userId); + // 刷新表单布局的缓存 + refreshCache(dsFormPageContentVo.getPageId()); + } + + /** + * 保存表格类型的布局的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void writeDsFormPageTable(InputObject inputObject, OutputObject outputObject) { + TableColumnVo tableColumnVo = inputObject.getParams(TableColumnVo.class); + String userId = inputObject.getLogParams().get("id").toString(); + tableColumnService.createList(tableColumnVo.getTableColumnList(), userId, tableColumnVo.getPageId(), getServiceClassName()); + } + + /** + * 根据业务数据id获取业务数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryBusinessDataByObject(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String objectKey = params.get("objectKey").toString(); + // 获取业务数据 + Map businessData = iDataService.getDataByObjectId(null, objectId, objectKey); + outputObject.setBean(businessData); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据业务对象的serviceClassName和流程模型id查找表单布局 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDsFormPageForProcess(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String serviceClassName = params.get("serviceClassName").toString(); + String actFlowId = params.get("actFlowId").toString(); + // 根据业务对象的serviceClassName和流程模型id查询 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPage::getClassName), serviceClassName); + queryWrapper.eq(MybatisPlusUtil.toColumns(DsFormPage::getActFlowId), actFlowId); + queryWrapper.select(CommonConstants.ID); + DsFormPage dsFormPage = getOne(queryWrapper); + if (ObjectUtil.isEmpty(dsFormPage)) { + throw new CustomException("未配置流程布局."); + } + dsFormPage = selectById(dsFormPage.getId()); + outputObject.setBean(dsFormPage); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/TableColumnServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/TableColumnServiceImpl.java new file mode 100644 index 0000000..88b43ea --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/dsform/service/impl/TableColumnServiceImpl.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dsform.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.dao.TableColumnDao; +import com.skyeye.dsform.entity.TableColumn; +import com.skyeye.dsform.service.DsFormPageService; +import com.skyeye.dsform.service.TableColumnService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Locale; + +/** + * @ClassName: TableColumnServiceImpl + * @Description: 表格布局的列属性服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/5 20:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "表格布局的列属性", groupName = "动态表单", manageShow = false) +public class TableColumnServiceImpl extends SkyeyeBusinessServiceImpl implements TableColumnService { + + @Autowired + private RedisCache redisCache; + + @Autowired + private DsFormPageService dsFormPageService; + + @Override + public List getTableColumnByPageId(String pageId, String pageKey) { + String cacheKey = getCacheKeyByPageId(pageId, pageKey); + List tableColumns = redisCache.getList(cacheKey, key -> { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.orderByAsc(MybatisPlusUtil.toColumns(TableColumn::getOrderBy)); + wrapper.eq(MybatisPlusUtil.toColumns(TableColumn::getPageId), pageId); + wrapper.eq(MybatisPlusUtil.toColumns(TableColumn::getPageKey), pageKey); + List tableColumnList = list(wrapper); + return tableColumnList; + }, RedisConstants.ALL_USE_TIME, TableColumn.class); + return tableColumns; + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void createList(List entitys, String userId, String pageId, String pageKey) { + deleteByPageId(pageId, pageKey); + entitys.forEach(tableColumn -> { + tableColumn.setPageId(pageId); + if (StrUtil.equals(pageKey, dsFormPageService.getServiceClassName())) { + tableColumn.setPageKey(pageKey); + } else { + if (StrUtil.isEmpty(tableColumn.getPageKey())) { + throw new CustomException("布局类型为空"); + } + } + }); + createEntity(entitys, userId); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = {Exception.class}) + public void deleteByPageId(String pageId, String pageKey) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TableColumn::getPageId), pageId); + queryWrapper.eq(MybatisPlusUtil.toColumns(TableColumn::getPageKey), pageKey); + remove(queryWrapper); + // 清空缓存 + String cacheKey = getCacheKeyByPageId(pageId, pageKey); + jedisClientService.del(cacheKey); + } + + private String getCacheKeyByPageId(String pageId, String pageKey) { + return String.format(Locale.ROOT, "skyeye:tableColumn:pageId:%s:%s", pageKey, pageId); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/BarCodeController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/BarCodeController.java new file mode 100644 index 0000000..da13181 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/BarCodeController.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.barcode.BarCodeApiMation; +import com.skyeye.eve.service.BarCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BarCodeController + * @Description: 条形码管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "条形码", tags = "条形码", modelName = "系统公共模块") +public class BarCodeController { + + @Autowired + private BarCodeService barCodeService; + + /** + * 批量新增条形码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBarCode", value = "批量新增条形码", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = BarCodeApiMation.class) + @RequestMapping("/post/BarCodeController/writeBarCode") + public void writeBarCode(InputObject inputObject, OutputObject outputObject) { + barCodeService.writeBarCode(inputObject, outputObject); + } + + /** + * 根据条形码code获取数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getDataByBarCode", value = "根据条形码code获取数据信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "barCode", name = "barCode", value = "条形码code", required = "required")}) + @RequestMapping("/post/BarCodeController/getDataByBarCode") + public void getDataByBarCode(InputObject inputObject, OutputObject outputObject) { + barCodeService.getDataByBarCode(inputObject, outputObject); + } + + /** + * 根据业务数据id获取条形码数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBarCodeByObjectIds", value = "根据业务数据id获取条形码数据", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "springApplicationName", name = "springApplicationName", value = "服务名", required = "required"), + @ApiImplicitParam(id = "codeImplClass", name = "codeImplClass", value = "条形码类型,对应的服务层类地址", required = "required"), + @ApiImplicitParam(id = "objectIds", name = "objectIds", value = "业务数据id集合", required = "required,json")}) + @RequestMapping("/post/BarCodeController/queryBarCodeByObjectIds") + public void queryBarCodeByObjectIds(InputObject inputObject, OutputObject outputObject) { + barCodeService.queryBarCodeByObjectIds(inputObject, outputObject); + } + + /** + * 根据业务数据id删除条形码数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBarCodeByObjectId", value = "根据业务数据id删除条形码数据", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "业务数据id", required = "required")}) + @RequestMapping("/post/BarCodeController/deleteBarCodeByObjectId") + public void deleteBarCodeByObjectId(InputObject inputObject, OutputObject outputObject) { + barCodeService.deleteBarCodeByObjectId(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SearchConfigController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SearchConfigController.java new file mode 100644 index 0000000..d362e5c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SearchConfigController.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.search.SearchMation; +import com.skyeye.eve.service.SearchConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SearchConfigController + * @Description: 高级查询配置管理类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/16 16:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "高级查询配置", tags = "高级查询配置", modelName = "系统公共模块") +public class SearchConfigController { + + @Autowired + private SearchConfigService searchConfigService; + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于前台使用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySearchParamsConfigToHtml", value = "根据urlId以及appId获取高级查询的参数配置信息----用于前台使用", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "urlId", name = "urlId", value = "接口的urlId", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "微服务的APPID", required = "required")}) + @RequestMapping("/post/SearchConfigController/querySearchParamsConfigToHtml") + public void querySearchParamsConfigToHtml(InputObject inputObject, OutputObject outputObject) { + searchConfigService.querySearchParamsConfigToHtml(inputObject, outputObject); + } + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于后台使用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySearchParamsConfig", value = "根据urlId以及appId获取高级查询的参数配置信息----用于后台使用", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "urlId", name = "urlId", value = "接口的urlId", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "微服务的APPID", required = "required")}) + @RequestMapping("/post/SearchConfigController/querySearchParamsConfig") + public void querySearchParamsConfig(InputObject inputObject, OutputObject outputObject) { + searchConfigService.querySearchParamsConfig(inputObject, outputObject); + } + + /** + * 新增/编辑高级查询配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSearchConfigMation", value = "新增/编辑高级查询配置", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SearchMation.class) + @RequestMapping("/post/SearchConfigController/writeSearchConfigMation") + public void writeSearchConfigMation(InputObject inputObject, OutputObject outputObject) { + searchConfigService.writeSearchConfigMation(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictDataController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictDataController.java new file mode 100644 index 0000000..69e555b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictDataController.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.dict.SysDictData; +import com.skyeye.eve.service.SysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysDictDataController + * @Description: 数据字典管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "数据字典", tags = "数据字典", modelName = "数据字典") +public class SysDictDataController { + + @Autowired + private SysDictDataService sysDictDataService; + + /** + * 获取数据字典列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictDataList", value = "获取数据字典列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class, value = { + @ApiImplicitParam(id = "dictTypeId", name = "dictTypeId", value = "数据字典分类id")}) + @RequestMapping("/post/SysDictDataController/queryDictDataList") + public void queryDictDataList(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑数据字典 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDictDataMation", value = "新增/编辑数据字典", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysDictData.class) + @RequestMapping("/post/SysDictDataController/writeDictDataMation") + public void writeDictDataMation(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID获取数据字典信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictDataMationById", value = "根据ID获取数据字典信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysDictDataController/queryDictDataMationById") + public void queryDictDataMationById(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.selectById(inputObject, outputObject); + } + + /** + * 根据IDs批量获取数据字典信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictDataMationByIds", value = "根据IDs批量获取数据字典信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个用逗号隔开", required = "required")}) + @RequestMapping("/post/SysDictDataController/queryDictDataMationByIds") + public void queryDictDataMationByIds(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.selectByIds(inputObject, outputObject); + } + + /** + * 根据ID删除数据字典 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDictDataMationById", value = "根据ID删除数据字典", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysDictDataController/deleteDictDataMationById") + public void deleteDictDataMationById(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.deleteById(inputObject, outputObject); + } + + /** + * 根据所属类型Code获取数据字典列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictDataListByDictTypeCode", value = "根据所属类型Code获取数据字典列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "dictTypeCode", name = "dictTypeCode", value = "所属类型Code", required = "required")}) + @RequestMapping("/post/SysDictDataController/queryDictDataListByDictTypeCode") + public void queryDictDataListByDictTypeCode(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.queryDictDataListByDictTypeCode(inputObject, outputObject); + } + + /** + * 获取指定分类下不等于指定ID的数据字典集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictDataListByDictTypeCodeAndNotId", value = "获取指定分类下不等于指定ID的数据字典集合", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "dictTypeCode", name = "dictTypeCode", value = "所属类型Code", required = "required"), + @ApiImplicitParam(id = "notId", name = "notId", value = "不等于这个ID")}) + @RequestMapping("/post/SysDictDataController/queryDictDataListByDictTypeCodeAndNotId") + public void queryDictDataListByDictTypeCodeAndNotId(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.queryDictDataListByDictTypeCodeAndNotId(inputObject, outputObject); + } + + /** + * 移动位置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setDictDataParent", value = "移动位置", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "数据字典id", required = "required"), + @ApiImplicitParam(id = "parentId", name = "parentId", value = "父节点id", required = "required")}) + @RequestMapping("/post/SysDictDataController/setDictDataParent") + public void setDictDataParent(InputObject inputObject, OutputObject outputObject) { + sysDictDataService.setDictDataParent(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictTypeController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictTypeController.java new file mode 100644 index 0000000..b4b0833 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysDictTypeController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.dict.SysDictType; +import com.skyeye.eve.service.SysDictTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysDictTypeController + * @Description: 数据字典类型管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "数据字典类型管理", tags = "数据字典类型管理", modelName = "数据字典") +public class SysDictTypeController { + + @Autowired + private SysDictTypeService sysDictTypeService; + + /** + * 获取数据字典类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictTypeList", value = "获取数据字典类型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysDictTypeController/queryDictTypeList") + public void queryDictTypeList(InputObject inputObject, OutputObject outputObject) { + sysDictTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑数据字典类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDictTypeMation", value = "新增/编辑数据字典类型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysDictType.class) + @RequestMapping("/post/SysDictTypeController/writeDictTypeMation") + public void writeDictTypeMation(InputObject inputObject, OutputObject outputObject) { + sysDictTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID获取数据字典类型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictTypeMationById", value = "根据ID获取数据字典类型信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysDictTypeController/queryDictTypeMationById") + public void queryDictTypeMationById(InputObject inputObject, OutputObject outputObject) { + sysDictTypeService.selectById(inputObject, outputObject); + } + + /** + * 根据ID删除数据字典类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDictTypeMationById", value = "根据ID删除数据字典类型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysDictTypeController/deleteDictTypeMationById") + public void deleteDictTypeMationById(InputObject inputObject, OutputObject outputObject) { + sysDictTypeService.deleteById(inputObject, outputObject); + } + + /** + * 根据状态获取数据字典类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDictTypeListByEnabled", value = "根据状态获取数据字典类型列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "enabled", name = "enabled", value = "状态(1 启用 2.停用)", required = "num")}) + @RequestMapping("/post/SysDictTypeController/queryDictTypeListByEnabled") + public void queryDictTypeListByEnabled(InputObject inputObject, OutputObject outputObject) { + sysDictTypeService.queryDictTypeListByEnabled(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelController.java new file mode 100644 index 0000000..661ff38 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.sysmodel.SysEveModelQueryDo; +import com.skyeye.eve.service.SysEveModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveModelController + * @Description: 系统编辑器模板管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:26 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "系统编辑器模板", tags = "系统编辑器模板", modelName = "系统公共模块") +public class SysEveModelController { + + @Autowired + private SysEveModelService sysEveModelService; + + /** + * 获取系统编辑器模板表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysevemodel001", value = "获取系统编辑器模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysEveModelQueryDo.class) + @RequestMapping("/post/SysEveModelController/querySysEveModelList") + public void querySysEveModelList(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.querySysEveModelList(inputObject, outputObject); + } + + /** + * 新增系统编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelController/insertSysEveModelMation") + public void insertSysEveModelMation(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.insertSysEveModelMation(inputObject, outputObject); + } + + /** + * 删除系统编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelController/deleteSysEveModelById") + public void deleteSysEveModelById(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.deleteSysEveModelById(inputObject, outputObject); + } + + /** + * 通过id查找对应的系统编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelController/selectSysEveModelById") + public void selectSysEveModelById(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.selectSysEveModelById(inputObject, outputObject); + } + + /** + * 通过id编辑对应的系统编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelController/editSysEveModelMationById") + public void editSysEveModelMationById(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.editSysEveModelMationById(inputObject, outputObject); + } + + /** + * 通过id查找对应的系统编辑器模板详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelController/selectSysEveModelMationById") + public void selectSysEveModelMationById(InputObject inputObject, OutputObject outputObject) { + sysEveModelService.selectSysEveModelMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelTypeController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelTypeController.java new file mode 100644 index 0000000..2992a2d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SysEveModelTypeController.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.SysEveModelTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SysEveModelTypeController { + + @Autowired + private SysEveModelTypeService sysEveModelTypeService; + + /** + * 获取系统模板分类列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/querySysEveModelTypeList") + public void querySysEveModelTypeList(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.querySysEveModelTypeList(inputObject, outputObject); + } + + /** + * 新增系统模板分类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/insertSysEveModelType") + public void insertSysEveModelType(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.insertSysEveModelType(inputObject, outputObject); + } + + /** + * 删除系统模板分类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/delSysEveModelTypeById") + public void delSysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.delSysEveModelTypeById(inputObject, outputObject); + } + + /** + * 根据id查询系统模板分类详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/querySysEveModelTypeById") + public void querySysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.querySysEveModelTypeById(inputObject, outputObject); + } + + /** + * 通过id编辑对应的系统模板分类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/updateSysEveModelTypeById") + public void updateSysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.updateSysEveModelTypeById(inputObject, outputObject); + } + + /** + * 通过parentId查找对应的系统模板分类列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveModelTypeController/querySysEveModelTypeByParentId") + public void querySysEveModelTypeByParentId(InputObject inputObject, OutputObject outputObject) { + sysEveModelTypeService.querySysEveModelTypeByParentId(inputObject, outputObject); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SystemFoundationSettingsController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SystemFoundationSettingsController.java new file mode 100644 index 0000000..ec7bd27 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/controller/SystemFoundationSettingsController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.SystemFoundationSettings; +import com.skyeye.eve.service.SystemFoundationSettingsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SystemFoundationSettingsController + * @Description: 系统基础设置控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "系统基础设置", tags = "系统基础设置", modelName = "系统基础设置") +public class SystemFoundationSettingsController { + + @Autowired + private SystemFoundationSettingsService systemFoundationSettingsService; + + @ApiOperation(id = "sysfdsettings001", value = "获取系统基础设置", method = "GET", allUse = "2") + @RequestMapping("/post/SystemFoundationSettingsController/querySystemFoundationSettingsList") + public void querySystemFoundationSettingsList(InputObject inputObject, OutputObject outputObject) { + systemFoundationSettingsService.querySystemFoundationSettingsList(inputObject, outputObject); + } + + @ApiOperation(id = "sysfdsettings002", value = "编辑系统基础设置", method = "PUT", allUse = "1") + @ApiImplicitParams(classBean = SystemFoundationSettings.class) + @RequestMapping("/post/SystemFoundationSettingsController/editSystemFoundationSettings") + public void editSystemFoundationSettings(InputObject inputObject, OutputObject outputObject) { + systemFoundationSettingsService.updateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/BarCodeDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/BarCodeDao.java new file mode 100644 index 0000000..570cb96 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/BarCodeDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.barcode.BarCodeMation; + +/** + * @ClassName: BarCodeDao + * @Description: 条形码数据管理层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BarCodeDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SearchDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SearchDao.java new file mode 100644 index 0000000..831e72d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SearchDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.search.SearchMation; + +/** + * @ClassName: SearchDao + * @Description: 高级查询属性配置管理数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:31 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SearchDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictDataDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictDataDao.java new file mode 100644 index 0000000..05491ea --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictDataDao.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.dict.SysDictData; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysDictDataDao + * @Description: 数据字典类型管理数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:31 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysDictDataDao extends SkyeyeBaseMapper { + + List> queryDictDataList(Map map); + + List queryDictDataListByDictTypeCode(@Param("dictTypeCpde") String dictTypeCpde, @Param("enabled") Integer enabled); + + /** + * 根据子id查询所有的父节点信息(包含子节点信息) + * + * @param ids 子id + * @return + */ + List> queryAllParentNodeById(@Param("ids") List ids); + + /** + * 根据父id查询所有的子节点信息(包含父id) + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictTypeDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictTypeDao.java new file mode 100644 index 0000000..3162ab1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysDictTypeDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.dict.SysDictType; + +/** + * @ClassName: SysDictTypeDao + * @Description: 数据字典类型管理数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:31 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysDictTypeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelDao.java new file mode 100644 index 0000000..35a7b78 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelDao.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.sysmodel.SysEveModelQueryDo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveModelDao + * @Description: 系统编辑器模板数据层 + * @author: skyeye云系列 + * @date: 2021/11/14 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveModelDao { + + List> querySysEveModelList(SysEveModelQueryDo sysEveModelQuery); + + Map querySysEveModelMationByNameAndType(Map map); + + int insertSysEveModelMation(Map map); + + int deleteSysEveModelById(@Param("id") String id); + + Map selectSysEveModelMationById(@Param("id") String id); + + int editSysEveModelMationById(Map map); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelTypeDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelTypeDao.java new file mode 100644 index 0000000..7ef024b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SysEveModelTypeDao.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveModelTypeDao + * @Description: 系统模板分类数据层 + * @author: skyeye云系列 + * @date: 2021/11/13 10:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveModelTypeDao { + + List> querySysEveModelTypeList(Map map); + + void insertSysEveModelType(Map map); + + Map querySysEveModelTypeById(@Param("id") String id); + + String querySysEveModelTypeByParentIdAndTypeName(Map map); + + List> querySysEveModelTypeByParentId(@Param("parentId") String parentId); + + void updateSysEveModelTypeById(Map map); + + void delSysEveModelTypeById(@Param("id") String id); + + void delSysEveModelTypeByParentId(@Param("parentId") String parentId); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SystemFoundationSettingsDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SystemFoundationSettingsDao.java new file mode 100644 index 0000000..4b0e7e1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/dao/SystemFoundationSettingsDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.eve.entity.SystemFoundationSettings; + +/** + * @ClassName: SystemFoundationSettingsDao + * @Description: 系统基础设置数据交互类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SystemFoundationSettingsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/SystemFoundationSettings.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/SystemFoundationSettings.java new file mode 100644 index 0000000..aed690d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/SystemFoundationSettings.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SystemFoundationSettings + * @Description: 系统基础设置实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/1 22:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = CacheConstants.SYSTEM_FOUNDATION_SETTINGS_CACHE_KEY) +@TableName(value = "system_foundation_settings", autoResultMap = true) +@ApiModel("系统基础设置实体类") +public class SystemFoundationSettings extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("email_type") + @ApiModelProperty(value = "邮箱类型", required = "required") + private String emailType; + + @TableField("email_receipt_server") + @ApiModelProperty(value = "收件服务器", required = "required") + private String emailReceiptServer; + + @TableField("email_receipt_server_port") + @ApiModelProperty(value = "收件服务器ssl端口", required = "required") + private String emailReceiptServerPort; + + @TableField("email_send_server") + @ApiModelProperty(value = "发件服务器", required = "required") + private String emailSendServer; + + @TableField("email_send_server_port") + @ApiModelProperty(value = "发件服务器ssl端口", required = "required") + private String emailSendServerPort; + + @TableField("no_documentary_day_num") + @ApiModelProperty(value = "未跟单天数,N天未跟单自动进入公海", required = "num") + private Integer noDocumentaryDayNum; + + @TableField("no_charge_id") + @ApiModelProperty(value = "未指定负责人,未指定责任人自动进入公海", required = "num") + private Integer noChargeId; + + @TableField(value = "holidays_type_json", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "企业假期类型以及扣薪信息", required = "required,json") + private List> holidaysTypeJson; + + @TableField(value = "year_holidays_mation", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "年假信息", required = "required,json") + private List> yearHolidaysMation; + + @TableField(value = "abnormal_mation", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "异常考勤制度管理信息", required = "required,json") + private List> abnormalMation; + + @TableField(value = "sys_order_basic_design", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "系统单据是否需要审核的设置", required = "required,json") + private List> sysOrderBasicDesign; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeApiMation.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeApiMation.java new file mode 100644 index 0000000..fb84442 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeApiMation.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.barcode; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: BarCodeApiMation + * @Description: 条形码实体类外面的box + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:57 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("条形码实体类外面的box") +public class BarCodeApiMation extends CommonInfo implements Serializable { + + @ApiModelProperty(value = "服务名", required = "required") + private String springApplicationName; + + @ApiModelProperty(value = "条形码类型,对应的服务层类地址", required = "required") + private String codeImplClass; + + @ApiModelProperty(value = "条形码列表", required = "required") + private List barCodeList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeMation.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeMation.java new file mode 100644 index 0000000..62bbeb4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/barcode/BarCodeMation.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.barcode; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: BarCodeMation + * @Description: 条形码实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:45 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "bar_code") +@ApiModel("条形码实体类") +public class BarCodeMation extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("object_id") + @ApiModelProperty(value = "关联的业务数据id,例如资产明细id", required = "required") + private String objectId; + + @TableField("code_num") + @ApiModelProperty(value = "条形码编号", required = "required") + private String codeNum; + + /** + * 服务名 + */ + @TableField("spring_application_name") + private String springApplicationName; + + /** + * 条形码类型,对应的服务层类地址 + */ + @TableField("code_impl_class") + private String codeImplClass; + + @TableField("image_path") + @ApiModelProperty(value = "条形码路径", required = "required") + private String imagePath; + + /** + * 录入日期 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private String createTime; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictData.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictData.java new file mode 100644 index 0000000..73e0045 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictData.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.dict; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysDictDataMation + * @Description: 数据字典实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/2 13:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"dictName", "dictTypeId"}) +@RedisCacheField(name = CacheConstants.DICT_DATA_CACHE_KEY) +@TableName(value = "sys_dict_data") +@ApiModel("数据字典实体类") +public class SysDictData extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("dict_name") + @ApiModelProperty(value = "字典名称", required = "required") + private String dictName; + + /** + * 多级节点时,节点路径名称 + */ + @TableField(exist = false) + private String pathName; + + @TableField("dict_type_id") + @ApiModelProperty(value = "数据字典类型id", required = "required") + private String dictTypeId; + + @TableField("dict_sort") + @ApiModelProperty(value = "字典排序", required = "required,num") + private Integer dictSort; + + @TableField("parent_id") + @ApiModelProperty(value = "父节点id", required = "required") + private String parentId; + + @TableField("level") + @ApiModelProperty(value = "级别", required = "required,num") + private Integer level; + + @TableField("is_default") + @ApiModelProperty(value = "是否默认 1.是 2.否", required = "required,num") + private Integer isDefault; + + @TableField("remark") + @ApiModelProperty(value = "备注信息") + private String remark; + + @TableField("enabled") + @ApiModelProperty(value = "状态(1 启用 2.停用)", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictType.java new file mode 100644 index 0000000..59eccd4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/dict/SysDictType.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.dict; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysDictType + * @Description: 数据字典类型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_dict_type") +@ApiModel("数据字典类型实体类") +public class SysDictType extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("dict_name") + @ApiModelProperty(value = "字典分类名称", required = "required", fuzzyLike = true) + private String dictName; + + @TableField("dict_code") + @ApiModelProperty(value = "字典分类CODE,需要保证唯一", required = "required", fuzzyLike = true) + private String dictCode; + + @TableField("remark") + @ApiModelProperty(value = "备注信息") + private String remark; + + @TableField("dict_type") + @ApiModelProperty(value = "字典类型 1. 一级分类 2. 多级分类", required = "required,num") + private Integer dictType; + + @TableField("choose_level") + @ApiModelProperty(value = "几级之后的可以选择,比如设置2级(包含2级)之后的可以选择", required = "required,num") + private Integer chooseLevel; + + @TableField("enabled") + @ApiModelProperty(value = "状态(1 启用 2.停用)", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/search/SearchMation.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/search/SearchMation.java new file mode 100644 index 0000000..2f5733b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/search/SearchMation.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.search; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.eve.search.entity.SearchParamsConfigMation; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: SearchMation + * @Description: 高级查询配置实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/12 11:01 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_search") +@ApiModel("高级查询配置实体类") +public class SearchMation extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("app_id") + @ApiModelProperty(value = "APPID", required = "required") + private String appId; + + @TableField("url_id") + @ApiModelProperty(value = "接口对应的url的id", required = "required") + private String urlId; + + @TableField(exist = false) + @ApiModelProperty(value = "参数配置信息", required = "required") + private Map paramsConfig; + + /** + * 参数配置信息json字符串 + */ + @TableField("params_config") + private String paramsConfigStr; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/sysmodel/SysEveModelQueryDo.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/sysmodel/SysEveModelQueryDo.java new file mode 100644 index 0000000..41f6baa --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/entity/sysmodel/SysEveModelQueryDo.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.sysmodel; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: SysEveModelQueryDo + * @Description: 系统编辑器模板查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("系统编辑器模板查询条件实体类") +public class SysEveModelQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "标题") + private String title; + + @ApiModelProperty(value = "模板类型 1.系统模板 2.个人模板") + private String type; + + @ApiModelProperty(value = "所属一级分类") + private String firstTypeId; + + @ApiModelProperty(value = "所属二级分类") + private String secondTypeId; + + /** + * 用户id + */ + private String userId; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/BarCodeService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/BarCodeService.java new file mode 100644 index 0000000..7129c6c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/BarCodeService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.barcode.BarCodeMation; + +/** + * @ClassName: BarCodeService + * @Description: 条形码服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:42 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BarCodeService extends SkyeyeBusinessService { + + void writeBarCode(InputObject inputObject, OutputObject outputObject); + + void getDataByBarCode(InputObject inputObject, OutputObject outputObject); + + void queryBarCodeByObjectIds(InputObject inputObject, OutputObject outputObject); + + void deleteBarCodeByObjectId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SearchConfigService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SearchConfigService.java new file mode 100644 index 0000000..d123bda --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SearchConfigService.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.search.SearchMation; + +import java.util.Map; + +public interface SearchConfigService { + + void querySearchParamsConfigToHtml(InputObject inputObject, OutputObject outputObject); + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于前台使用 + * + * @param urlId urlId + * @param appId appId + * @return 高级查询的参数配置信息 + */ + Map querySearchParamsConfigToHtml(String urlId, String appId); + + void querySearchParamsConfig(InputObject inputObject, OutputObject outputObject); + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于后台使用 + * + * @param urlId urlId + * @param appId appId + * @return 高级查询的参数配置信息 + */ + Map querySearchParamsConfig(String urlId, String appId); + + void writeSearchConfigMation(InputObject inputObject, OutputObject outputObject); + + /** + * 根据urlId以及appId获取高级查询信息 + * + * @param urlId urlId + * @param appId appId + * @return 高级查询信息 + */ + SearchMation querySearchMation(String urlId, String appId); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictDataService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictDataService.java new file mode 100644 index 0000000..2b94130 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictDataService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.dict.SysDictData; + +/** + * @ClassName: SysDictDataService + * @Description: 数据字典服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/2 13:18 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysDictDataService extends SkyeyeBusinessService { + + void queryDictDataListByDictTypeCode(InputObject inputObject, OutputObject outputObject); + + void queryDictDataListByDictTypeCodeAndNotId(InputObject inputObject, OutputObject outputObject); + + void setDictDataParent(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictTypeService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictTypeService.java new file mode 100644 index 0000000..524b919 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysDictTypeService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.dict.SysDictType; + +/** + * @ClassName: SysDictTypeService + * @Description: 数据字典类型管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysDictTypeService extends SkyeyeBusinessService { + + void queryDictTypeListByEnabled(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelService.java new file mode 100644 index 0000000..2fbedaf --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface SysEveModelService { + + void querySysEveModelList(InputObject inputObject, OutputObject outputObject); + + void insertSysEveModelMation(InputObject inputObject, OutputObject outputObject); + + void deleteSysEveModelById(InputObject inputObject, OutputObject outputObject); + + void selectSysEveModelById(InputObject inputObject, OutputObject outputObject); + + void selectSysEveModelMationById(InputObject inputObject, OutputObject outputObject); + + void editSysEveModelMationById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelTypeService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelTypeService.java new file mode 100644 index 0000000..99638f1 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SysEveModelTypeService.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: SysEveModelTypeService + * @Description: 系统模板分类业务层 + * @author: skyeye云系列 + * @date: 2021/11/13 11:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveModelTypeService { + + /** + * 获取系统模板分类列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void querySysEveModelTypeList(InputObject inputObject, OutputObject outputObject); + + /** + * 新增系统模板分类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void insertSysEveModelType(InputObject inputObject, OutputObject outputObject); + + /** + * 根据id查询系统模板分类详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void querySysEveModelTypeById(InputObject inputObject, OutputObject outputObject); + + /** + * 通过parentId查找对应的系统模板分类列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void querySysEveModelTypeByParentId(InputObject inputObject, OutputObject outputObject); + + /** + * 通过id编辑对应的系统模板分类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void updateSysEveModelTypeById(InputObject inputObject, OutputObject outputObject); + + /** + * 删除系统模板分类 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void delSysEveModelTypeById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SystemFoundationSettingsService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SystemFoundationSettingsService.java new file mode 100644 index 0000000..5e28f5b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/SystemFoundationSettingsService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.SystemFoundationSettings; + +import java.util.Map; + +/** + * @ClassName: SystemFoundationSettingsService + * @Description: 系统基础设置服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SystemFoundationSettingsService extends SkyeyeBusinessService { + + void querySystemFoundationSettingsList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/BarCodeServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/BarCodeServiceImpl.java new file mode 100644 index 0000000..e0e8c1f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/BarCodeServiceImpl.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.BarCodeDao; +import com.skyeye.eve.entity.barcode.BarCodeApiMation; +import com.skyeye.eve.entity.barcode.BarCodeMation; +import com.skyeye.eve.service.BarCodeService; +import com.skyeye.sdk.data.service.IDataService; +import net.sf.json.JSONArray; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: BarCodeServiceImpl + * @Description: 条形码服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 9:42 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class BarCodeServiceImpl extends SkyeyeBusinessServiceImpl implements BarCodeService { + + @Autowired + private BarCodeDao barCodeDao; + + @Autowired + private IDataService iDataService; + + @Autowired + private DiscoveryClient discoveryClient; + + @Value("${IMAGES_PATH}") + private String tPath; + + /** + * 批量新增条形码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void writeBarCode(InputObject inputObject, OutputObject outputObject) { + BarCodeApiMation barCodeApiMation = inputObject.getParams(BarCodeApiMation.class); + List barCodeList = barCodeApiMation.getBarCodeList(); + String createTime = DateUtil.getTimeAndToString(); + barCodeList.forEach(barCodeMation -> { + barCodeMation.setSpringApplicationName(barCodeApiMation.getSpringApplicationName()); + barCodeMation.setCodeImplClass(barCodeApiMation.getCodeImplClass()); + barCodeMation.setCreateTime(createTime); + }); + this.saveBatch(barCodeList); + } + + /** + * 根据条形码code获取数据信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getDataByBarCode(InputObject inputObject, OutputObject outputObject) { + String barCode = inputObject.getParams().get("barCode").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BarCodeMation::getCodeNum), barCode); + BarCodeMation barCodeMation = barCodeDao.selectOne(queryWrapper); + + // 根据服务名获取服务实例 + List allInstances = discoveryClient.getInstances(barCodeMation.getSpringApplicationName()); + if (CollectionUtils.isEmpty(allInstances)) { + outputObject.setreturnMessage("this service[{}] has no instance.", barCodeMation.getSpringApplicationName()); + return; + } + + // 调用SDK服务获取数据信息 + Map result = iDataService.getDataByObjectId(allInstances.get(0).getUri(), barCodeMation.getObjectId(), + barCodeMation.getCodeImplClass()); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据业务数据id获取条形码数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryBarCodeByObjectIds(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String springApplicationName = params.get("springApplicationName").toString(); + String codeImplClass = params.get("codeImplClass").toString(); + List objectIds = JSONArray.fromObject(params.get("objectIds").toString()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BarCodeMation::getSpringApplicationName), springApplicationName); + queryWrapper.eq(MybatisPlusUtil.toColumns(BarCodeMation::getCodeImplClass), codeImplClass); + queryWrapper.in(MybatisPlusUtil.toColumns(BarCodeMation::getObjectId), objectIds); + List barCodeMationList = super.list(queryWrapper); + outputObject.setBeans(barCodeMationList); + outputObject.settotal(barCodeMationList.size()); + } + + @Override + public void deleteBarCodeByObjectId(InputObject inputObject, OutputObject outputObject) { + String objectId = inputObject.getParams().get("objectId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BarCodeMation::getObjectId), objectId); + BarCodeMation barCodeMation = getOne(queryWrapper, false); + // 删除图片路径 + String basePath = tPath + barCodeMation.getImagePath().replace("/images/", ""); + FileUtil.deleteFile(basePath); + // 删除数据 + deleteById(barCodeMation.getId()); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SearchConfigServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SearchConfigServiceImpl.java new file mode 100644 index 0000000..ebd2558 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SearchConfigServiceImpl.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.SearchDao; +import com.skyeye.eve.entity.search.SearchMation; +import com.skyeye.eve.search.entity.SearchOperatorMation; +import com.skyeye.eve.search.entity.SearchParamsConfigMation; +import com.skyeye.eve.search.service.ISearchConfigService; +import com.skyeye.eve.service.SearchConfigService; +import com.skyeye.jedis.JedisClientService; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +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.ObjectUtils; + +import java.util.List; +import java.util.Map; + +@Service +public class SearchConfigServiceImpl implements SearchConfigService { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchConfigServiceImpl.class); + + @Autowired + private SearchDao searchDao; + + @Autowired + private ISearchConfigService iSearchConfigService; + + @Autowired + private JedisClientService jedisService; + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于前台使用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySearchParamsConfigToHtml(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String urlId = params.get("urlId").toString(); + String appId = params.get("appId").toString(); + Map result = this.querySearchParamsConfigToHtml(urlId, appId); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于前台使用 + * + * @param urlId urlId + * @param appId appId + * @return 高级查询的参数配置信息 + */ + @Override + public Map querySearchParamsConfigToHtml(String urlId, String appId) { + Map result = querySearchParamsConfig(urlId, appId); + if (result != null) { + result.forEach((key, value) -> { + String valueStr = JSONUtil.toJsonStr(value); + SearchParamsConfigMation searchParamsConfigMation = JSONUtil.toBean(valueStr, SearchParamsConfigMation.class); + // 获取筛选条件 + List searchCondition = searchParamsConfigMation.getSearchCondition(); + if (CollectionUtils.isNotEmpty(searchCondition)) { + searchCondition.forEach(bean -> { + bean.setMySql(null); + bean.setOracle(null); + bean.setPgSql(null); + bean.setSqlServer(null); + }); + } + result.put(key, searchParamsConfigMation); + }); + return result; + } + return null; + } + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于后台使用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySearchParamsConfig(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String urlId = params.get("urlId").toString(); + String appId = params.get("appId").toString(); + Map result = this.querySearchParamsConfig(urlId, appId); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据urlId以及appId获取高级查询的参数配置信息----用于后台使用 + * + * @param urlId urlId + * @param appId appId + * @return 高级查询的参数配置信息 + */ + @Override + public Map querySearchParamsConfig(String urlId, String appId) { + SearchMation searchMation = querySearchMation(urlId, appId); + if (searchMation != null) { + Map result = JSONUtil.toBean(searchMation.getParamsConfigStr(), null); + return result; + } + return null; + } + + /** + * 新增/编辑高级查询配置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void writeSearchConfigMation(InputObject inputObject, OutputObject outputObject) { + SearchMation searchMation = inputObject.getParams(SearchMation.class); + // 1.根据appId和urlId进行校验 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SearchMation::getAppId), searchMation.getAppId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(SearchMation::getUrlId), searchMation.getUrlId()); + if (StringUtils.isNotEmpty(searchMation.getId())) { + queryWrapper.ne(CommonConstants.ID, searchMation.getId()); + } + SearchMation checkSearchMation = searchDao.selectOne(queryWrapper); + if (ObjectUtils.isEmpty(checkSearchMation)) { + searchMation.setParamsConfigStr(JSONUtil.toJsonStr(searchMation.getParamsConfig())); + // 2.新增/编辑数据 + if (StringUtils.isNotEmpty(searchMation.getId())) { + LOGGER.info("update searchConfig data, id is {}", searchMation.getId()); + searchDao.updateById(searchMation); + } else { + DataCommonUtil.setId(searchMation); + LOGGER.info("insert searchConfig data, id is {}", searchMation.getId()); + searchDao.insert(searchMation); + } + // 删除缓存 + String searchParamsConfigCacheKey = iSearchConfigService.querySearchParamsConfigCacheKeyById(searchMation.getUrlId(), searchMation.getAppId()); + String searchParamsConfigToHtmlCacheKey = iSearchConfigService.querySearchParamsConfigToHtmlCacheKeyById(searchMation.getUrlId(), searchMation.getAppId()); + jedisService.del(searchParamsConfigCacheKey); + jedisService.del(searchParamsConfigToHtmlCacheKey); + outputObject.setBean(searchMation); + } else { + outputObject.setreturnMessage("this data is non-existent."); + } + } + + @Override + public SearchMation querySearchMation(String urlId, String appId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SearchMation::getUrlId), urlId); + queryWrapper.eq(MybatisPlusUtil.toColumns(SearchMation::getAppId), appId); + return searchDao.selectOne(queryWrapper); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictDataServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..5c513c3 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.SysDictDataDao; +import com.skyeye.eve.dao.SysDictTypeDao; +import com.skyeye.eve.entity.dict.SysDictData; +import com.skyeye.eve.entity.dict.SysDictType; +import com.skyeye.eve.service.SysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SysDictDataServiceImpl + * @Description: 数据字典服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/2 13:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "数据字典", groupName = "数据字典") +public class SysDictDataServiceImpl extends SkyeyeBusinessServiceImpl implements SysDictDataService { + + @Autowired + private SysDictTypeDao sysDictTypeDao; + + @Override + public List> queryPageDataList(InputObject inputObject) { + Map map = inputObject.getParams(); + List> beans = skyeyeBaseMapper.queryDictDataList(map); + return beans; + } + + @Override + public void writePostpose(SysDictData entity, String userId) { + super.writePostpose(entity, userId); + // 设置默认值 + setIsDefault(entity); + } + + private void setIsDefault(SysDictData sysDictData) { + if (sysDictData.getIsDefault().equals(IsDefaultEnum.IS_DEFAULT.getKey())) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(SysDictData::getDictTypeId), sysDictData.getDictTypeId()); + updateWrapper.ne(CommonConstants.ID, sysDictData.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(SysDictData::getIsDefault), IsDefaultEnum.NOT_DEFAULT.getKey()); + update(null, updateWrapper); + } + } + + @Override + public SysDictData selectById(String id) { + SysDictData sysDictData = super.selectById(id); + + // 设置路径名称 + Map>> groupByMap = getParentNameMap(Arrays.asList(id)); + List> parentList = groupByMap.get(id); + if (CollectionUtil.isNotEmpty(parentList)) { + List names = parentList.stream().map(bean -> bean.get("name").toString()).collect(Collectors.toList()); + sysDictData.setPathName(Joiner.on(CommonCharConstants.SLASH_MARK).join(names)); + } + + return sysDictData; + } + + private Map>> getParentNameMap(List ids) { + List> parentNames = skyeyeBaseMapper.queryAllParentNodeById(ids); + if (CollectionUtil.isEmpty(parentNames)) { + return new HashMap<>(); + } + Map>> groupByMap = parentNames.stream() + .sorted(Comparator.comparing(bean -> bean.get("level").toString(), Comparator.reverseOrder())) + .collect(Collectors.groupingBy(bean -> bean.get("childId").toString())); + return groupByMap; + } + + @Override + public List selectByIds(String... ids) { + List sysDictDataList = super.selectByIds(ids); + // 设置路径名称 + Map>> groupByMap = getParentNameMap(Arrays.asList(ids)); + sysDictDataList.forEach(sysDictData -> { + List> parentList = groupByMap.get(sysDictData.getId()); + if (CollectionUtil.isNotEmpty(parentList)) { + List names = parentList.stream().map(bean -> bean.get("name").toString()).collect(Collectors.toList()); + sysDictData.setPathName(Joiner.on(CommonCharConstants.SLASH_MARK).join(names)); + } + }); + return sysDictDataList; + } + + /** + * 根据所属类型Code获取数据字典列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDictDataListByDictTypeCode(InputObject inputObject, OutputObject outputObject) { + String dictTypeCode = inputObject.getParams().get("dictTypeCode").toString(); + List dictDataList = skyeyeBaseMapper.queryDictDataListByDictTypeCode(dictTypeCode, EnableEnum.ENABLE_USING.getKey()); + if (CollectionUtil.isEmpty(dictDataList)) { + return; + } + List> result = new ArrayList<>(); + for (SysDictData bean : dictDataList) { + Map map = JSONObject.parseObject(JSONObject.toJSONString(bean), Map.class); + map.put("name", map.get("dictName")); + result.add(map); + } + + List> listTree = ToolUtil.listToTree(result, "id", "parentId", "children"); + SysDictType sysDictType = sysDictTypeDao.selectById(dictDataList.get(0).getDictTypeId()); + resetCheckNode(listTree, 1, sysDictType.getChooseLevel()); + outputObject.setBeans(result); + outputObject.setCustomBeans("treeRows", listTree); + outputObject.settotal(result.size()); + } + + private void resetCheckNode(List> listTree, int parentLevel, int chooseLevel) { + listTree.forEach(node -> { + if (parentLevel < chooseLevel) { + node.put("nocheck", true); + List> child = (List>) node.get("children"); + if (CollectionUtil.isNotEmpty(child)) { + resetCheckNode(child, parentLevel + 1, chooseLevel); + } + } + }); + } + + /** + * 获取指定分类下不等于指定ID的数据字典集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDictDataListByDictTypeCodeAndNotId(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String dictTypeCode = params.get("dictTypeCode").toString(); + String notId = params.get("notId").toString(); + // 获取所有的数据字典 + List dictDataList = skyeyeBaseMapper.queryDictDataListByDictTypeCode(dictTypeCode, EnableEnum.ENABLE_USING.getKey()); + if (!ToolUtil.isBlank(notId)) { + // 移除不需要查询的节点,包含子节点 + List childId = skyeyeBaseMapper.queryAllChildIdsByParentId(Arrays.asList(notId)); + dictDataList = dictDataList.stream().filter(bean -> !childId.contains(bean.getId())).collect(Collectors.toList()); + } + List> result = new ArrayList<>(); + for (SysDictData bean : dictDataList) { + Map map = JSONObject.parseObject(JSONObject.toJSONString(bean), Map.class); + map.put("name", map.get("dictName")); + result.add(map); + } + result = ToolUtil.listToTree(result, "id", "parentId", "children"); + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + + /** + * 移动位置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void setDictDataParent(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String parentId = params.get("parentId").toString(); + UpdateWrapper wrapper = new UpdateWrapper<>(); + wrapper.eq(CommonConstants.ID, id); + wrapper.set(MybatisPlusUtil.toColumns(SysDictData::getParentId), parentId); + update(null, wrapper); + refreshCache(id); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictTypeServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..69454cd --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.SysDictTypeDao; +import com.skyeye.eve.entity.dict.SysDictType; +import com.skyeye.eve.service.SysDictTypeService; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysDictTypeServiceImpl + * @Description: 数据字典类型管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:31 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "数据字典类型", groupName = "数据字典") +public class SysDictTypeServiceImpl extends SkyeyeBusinessServiceImpl implements SysDictTypeService { + + @Override + public void validatorEntity(SysDictType entity) { + // 根据dictName和dictCode进行校验 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(SysDictType::getDictName), entity.getDictName()) + .or().eq(MybatisPlusUtil.toColumns(SysDictType::getDictCode), entity.getDictCode())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SysDictType checkDictType = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkDictType)) { + throw new CustomException("this name or dictCode is exist."); + } + } + + /** + * 根据状态获取数据字典类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDictTypeListByEnabled(InputObject inputObject, OutputObject outputObject) { + String enabled = inputObject.getParams().get("enabled").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(SysDictType::getDictName)); + if (StringUtils.isNotEmpty(enabled)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(SysDictType::getEnabled), enabled); + } + List dictTypeList = list(queryWrapper); + List> result = new ArrayList<>(); + for (SysDictType bean : dictTypeList) { + Map map = BeanUtil.beanToMap(bean); + map.put("name", map.get("dictName")); + map.put("pId", CommonNumConstants.NUM_ZERO); + result.add(map); + } + outputObject.setBeans(result); + outputObject.settotal(result.size()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelServiceImpl.java new file mode 100644 index 0000000..456fb57 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelServiceImpl.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.SysEveModelDao; +import com.skyeye.eve.entity.sysmodel.SysEveModelQueryDo; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.eve.service.SysEveModelService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveModelServiceImpl + * @Description: 系统编辑器模板服务类 + * @author: skyeye云系列 + * @date: 2021/11/14 9:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SysEveModelServiceImpl implements SysEveModelService { + + @Autowired + private SysEveModelDao sysEveModelDao; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private IAuthUserService iAuthUserService; + + /** + * 获取系统编辑器模板表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysEveModelList(InputObject inputObject, OutputObject outputObject) { + SysEveModelQueryDo sysEveModelQuery = inputObject.getParams(SysEveModelQueryDo.class); + sysEveModelQuery.setUserId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(sysEveModelQuery.getPage(), sysEveModelQuery.getLimit()); + List> beans = sysEveModelDao.querySysEveModelList(sysEveModelQuery); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 新增系统编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertSysEveModelMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + Map bean = sysEveModelDao.querySysEveModelMationByNameAndType(map); + if (bean != null && !bean.isEmpty()) { + outputObject.setreturnMessage("该系统编辑器模板已存在,请更换"); + } else { + map.put("id", ToolUtil.getSurFaceId()); + map.put("createTime", DateUtil.getTimeAndToString()); + sysEveModelDao.insertSysEveModelMation(map); + } + } + + /** + * 删除编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteSysEveModelById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Map bean = sysEveModelDao.selectSysEveModelMationById(id); + if (bean != null && !bean.isEmpty()) { + FileUtil.deleteFile(tPath.replace("images", "") + bean.get("logo").toString()); + sysEveModelDao.deleteSysEveModelById(id); + } + } + + /** + * 通过id查找对应的编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void selectSysEveModelById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Map bean = sysEveModelDao.selectSysEveModelMationById(id); + outputObject.setBean(bean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 通过id编辑对应的编辑器模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editSysEveModelMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + Map bean = sysEveModelDao.querySysEveModelMationByNameAndType(map); + if (bean != null && !bean.isEmpty()) { + outputObject.setreturnMessage("该编辑器模板已存在,请更换"); + } else { + map.put("lastUpdateTime", DateUtil.getTimeAndToString()); + sysEveModelDao.editSysEveModelMationById(map); + } + } + + /** + * 通过id查找对应的编辑器模板详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void selectSysEveModelMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Map bean = sysEveModelDao.selectSysEveModelMationById(id); + outputObject.setBean(bean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} + diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelTypeServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelTypeServiceImpl.java new file mode 100644 index 0000000..38500e2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SysEveModelTypeServiceImpl.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.SysEveModelTypeDao; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.eve.service.SysEveModelTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveModelTypeServiceImpl + * @Description: 系统模板分类业务实现层 + * @author: skyeye云系列 + * @date: 2021/11/13 10:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SysEveModelTypeServiceImpl implements SysEveModelTypeService { + + @Autowired + private SysEveModelTypeDao sysEveModelTypeDao; + + @Autowired + private IAuthUserService iAuthUserService; + + /** + * 获取系统模板分类列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysEveModelTypeList(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + List> beans = sysEveModelTypeDao.querySysEveModelTypeList(inputParams); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + iAuthUserService.setNameForMap(beans, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void insertSysEveModelType(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + if (checkParentIdExists(inputParams, outputObject)) { + return; + } + inputParams.put("id", ToolUtil.getSurFaceId()); + inputParams.put("createTime", DateUtil.getTimeAndToString()); + inputParams.put("userId", inputObject.getLogParams().get("id")); + sysEveModelTypeDao.insertSysEveModelType(inputParams); + } + + @Override + public void querySysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + Map sysEveModelTypeBean = sysEveModelTypeDao.querySysEveModelTypeById(inputParams.get("id").toString()); + outputObject.setBean(sysEveModelTypeBean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void querySysEveModelTypeByParentId(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + List> sysEveModelTypeList = sysEveModelTypeDao.querySysEveModelTypeByParentId(inputParams.get("parentId").toString()); + outputObject.setBeans(sysEveModelTypeList); + outputObject.settotal(sysEveModelTypeList.size()); + } + + @Override + public void updateSysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + if (checkParentIdExists(inputParams, outputObject)) { + return; + } + inputParams.put("lastUpdateTime", DateUtil.getTimeAndToString()); + inputParams.put("userId", inputObject.getLogParams().get("id")); + sysEveModelTypeDao.updateSysEveModelTypeById(inputParams); + } + + /** + * 校验parentId是否存在 + * + * @param inputParams + * @param outputObject 出参以及提示信息的返回值对象 + * @return true: parentId+typeName存在, 反之false + */ + private boolean checkParentIdExists(Map inputParams, OutputObject outputObject) { + String tempId = sysEveModelTypeDao.querySysEveModelTypeByParentIdAndTypeName(inputParams); + if (tempId == null || tempId.equals(inputParams.get("id"))) { + return false; + } + outputObject.setreturnMessage("父节点下已存在该分类名称."); + return true; + } + + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void delSysEveModelTypeById(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + String id = inputParams.get("id").toString(); + // 根据Id删除该节点id被作为parentId使用的其他页面分类数据 + sysEveModelTypeDao.delSysEveModelTypeByParentId(id); + sysEveModelTypeDao.delSysEveModelTypeById(id); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SystemFoundationSettingsServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SystemFoundationSettingsServiceImpl.java new file mode 100644 index 0000000..fe91521 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/eve/service/impl/SystemFoundationSettingsServiceImpl.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.dao.SystemFoundationSettingsDao; +import com.skyeye.eve.entity.SystemFoundationSettings; +import com.skyeye.eve.service.SystemFoundationSettingsService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: SystemFoundationSettingsServiceImpl + * @Description: 系统基础设置服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/6 22:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "系统基础设置", groupName = "系统基础设置") +public class SystemFoundationSettingsServiceImpl extends SkyeyeBusinessServiceImpl implements SystemFoundationSettingsService { + + @Override + public void querySystemFoundationSettingsList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + SystemFoundationSettings systemFoundationSettings = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(systemFoundationSettings)) { + throw new RuntimeException("系统基础设置不存在,请先添加!"); + } + outputObject.setBean(systemFoundationSettings); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/executor/ExecutorConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/executor/ExecutorConfig.java new file mode 100644 index 0000000..5a0db22 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/executor/ExecutorConfig.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.executor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +/** + * @ClassName: ExecutorConfig + * @Description: 异步任务配置类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 22:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@ManagedResource +public class ExecutorConfig { + + @Bean(name = "codeRuleExecutor") + public Executor getDetailsAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(5); + executor.setQueueCapacity(1000000); + executor.setThreadNamePrefix("codeRuleExecutor-"); + executor.initialize(); + return executor; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/config/FileAutoConfiguration.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/config/FileAutoConfiguration.java new file mode 100644 index 0000000..720f7cc --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/config/FileAutoConfiguration.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.config; + +import com.skyeye.framework.file.core.client.FileClientFactory; +import com.skyeye.framework.file.core.client.FileClientFactoryImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: FileAutoConfiguration + * @Description: 文件配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +public class FileAutoConfiguration { + + @Bean + public FileClientFactory fileClientFactory() { + return new FileClientFactoryImpl(); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/AbstractFileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/AbstractFileClient.java new file mode 100644 index 0000000..438f687 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/AbstractFileClient.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client; + +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: AbstractFileClient + * @Description: 文件客户端的抽象类,提供模板方法,减少子类的冗余代码 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 9:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractFileClient implements FileClient { + + /** + * 配置编号 + */ + private final String id; + /** + * 文件配置 + */ + protected Config config; + + public AbstractFileClient(String id, Config config) { + this.id = id; + this.config = config; + } + + /** + * 初始化 + */ + public final void init() { + doInit(); + log.debug("[init][配置({}) 初始化完成]", config); + } + + /** + * 自定义初始化 + */ + protected abstract void doInit(); + + public final void refresh(Config config) { + // 判断是否更新 + if (config.equals(this.config)) { + return; + } + log.info("[refresh][配置({})发生变化,重新初始化]", config); + this.config = config; + // 初始化 + this.init(); + } + + @Override + public String getId() { + return id; + } + + /** + * 格式化文件的 URL 访问地址 + * 使用场景:local、ftp、db,通过 FileController 的 getFile 来获取文件内容 + * + * @param path 文件路径 + * @return URL 访问地址 + */ + protected String formatFileUrl(String path) { + return StrUtil.format("/upload/{}/get/{}", getId(), path); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClient.java new file mode 100644 index 0000000..0fe9959 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClient.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client; + +import com.skyeye.framework.file.core.client.s3.FilePresignedUrlRespDTO; + +/** + * @ClassName: FileClient + * @Description: 文件客户端 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 12:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileClient { + + /** + * 获得客户端编号 + * + * @return 客户端编号 + */ + String getId(); + + /** + * 上传文件 + * + * @param content 文件流 + * @param path 相对路径 + * @return 完整路径,即 HTTP 访问地址 + * @throws Exception 上传文件时,抛出 Exception 异常 + */ + String upload(byte[] content, String path, String type) throws Exception; + + /** + * 删除文件 + * + * @param path 相对路径 + * @throws Exception 删除文件时,抛出 Exception 异常 + */ + void delete(String path) throws Exception; + + /** + * 获得文件的内容 + * + * @param path 相对路径 + * @return 文件的内容 + */ + byte[] getContent(String path) throws Exception; + + /** + * 获得文件预签名地址 + * + * @param path 相对路径 + * @return 文件预签名地址 + */ + default FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception { + throw new UnsupportedOperationException("不支持的操作"); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientConfig.java new file mode 100644 index 0000000..aca2f76 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientConfig.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client; + +import javax.validation.Validator; + +/** + * @ClassName: FileClientConfig + * @Description: 文件客户端的配置,不同实现的客户端,需要不同的配置,通过子类来定义 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 9:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileClientConfig { + + /** + * 参数校验 + * + * @param validator 校验对象 + */ + void validate(Validator validator); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactory.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactory.java new file mode 100644 index 0000000..3537906 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactory.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client; + +import com.skyeye.upload.enums.FileStorageEnum; + +public interface FileClientFactory { + + /** + * 移除文件客户端 + * + * @param configId 配置编号 + */ + void removeFileClient(String configId); + + /** + * 获得文件客户端 + * + * @param configId 配置编号 + * @return 文件客户端 + */ + FileClient getFileClient(String configId); + + /** + * 创建文件客户端 + * + * @param configId 配置编号 + * @param storage 存储器的枚举 {@link FileStorageEnum} + * @param config 文件配置 + */ + void createOrUpdateFileClient(String configId, Integer storage, Config config); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactoryImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactoryImpl.java new file mode 100644 index 0000000..4211f79 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/FileClientFactoryImpl.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ReflectUtil; +import com.skyeye.upload.enums.FileStorageEnum; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @ClassName: FileClientFactoryImpl + * @Description: 文件客户端的工厂实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 9:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class FileClientFactoryImpl implements FileClientFactory { + + /** + * 文件客户端 Map + * key:配置编号 + */ + private final ConcurrentMap> clients = new ConcurrentHashMap<>(); + + @Override + public void removeFileClient(String configId) { + clients.remove(configId); + } + + @Override + public FileClient getFileClient(String configId) { + AbstractFileClient client = clients.get(configId); + if (client == null) { + log.error("[getFileClient][配置编号({}) 找不到客户端]", configId); + } + return client; + } + + @Override + public void createOrUpdateFileClient(String configId, Integer storage, Config config) { + AbstractFileClient client = (AbstractFileClient) clients.get(configId); + if (client == null) { + client = this.createFileClient(configId, storage, config); + client.init(); + clients.put(client.getId(), client); + } else { + client.refresh(config); + } + } + + private AbstractFileClient createFileClient( + String configId, Integer storage, Config config) { + FileStorageEnum storageEnum = FileStorageEnum.getByStorage(storage); + Assert.notNull(storageEnum, String.format("文件配置(%s) 为空", storageEnum)); + // 创建客户端 + return (AbstractFileClient) ReflectUtil.newInstance(storageEnum.getClientClass(), configId, config); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClient.java new file mode 100644 index 0000000..49f1425 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClient.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.db; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.skyeye.framework.file.core.client.AbstractFileClient; +import com.skyeye.upload.entity.FileContent; +import com.skyeye.upload.service.FileContentService; + +/** + * @ClassName: DBFileClient + * @Description: 基于 DB 存储的文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class DBFileClient extends AbstractFileClient { + + private FileContentService fileContentService; + + public DBFileClient(String id, DBFileClientConfig config) { + super(id, config); + } + + @Override + protected void doInit() { + fileContentService = SpringUtil.getBean(FileContentService.class); + } + + @Override + public String upload(byte[] content, String path, String type) { + FileContent fileContent = new FileContent(); + fileContent.setConfigId(getId()); + fileContent.setPath(path); + fileContent.setContent(content); + fileContentService.createEntity(fileContent, StrUtil.EMPTY); + // 拼接返回路径 + return super.formatFileUrl(path); + } + + @Override + public void delete(String path) { + fileContentService.deleteByPath(path); + } + + @Override + public byte[] getContent(String path) { + FileContent fileContent = fileContentService.queryByPath(path); + return fileContent.getContent(); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClientConfig.java new file mode 100644 index 0000000..3ff1678 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/db/DBFileClientConfig.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.db; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; + +/** + * @ClassName: DBFileClientConfig + * @Description: 基于 DB 存储的文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 10:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("基于 DB 存储的文件客户端的配置类") +public class DBFileClientConfig implements FileClientConfig { + + @NotBlank(message = "自定义域名", groups = {Config.class}) + private String domain; + + public interface Config { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, Config.class); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClient.java new file mode 100644 index 0000000..289aeac --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClient.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.ftp; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.ftp.Ftp; +import cn.hutool.extra.ftp.FtpException; +import com.skyeye.framework.file.core.client.AbstractFileClient; +import com.skyeye.upload.enums.FileFtpMode; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +/** + * @ClassName: FtpFileClient + * @Description: Ftp 文件客户端 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class FtpFileClient extends AbstractFileClient { + + private Ftp ftp; + + public FtpFileClient(String id, FtpFileClientConfig config) { + super(id, config); + } + + @Override + protected void doInit() { + // 把配置的 \ 替换成 /, 如果路径配置 \a\test, 替换成 /a/test, 替换方法已经处理 null 情况 + config.setBasePath(StrUtil.replace(config.getBasePath(), StrUtil.BACKSLASH, StrUtil.SLASH)); + // ftp的路径是 / 结尾 + if (!config.getBasePath().endsWith(StrUtil.SLASH)) { + config.setBasePath(config.getBasePath() + StrUtil.SLASH); + } + + // 初始化 Ftp 对象 + this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(), + CharsetUtil.CHARSET_UTF_8, null, null, FileFtpMode.getFtpModeByKey(config.getMode())); + } + + @Override + public String upload(byte[] content, String path, String type) { + // 执行写入 + String filePath = getFilePath(path); + String fileName = FileUtil.getName(filePath); + String dir = StrUtil.removeSuffix(filePath, fileName); + ftp.reconnectIfTimeout(); + boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content)); + if (!success) { + throw new FtpException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath)); + } + // 拼接返回路径 + return super.formatFileUrl(path); + } + + @Override + public void delete(String path) { + String filePath = getFilePath(path); + ftp.reconnectIfTimeout(); + ftp.delFile(filePath); + } + + @Override + public byte[] getContent(String path) { + String filePath = getFilePath(path); + String fileName = FileUtil.getName(filePath); + String dir = StrUtil.removeSuffix(filePath, fileName); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ftp.reconnectIfTimeout(); + ftp.download(dir, fileName, out); + return out.toByteArray(); + } + + private String getFilePath(String path) { + return config.getBasePath() + path; + } + +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClientConfig.java new file mode 100644 index 0000000..698cf8e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/ftp/FtpFileClientConfig.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.ftp; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @ClassName: FtpFileClientConfig + * @Description: Ftp 文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 11:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("Ftp 文件客户端的配置类") +public class FtpFileClientConfig implements FileClientConfig { + + @NotBlank(message = "基础路径", groups = {Config.class}) + private String basePath; + + @NotBlank(message = "自定义域名", groups = {Config.class}) + private String domain; + + @NotBlank(message = "主机地址", groups = {Config.class}) + private String host; + + @NotNull(message = "主机端口", groups = {Config.class}) + private Integer port; + + @NotBlank(message = "用户名", groups = {Config.class}) + private String username; + + @NotBlank(message = "密码", groups = {Config.class}) + private String password; + + /** + * 连接模式 + *

+ * 使用 {@link cn.hutool.extra.ftp.FtpMode} 对应的字符串 + */ + @NotBlank(message = "连接模式", groups = {Config.class}) + private String mode; + + public interface Config { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, Config.class); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClient.java new file mode 100644 index 0000000..c1ae9ac --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClient.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.local; + +import cn.hutool.core.io.FileUtil; +import com.skyeye.framework.file.core.client.AbstractFileClient; + +import java.io.File; + +/** + * @ClassName: LocalFileClient + * @Description: 本地文件客户端 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class LocalFileClient extends AbstractFileClient { + + public LocalFileClient(String id, LocalFileClientConfig config) { + super(id, config); + } + + @Override + protected void doInit() { + // 补全风格。例如说 Linux 是 /,Windows 是 \ + if (!config.getBasePath().endsWith(File.separator)) { + config.setBasePath(config.getBasePath() + File.separator); + } + } + + @Override + public String upload(byte[] content, String path, String type) { + // 执行写入 + String filePath = getFilePath(path); + FileUtil.writeBytes(content, filePath); + // 拼接返回路径 + return super.formatFileUrl(path); + } + + @Override + public void delete(String path) { + String filePath = getFilePath(path); + FileUtil.del(filePath); + } + + @Override + public byte[] getContent(String path) { + String filePath = getFilePath(path); + return FileUtil.readBytes(filePath); + } + + private String getFilePath(String path) { + return config.getBasePath() + path; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClientConfig.java new file mode 100644 index 0000000..d4a3ef4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/local/LocalFileClientConfig.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.local; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; + +/** + * @ClassName: LocalFileClientConfig + * @Description: 本地文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("本地文件客户端的配置类") +public class LocalFileClientConfig implements FileClientConfig { + + @NotBlank(message = "基础路径", groups = {Config.class}) + private String basePath; + + @NotBlank(message = "自定义域名", groups = {Config.class}) + private String domain; + + public interface Config { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, Config.class); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/FilePresignedUrlRespDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/FilePresignedUrlRespDTO.java new file mode 100644 index 0000000..5cc0d8e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/FilePresignedUrlRespDTO.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.s3; + +import com.skyeye.annotation.api.Property; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FilePresignedUrlRespDTO + * @Description: 文件预签名地址 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FilePresignedUrlRespDTO { + + @Property(value = "文件配置id") + private String configId; + + @Property(value = "文件上传 URL(用于上传)") + private String uploadUrl; + + @Property(value = "文件 URL(用于读取、下载等)") + private String url; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClient.java new file mode 100644 index 0000000..7748b91 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClient.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.s3; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.skyeye.framework.file.core.client.AbstractFileClient; +import io.minio.*; +import io.minio.http.Method; + +import java.io.ByteArrayInputStream; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName: S3FileClient + * @Description: 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务 + * *

+ * * S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 12:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class S3FileClient extends AbstractFileClient { + + private MinioClient client; + + public S3FileClient(String id, S3FileClientConfig config) { + super(id, config); + } + + @Override + protected void doInit() { + // 补全 domain + if (StrUtil.isEmpty(config.getDomain())) { + config.setDomain(buildDomain()); + } + // 初始化客户端 + client = MinioClient.builder() + .endpoint(buildEndpointURL()) // Endpoint URL + .region(buildRegion()) // Region + .credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥 + .build(); + enableVirtualStyleEndpoint(); + } + + /** + * 基于 endpoint 构建调用云服务的 URL 地址 + * + * @return URI 地址 + */ + private String buildEndpointURL() { + // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO + if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) { + return config.getEndpoint(); + } + return StrUtil.format("https://{}", config.getEndpoint()); + } + + /** + * 基于 bucket + endpoint 构建访问的 Domain 地址 + * + * @return Domain 地址 + */ + private String buildDomain() { + // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO + if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) { + return StrUtil.format("{}/{}", config.getEndpoint(), config.getBucket()); + } + // 阿里云、腾讯云、华为云都适合。七牛云比较特殊,必须有自定义域名 + return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint()); + } + + /** + * 基于 bucket 构建 region 地区 + * + * @return region 地区 + */ + private String buildRegion() { + // 阿里云必须有 region,否则会报错 + if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_ALIYUN)) { + return StrUtil.subBefore(config.getEndpoint(), '.', false) + .replaceAll("-internal", "")// 去除内网 Endpoint 的后缀 + .replaceAll("https://", ""); + } + // 腾讯云必须有 region,否则会报错 + if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_TENCENT)) { + return StrUtil.subAfter(config.getEndpoint(), "cos.", false) + .replaceAll("." + S3FileClientConfig.ENDPOINT_TENCENT, ""); // 去除 Endpoint + } + return null; + } + + /** + * 开启 VirtualStyle 模式 + */ + private void enableVirtualStyleEndpoint() { + if (StrUtil.containsAny(config.getEndpoint(), + S3FileClientConfig.ENDPOINT_TENCENT, // 腾讯云 https://cloud.tencent.com/document/product/436/41284 + S3FileClientConfig.ENDPOINT_VOLCES)) { // 火山云 https://www.volcengine.com/docs/6349/1288493 + client.enableVirtualStyleEndpoint(); + } + } + + @Override + public String upload(byte[] content, String path, String type) throws Exception { + // 执行上传 + client.putObject(PutObjectArgs.builder() + .bucket(config.getBucket()) // bucket 必须传递 + .contentType(type) + .object(path) // 相对路径作为 key + .stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容 + .build()); + // 拼接返回路径 + return config.getDomain() + "/" + path; + } + + @Override + public void delete(String path) throws Exception { + client.removeObject(RemoveObjectArgs.builder() + .bucket(config.getBucket()) // bucket 必须传递 + .object(path) // 相对路径作为 key + .build()); + } + + @Override + public byte[] getContent(String path) throws Exception { + GetObjectResponse response = client.getObject(GetObjectArgs.builder() + .bucket(config.getBucket()) // bucket 必须传递 + .object(path) // 相对路径作为 key + .build()); + return IoUtil.readBytes(response); + } + + @Override + public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception { + String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() + .method(Method.PUT) + .bucket(config.getBucket()) + .object(path) + .expiry(10, TimeUnit.MINUTES) // 过期时间(秒数)取值范围:1 秒 ~ 7 天 + .build() + ); + return new FilePresignedUrlRespDTO(null, uploadUrl, config.getDomain() + "/" + path); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClientConfig.java new file mode 100644 index 0000000..d8a0e4a --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/s3/S3FileClientConfig.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.s3; + +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.NotBlank; + +/** + * @ClassName: S3FileClientConfig + * @Description: S3 文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 11:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("S3 文件客户端的配置类") +public class S3FileClientConfig implements FileClientConfig { + + public static final String ENDPOINT_QINIU = "qiniucs.com"; + + public static final String ENDPOINT_ALIYUN = "aliyuncs.com"; + + public static final String ENDPOINT_TENCENT = "myqcloud.com"; + + public static final String ENDPOINT_VOLCES = "volces.com"; // 火山云(字节) + + /** + * 节点地址 + * 1. MinIO:https://www.iocoder.cn/Spring-Boot/MinIO 。例如说,http://127.0.0.1:9000 + * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html + * 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224 + * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname + * 5. 华为云:https://developer.huaweicloud.com/endpoint?OBS + */ + @NotBlank(message = "节点地址", groups = {Config.class}) + private String endpoint; + + /** + * 自定义域名 + * 1. MinIO:通过 Nginx 配置 + * 2. 阿里云:https://help.aliyun.com/document_detail/31836.html + * 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142 + * 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name + * 5. 华为云:https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html + */ + @NotBlank(message = "自定义域名", groups = {Config.class}) + private String domain; + + @NotBlank(message = "存储 Bucket", groups = {Config.class}) + private String bucket; + + /** + * 访问 Key + * 1. MinIO:https://www.iocoder.cn/Spring-Boot/MinIO + * 2. 阿里云:https://ram.console.aliyun.com/manage/ak + * 3. 腾讯云:https://console.cloud.tencent.com/cam/capi + * 4. 七牛云:https://portal.qiniu.com/user/key + * 5. 华为云:https://support.huaweicloud.com/qs-obs/obs_qs_0005.html + */ + @NotBlank(message = "访问 Key", groups = {Config.class}) + private String accessKey; + + @NotBlank(message = "访问 Secret", groups = {Config.class}) + private String accessSecret; + + /** + * TODO 待补充 + * + * @return + */ + @SuppressWarnings("RedundantIfStatement") + @AssertTrue(message = "domain 不能为空") + @JsonIgnore + public boolean isDomainValid() { + // 如果是七牛,必须带有 domain + if (StrUtil.contains(endpoint, ENDPOINT_QINIU) && StrUtil.isEmpty(domain)) { + return false; + } + return true; + } + + public interface Config { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, Config.class); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClient.java new file mode 100644 index 0000000..f191c4a --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClient.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.sftp; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.extra.ssh.Sftp; +import com.skyeye.framework.file.core.client.AbstractFileClient; + +import java.io.File; + +/** + * @ClassName: SftpFileClient + * @Description: Sftp 文件客户端 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class SftpFileClient extends AbstractFileClient { + + private Sftp sftp; + + public SftpFileClient(String id, SftpFileClientConfig config) { + super(id, config); + } + + @Override + protected void doInit() { + // 补全风格。例如说 Linux 是 /,Windows 是 \ + if (!config.getBasePath().endsWith(File.separator)) { + config.setBasePath(config.getBasePath() + File.separator); + } + // 初始化 Ftp 对象 + this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword()); + } + + @Override + public String upload(byte[] content, String path, String type) { + // 执行写入 + String filePath = getFilePath(path); + File file = com.skyeye.common.util.FileUtil.createTempFile(content); + sftp.upload(filePath, file); + // 拼接返回路径 + return super.formatFileUrl(path); + } + + @Override + public void delete(String path) { + String filePath = getFilePath(path); + sftp.delFile(filePath); + } + + @Override + public byte[] getContent(String path) { + String filePath = getFilePath(path); + File destFile = com.skyeye.common.util.FileUtil.createTempFile(); + sftp.download(filePath, destFile); + return FileUtil.readBytes(destFile); + } + + private String getFilePath(String path) { + return config.getBasePath() + path; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClientConfig.java new file mode 100644 index 0000000..ceb97e5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/framework/file/core/client/sftp/SftpFileClientConfig.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.framework.file.core.client.sftp; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @ClassName: SftpFileClientConfig + * @Description: Sftp 文件客户端的配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 11:59 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("Sftp 文件客户端的配置类") +public class SftpFileClientConfig implements FileClientConfig { + + @NotBlank(message = "基础路径", groups = {Config.class}) + private String basePath; + + @NotBlank(message = "自定义域名", groups = {Config.class}) + private String domain; + + @NotBlank(message = "主机地址", groups = {Config.class}) + private String host; + + @NotNull(message = "主机端口", groups = {Config.class}) + private Integer port; + + @NotBlank(message = "用户名", groups = {Config.class}) + private String username; + + @NotBlank(message = "密码", groups = {Config.class}) + private String password; + + public interface Config { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, Config.class); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/EventType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/EventType.java new file mode 100644 index 0000000..9991871 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/EventType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: EventType + * @Description: 操作按钮事件类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum EventType implements SkyeyeEnumClass { + + AJAX("ajax", "请求事件", true, false), + OPEN_PAGE("openPage", "新开页面", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/MenuPageType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/MenuPageType.java new file mode 100644 index 0000000..bdb4374 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/MenuPageType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MenuPageType + * @Description: 菜单页面类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/29 11:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MenuPageType implements SkyeyeEnumClass { + + CUSTOM(1, "自定义页面", true, true), + LAYOUT(2, "表单布局", true, false), + REPORT(3, "报表视图", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/OperatePosition.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/OperatePosition.java new file mode 100644 index 0000000..a574ab2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/OperatePosition.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OperatePosition + * @Description: 操作按钮展示位置枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OperatePosition implements SkyeyeEnumClass { + + TOOL_BAR("toolBar", "工具栏", true, true), + ACTION_BAR("actionBar", "操作栏", true, false), + RIGHT_MENU_BAR("rightMenuBar", "右键菜单栏", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/PageOpenType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/PageOpenType.java new file mode 100644 index 0000000..9c0d247 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/classenum/PageOpenType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PageOpenType + * @Description: 页面布局打开方式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/18 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PageOpenType implements SkyeyeEnumClass { + + NORMAL(1, "正常打开", true, true), + PARENT_PAGE(2, "父页面打开", true, false), + NEW_WINDOW(3, "新窗口打开", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/controller/OperateController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/controller/OperateController.java new file mode 100644 index 0000000..2bd50dd --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/controller/OperateController.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.operate.entity.Operate; +import com.skyeye.operate.service.OperateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OperateController + * @Description: 操作管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "操作管理", tags = "操作管理", modelName = "系统公共模块") +public class OperateController { + + @Autowired + private OperateService operateService; + + @ApiOperation(id = "queryOperateList", value = "获取操作列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId", required = "required"), + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required")}) + @RequestMapping("/post/OperateController/queryOperateList") + public void queryOperateList(InputObject inputObject, OutputObject outputObject) { + operateService.queryOperateList(inputObject, outputObject); + } + + @ApiOperation(id = "writeOperate", value = "新增/编辑操作", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Operate.class) + @RequestMapping("/post/OperateController/writeOperate") + public void writeOperate(InputObject inputObject, OutputObject outputObject) { + operateService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryOperateById", value = "根据id查看操作信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "操作信息的id", required = "required")}) + @RequestMapping("/post/OperateController/queryOperateById") + public void queryOperateById(InputObject inputObject, OutputObject outputObject) { + operateService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "deleteOperateById", value = "根据id删除操作信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "操作信息的id", required = "required")}) + @RequestMapping("/post/OperateController/deleteOperateById") + public void deleteOperateById(InputObject inputObject, OutputObject outputObject) { + operateService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateDao.java new file mode 100644 index 0000000..d97ebd9 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.operate.entity.Operate; + +/** + * @ClassName: OperateDao + * @Description: 操作管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OperateDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateOpenPageDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateOpenPageDao.java new file mode 100644 index 0000000..14c3034 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/dao/OperateOpenPageDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.operate.entity.OperateOpenPage; + +/** + * @ClassName: OperateOpenPageDao + * @Description: 操作信息对应的新开页面信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OperateOpenPageDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/Operate.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/Operate.java new file mode 100644 index 0000000..54da1ea --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/Operate.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Operate + * @Description: 操作管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "skyeye:operate") +@TableName(value = "skyeye_operate", autoResultMap = true) +@ApiModel("操作管理实体类") +public class Operate extends BaseGeneralInfo { + + @TableField("position") + @ApiModelProperty(value = "展示位置,参考#OperatePosition", required = "required") + private String position; + + @TableField("color") + @ApiModelProperty(value = "操作按钮的颜色,展示位置为操作栏时必填,参考#ButtonColorType") + private String color; + + @TableField("auth_point_num") + @ApiModelProperty(value = "权限控制编号") + private String authPointNum; + + @TableField("event_type") + @ApiModelProperty(value = "事件类型,参考#EventType", required = "required") + private String eventType; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序,值越大越往后", required = "required,num") + private Integer orderBy; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField("app_id") + @ApiModelProperty(value = "应用的appId", required = "required") + private String appId; + + @TableField(exist = false) + @ApiModelProperty(value = "当事件类型为请求事件时,填写的接口信息") + private BusinessApi businessApi; + + @TableField(value = "open_type") + @ApiModelProperty(value = "页面布局打开方式,参考#PageOpenType") + private Integer openType; + + @TableField(exist = false) + @ApiModelProperty(value = "当事件类型为新开页面时,填写的页面/布局信息") + private OperateOpenPage operateOpenPage; + + @TableField(value = "show_condition", typeHandler = OperateListTypeHandler.class) + @ApiModelProperty(value = "操作按钮显示的条件") + private List showConditionList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateListTypeHandler.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateListTypeHandler.java new file mode 100644 index 0000000..4eff4b6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateListTypeHandler.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.entity; + +import com.alibaba.fastjson.TypeReference; +import com.skyeye.common.util.mybatisplus.ListTypeHandler; + +import java.util.List; + +/** + * @ClassName: OperateListTypeHandler + * @Description: 操作按钮显示条件对应的监听器集合转换处理类 + * @author: skyeye云系列--卫志强 + * @date: 2023/6/11 23:11 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class OperateListTypeHandler extends ListTypeHandler { + + @Override + protected TypeReference> specificType() { + return new TypeReference>() { + }; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateOpenPage.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateOpenPage.java new file mode 100644 index 0000000..27ec1be --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateOpenPage.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.operate.classenum.MenuPageType; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: OperateOpenPage + * @Description: 操作信息对应的新开页面信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_operate_page", autoResultMap = true) +@ApiModel("操作信息对应的新开页面信息实体类") +public class OperateOpenPage extends OperatorUserInfo { + + @TableId("id") + @Property(value = "主键id") + private String id; + + @TableField("operate_id") + @Property(value = "操作信息的id") + private String operateId; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("`type`") + @ApiModelProperty(value = "页面类型", required = "required", enumClass = MenuPageType.class) + private Integer type; + + @TableField("page_url") + @ApiModelProperty(value = "自定义页面的地址/表单布局的id", required = "required") + private String pageUrl; + + @TableField("path") + @ApiModelProperty(value = "VUE前端路由路径") + private String path; + + @TableField(exist = false) + @Property(value = "当 type 为表单布局时,存储的表单布局信息") + private DsFormPage dsFormPage; + + @TableField(exist = false) + @Property(value = "当 type 为视图页面时,存储的视图页面信息") + private Map reportPage; + + @TableField(value = "params", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "请求参数,数据格式:{入参key: 需要解析的属性key}", required = "json") + private Map params; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateShowCondition.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateShowCondition.java new file mode 100644 index 0000000..53aca26 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/entity/OperateShowCondition.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OperateShowCondition + * @Description: 操作按钮显示的条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/20 23:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("操作按钮显示的条件实体类") +public class OperateShowCondition { + + @ApiModelProperty(value = "属性名", required = "required") + private String attrKey; + + @ApiModelProperty(value = "比较符号", required = "required") + private String symbols; + + @Property(value = "比较符号标识") + private String symbolsMark; + + @ApiModelProperty(value = "值") + private String value; + + @ApiModelProperty(value = "显示值") + private String displayValue; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateOpenPageService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateOpenPageService.java new file mode 100644 index 0000000..da222b5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateOpenPageService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.operate.entity.OperateOpenPage; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OperateOpenPageService + * @Description: 操作信息对应的新开页面信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OperateOpenPageService extends SkyeyeBusinessService { + + void deleteByOperateId(String operateId); + + OperateOpenPage selectByOperateId(String operateId); + + Map selectByOperateIds(List operateIds); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateService.java new file mode 100644 index 0000000..5c09f57 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/OperateService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.operate.entity.Operate; + +import java.util.List; + +/** + * @ClassName: OperateService + * @Description: 操作管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OperateService extends SkyeyeBusinessService { + + void queryOperateList(InputObject inputObject, OutputObject outputObject); + + List getOperatesByClassName(String appId, String className); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateOpenPageServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateOpenPageServiceImpl.java new file mode 100644 index 0000000..45dc51f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateOpenPageServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.operate.dao.OperateOpenPageDao; +import com.skyeye.operate.entity.OperateOpenPage; +import com.skyeye.operate.service.OperateOpenPageService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OperateOpenPageServiceImpl + * @Description: 操作信息对应的新开页面信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class OperateOpenPageServiceImpl extends SkyeyeBusinessServiceImpl implements OperateOpenPageService { + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = {Exception.class}) + public String createEntity(OperateOpenPage entity, String userId) { + if (StrUtil.isEmpty(entity.getOperateId())) { + throw new CustomException("操作信息id为空,请确认."); + } + deleteByOperateId(entity.getOperateId()); + return super.createEntity(entity, userId); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = {Exception.class}) + public void deleteByOperateId(String operateId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(OperateOpenPage::getOperateId), operateId); + remove(queryWrapper); + } + + @Override + public OperateOpenPage selectByOperateId(String operateId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(OperateOpenPage::getOperateId), operateId); + return getOne(queryWrapper); + } + + @Override + public Map selectByOperateIds(List operateIds) { + if (CollectionUtil.isEmpty(operateIds)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(OperateOpenPage::getOperateId), operateIds); + List operateOpenPageList = list(queryWrapper); + return operateOpenPageList.stream().collect(Collectors.toMap(OperateOpenPage::getOperateId, bean -> bean)); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateServiceImpl.java new file mode 100644 index 0000000..b98926e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/operate/service/impl/OperateServiceImpl.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.operate.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.attr.classenum.AttrSymbols; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.business.entity.BusinessApi; +import com.skyeye.business.service.BusinessApiService; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.dsform.service.DsFormPageService; +import com.skyeye.operate.classenum.EventType; +import com.skyeye.operate.classenum.MenuPageType; +import com.skyeye.operate.dao.OperateDao; +import com.skyeye.operate.entity.Operate; +import com.skyeye.operate.entity.OperateOpenPage; +import com.skyeye.operate.service.OperateOpenPageService; +import com.skyeye.operate.service.OperateService; +import com.skyeye.rest.report.service.IReportPageService; +import com.skyeye.server.entity.ServiceBeanCustom; +import com.skyeye.server.service.ServiceBeanCustomService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OperateServiceImpl + * @Description: 操作管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/29 18:07 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@Slf4j +public class OperateServiceImpl extends SkyeyeBusinessServiceImpl implements OperateService { + + @Autowired + private BusinessApiService businessApiService; + + @Autowired + private OperateOpenPageService operateOpenPageService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private DsFormPageService dsFormPageService; + + @Autowired + private ServiceBeanCustomService serviceBeanCustomService; + + @Autowired + private IReportPageService iReportPageService; + + /** + * 获取操作列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryOperateList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String appId = params.get("appId").toString(); + String className = params.get("className").toString(); + List operateList = getOperatesByClassName(appId, className); + + iAuthUserService.setName(operateList, "createId", "createName"); + iAuthUserService.setName(operateList, "lastUpdateId", "lastUpdateName"); + outputObject.setBeans(operateList); + outputObject.settotal(operateList.size()); + } + + @Override + public List getOperatesByClassName(String appId, String className) { + String cacheKey = getCacheKeyByClassName(appId, className); + List operateList = redisCache.getList(cacheKey, key -> { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.orderByAsc(MybatisPlusUtil.toColumns(Operate::getOrderBy)); + wrapper.eq(MybatisPlusUtil.toColumns(Operate::getClassName), className); + List operates = list(wrapper); + List ids = operates.stream().map(Operate::getId).collect(Collectors.toList()); + + // 获取接口配置信息 + Map businessApiMap = businessApiService.selectByObjectIds(ids); + // 获取新开页面配置信息 + Map operateOpenPageMap = operateOpenPageService.selectByOperateIds(ids); + operates.forEach(operate -> { + String id = operate.getId(); + operate.setBusinessApi(businessApiMap.get(id)); + operate.setOperateOpenPage(operateOpenPageMap.get(id)); + }); + + return operates; + }, RedisConstants.ALL_USE_TIME, Operate.class); + + operateList.forEach(operate -> { + if (CollectionUtil.isNotEmpty(operate.getShowConditionList())) { + operate.getShowConditionList().forEach(condition -> { + condition.setSymbolsMark(AttrSymbols.getSymbols(condition.getSymbols())); + }); + } + }); + return operateList; + } + + @Override + public void writePostpose(Operate entity, String userId) { + super.writePostpose(entity, userId); + if (StrUtil.equals(entity.getEventType(), EventType.AJAX.getKey())) { + // 保存请求事件 + BusinessApi businessApi = entity.getBusinessApi(); + businessApi.setObjectId(entity.getId()); + businessApi.setObjectKey(getServiceClassName()); + businessApiService.createEntity(businessApi, userId); + } else if (StrUtil.equals(entity.getEventType(), EventType.OPEN_PAGE.getKey())) { + // 保存新开页面事件 + OperateOpenPage operateOpenPage = entity.getOperateOpenPage(); + operateOpenPage.setOperateId(entity.getId()); + operateOpenPageService.createEntity(operateOpenPage, userId); + } + String cacheKey = getCacheKeyByClassName(entity.getAppId(), entity.getClassName()); + jedisClientService.del(cacheKey); + } + + /** + * 根据id查询数据 + * + * @param id + * @return + */ + @Override + public Operate selectById(String id) { + Operate operate = super.selectById(id); + if (StrUtil.equals(operate.getEventType(), EventType.OPEN_PAGE.getKey())) { + // 新开页面 + OperateOpenPage operateOpenPage = operate.getOperateOpenPage(); + if (operateOpenPage.getType() == MenuPageType.LAYOUT.getKey()) { + // 表单布局 + try { + DsFormPage dsFormPage = dsFormPageService.getDataFromDb(operateOpenPage.getPageUrl()); + ServiceBeanCustom serviceBeanCustom = serviceBeanCustomService.selectServiceBeanCustom(dsFormPage.getAppId(), dsFormPage.getClassName()); + dsFormPage.setServiceBeanCustom(serviceBeanCustom); + operateOpenPage.setDsFormPage(dsFormPage); + } catch (Exception ex) { + log.info(String.format(Locale.ROOT, "FormPage %s is not exits. 【selectById】", operateOpenPage.getPageUrl())); + } + } else if (operateOpenPage.getType() == MenuPageType.REPORT.getKey()) { + // 报表页面 + operateOpenPage.setReportPage(iReportPageService.queryDataMationById(operateOpenPage.getPageUrl())); + } + } + return operate; + } + + @Override + public Operate getDataFromDb(String id) { + Operate operate = super.getDataFromDb(id); + if (StrUtil.equals(operate.getEventType(), EventType.AJAX.getKey())) { + // 查询请求事件 + BusinessApi businessApi = businessApiService.selectByObjectId(id); + operate.setBusinessApi(businessApi); + } else if (StrUtil.equals(operate.getEventType(), EventType.OPEN_PAGE.getKey())) { + // 查询新开页面事件 + OperateOpenPage operateOpenPage = operateOpenPageService.selectByOperateId(id); + operate.setOperateOpenPage(operateOpenPage); + } + return operate; + } + + @Override + public void deletePostpose(Operate entity) { + // 删除的时候不用区分事件类型,直接每张表都删除一次 + businessApiService.deleteByObjectId(entity.getId()); + operateOpenPageService.deleteByOperateId(entity.getId()); + // 清空缓存 + String cacheKey = getCacheKeyByClassName(entity.getAppId(), entity.getClassName()); + jedisClientService.del(cacheKey); + } + + private String getCacheKeyByClassName(String appId, String className) { + return String.format(Locale.ROOT, "skyeye:operate:className:%s:%s", appId, className); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/config/SkyeyePayAutoConfiguration.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/config/SkyeyePayAutoConfiguration.java new file mode 100644 index 0000000..9f3b95b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/config/SkyeyePayAutoConfiguration.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.config; + +import com.skyeye.pay.core.PayClientFactory; +import com.skyeye.pay.core.service.PayClientFactoryImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: SkyeyePayAutoConfiguration + * @Description: 支付配置类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 11:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +public class SkyeyePayAutoConfiguration { + + @Bean + public PayClientFactory payClientFactory() { + return new PayClientFactoryImpl(); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayAppController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayAppController.java new file mode 100644 index 0000000..a85dd26 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayAppController.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pay.entity.PayApp; +import com.skyeye.pay.service.PayAppService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PayAppController + * @Description: 支付应用信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "支付应用管理", tags = "支付应用管理", modelName = "支付应用管理") +public class PayAppController { + + @Autowired + private PayAppService payAppService; + + /** + * 新增/修改支付应用信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePayApp", value = "新增/修改支付应用信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PayApp.class) + @RequestMapping("/post/PayAppController/writePayApp") + public void writePayApp(InputObject inputObject, OutputObject outputObject) { + payAppService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取全部已启用的支付应用信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEnabledPayAppList", value = "获取全部已启用的支付应用信息", method = "POST", allUse = "2") + @RequestMapping("/post/PayAppController/queryAllEnabledPayAppList") + public void queryAllEnabledPayAppList(InputObject inputObject, OutputObject outputObject) { + payAppService.queryList(inputObject, outputObject); + } + + /** + * 根据id删除支付应用信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePayAppById", value = "根据id删除支付应用信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PayAppController/deletePayAppById") + public void deletePayAppById(InputObject inputObject, OutputObject outputObject) { + payAppService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询支付应用信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPayAppById", value = "根据id查询支付应用信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PayAppController/queryPayAppById") + public void queryPayAppById(InputObject inputObject, OutputObject outputObject) { + payAppService.selectById(inputObject, outputObject); + } + + /** + * 分页查询支付应用信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPayAppList", value = "分页查询支付应用信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PayAppController/queryPayAppList") + public void queryPayAppList(InputObject inputObject, OutputObject outputObject) { + payAppService.queryPageList(inputObject, outputObject); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayChannelController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayChannelController.java new file mode 100644 index 0000000..2da643e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayChannelController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pay.entity.PayChannel; +import com.skyeye.pay.service.PayChannelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PayChannelController + * @Description: 支付渠道信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "支付渠道管理", tags = "支付渠道管理", modelName = "支付渠道管理") +public class PayChannelController { + + @Autowired + private PayChannelService payChannelService; + + /** + * 新增/修改支付渠道信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writePayChannel", value = "新增/修改支付渠道信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = PayChannel.class) + @RequestMapping("/post/PayChannelController/writePayChannel") + public void writePayChannel(InputObject inputObject, OutputObject outputObject) { + payChannelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除支付渠道信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePayChannelById", value = "根据id删除支付渠道信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PayChannelController/deletePayChannelById") + public void deletePayChannelById(InputObject inputObject, OutputObject outputObject) { + payChannelService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询支付渠道信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPayChannelById", value = "根据id查询支付渠道信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PayChannelController/queryPayChannelById") + public void queryPayChannelById(InputObject inputObject, OutputObject outputObject) { + payChannelService.selectById(inputObject, outputObject); + } + + /** + * 分页查询支付渠道信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPayChannelList", value = "分页查询支付渠道信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PayChannelController/queryPayChannelList") + public void queryPayChannelList(InputObject inputObject, OutputObject outputObject) { + payChannelService.queryPageList(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayController.java new file mode 100644 index 0000000..0c7c387 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/controller/PayController.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.pay.service.PayService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PayController + * @Description: 统一支付 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 8:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "统一支付", tags = "统一支付", modelName = "统一支付") +public class PayController { + + @Autowired + private PayService payService; + + @ApiOperation(id = "payment", value = "统一支付", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "data", name = "data", value = "业务数据", required = "required,json"), + @ApiImplicitParam(id = "channelCode", name = "channelCode", value = "支付渠道编码", required = "required"), + @ApiImplicitParam(id = "returnUrl", name = "returnUrl", value = "支付结果的return回调地址必须是URL格式"), + @ApiImplicitParam(id = "channelExtras", name = "channelExtras", value = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数", required = "json"), + @ApiImplicitParam(id = "notifyUrl", name = "notifyUrl", value = "回调地址,支付成功后通知商户的地址,必须是URL格式")}) + @RequestMapping("/post/PayController/payment") + public void payment(InputObject inputObject, OutputObject outputObject) { + payService.payment(inputObject, outputObject); + } + + @ApiOperation(id = "generatePayRrCode", value = "生成支付二维码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "data", name = "data", value = "业务数据", required = "required,json"), + @ApiImplicitParam(id = "channelCode", name = "channelCode", value = "支付渠道编码", required = "required"), + @ApiImplicitParam(id = "ip", name = "ip", value = "用户的IP地址", required = "required"), + @ApiImplicitParam(id = "notifyUrl", name = "notifyUrl", value = "回调地址,支付成功后通知商户的地址,必须是URL格式")}) + @RequestMapping("/post/PayController/generatePayRrCode") + public void generatePayRrCode(InputObject inputObject, OutputObject outputObject) { + payService.generatePayRrCode(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClient.java new file mode 100644 index 0000000..9592f0d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClient.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core; + +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.core.dto.refund.PayRefundRespDTO; +import com.skyeye.pay.core.dto.refund.PayRefundUnifiedReqDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferRespDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferUnifiedReqDTO; +import com.skyeye.pay.enums.PayTransferType; + +import java.util.Map; + +/** + * @ClassName: PayClient + * @Description: 支付客户端,用于对接各支付渠道的 SDK,实现发起支付、退款等功能 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayClient { + + /** + * 获得渠道编号 + * + * @return 渠道编号 + */ + String getId(); + + // ============ 支付相关 ========== + + /** + * 调用支付渠道,统一下单 + * + * @param reqDTO 下单信息 + * @return 支付订单信息 + */ + PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO); + + /** + * 解析 order 回调数据 + * + * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 + * @param body HTTP 回调接口的 request body + * @return 支付订单信息 + */ + PayOrderRespDTO parseOrderNotify(Map params, String body); + + /** + * 获得支付订单信息 + * + * @param outTradeNo 外部订单号 + * @return 支付订单信息 + */ + PayOrderRespDTO getOrder(String outTradeNo); + + // ============ 退款相关 ========== + + /** + * 调用支付渠道,进行退款 + * + * @param reqDTO 统一退款请求信息 + * @return 退款信息 + */ + PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO); + + /** + * 解析 refund 回调数据 + * + * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数 + * @param body HTTP 回调接口的 request body + * @return 支付订单信息 + */ + PayRefundRespDTO parseRefundNotify(Map params, String body); + + /** + * 获得退款订单信息 + * + * @param outTradeNo 外部订单号 + * @param outRefundNo 外部退款号 + * @return 退款订单信息 + */ + PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo); + + /** + * 调用渠道,进行转账 + * + * @param reqDTO 统一转账请求信息 + * @return 转账信息 + */ + PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO); + + /** + * 获得转账订单信息 + * + * @param outTradeNo 外部订单号 + * @param type 转账类型 + * @return 转账信息 + */ + PayTransferRespDTO getTransfer(String outTradeNo, PayTransferType type); + + /** + * @param outTradeNo 订单号 + * @param body 订单描述 + * @param totalFee 订单金额,单位:分 + * @param ip 用户 IP + * @param notifyUrl 支付结果通知 URL + * @return + */ + String generateRrCode(String outTradeNo, String body, String totalFee, String ip, String notifyUrl); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientConfig.java new file mode 100644 index 0000000..93e44ad --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientConfig.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import javax.validation.Validator; + +/** + * @ClassName: PayClientConfig + * @Description: 支付客户端的配置,本质是支付渠道的配置 + * 每个不同的渠道,需要不同的配置,通过子类来定义 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) +// @JsonTypeInfo 注解的作用,Jackson 多态 +// 1. 序列化到时数据库时,增加 @class 属性。 +// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型 +public interface PayClientConfig { + + /** + * 参数校验 + * + * @param validator 校验对象 + */ + void validate(Validator validator); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientFactory.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientFactory.java new file mode 100644 index 0000000..cb04714 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/PayClientFactory.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core; + + +import com.skyeye.pay.enums.PayType; + +/** + * @ClassName: PayClientFactory + * @Description: 支付客户端的工厂接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayClientFactory { + + /** + * 获得支付客户端 + * + * @param channelId 渠道编号 + * @return 支付客户端 + */ + PayClient getPayClient(String channelId); + + /** + * 创建支付客户端 + * + * @param channelId 渠道编号 + * @param channelCode 渠道编码 + * @param config 支付配置 + * @return 支付客户端 + */ + PayClient createOrUpdatePayClient(String channelId, String channelCode, + Config config); + + /** + * 注册支付客户端 Class,用于模块中实现的 PayClient + * + * @param channel 支付渠道的编码的枚举 + * @param payClientClass 支付客户端 class + */ + void registerPayClientClass(PayType channel, Class payClientClass); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderRespDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderRespDTO.java new file mode 100644 index 0000000..20e1af3 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderRespDTO.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.order; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.pay.enums.PayOrderStatusResp; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * @ClassName: PayOrderRespDTO + * @Description: 渠道支付订单 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@Accessors(chain = true) +@ApiModel("渠道支付订单 Response DTO") +public class PayOrderRespDTO { + + @Property("支付状态,参考#PayOrderStatusResp") + private Integer status; + + @Property("外部订单号,对应 PayOrderExtensionDO 的 no 字段") + private String outTradeNo; + + @Property("支付渠道编号") + private String channelOrderNo; + + @Property("支付渠道用户编号") + private String channelUserId; + + @Property("支付成功时间") + private LocalDateTime successTime; + + @Property("原始的同步/异步通知结果") + private Object rawData; + + // ========== 主动发起支付时,会返回的字段 ========== + + @Property("展示模式,参考#PayOrderDisplayMode") + private String displayMode; + + @Property("展示内容") + private String displayContent; + + @Property("调用渠道的错误码【这里返回的是业务异常,而是不系统异常。如果是系统异常,则会抛出】") + private String channelErrorCode; + + @Property("调用渠道的错误信息") + private String channelErrorMsg; + + /** + * 创建【WAITING】状态的订单返回 + */ + public static PayOrderRespDTO waitingOf(String displayMode, String displayContent, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.setStatus(PayOrderStatusResp.WAITING.getKey()); + respDTO.setDisplayMode(displayMode); + respDTO.setDisplayContent(displayContent); + // 相对通用的字段 + respDTO.setOutTradeNo(outTradeNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【SUCCESS】状态的订单返回 + */ + public static PayOrderRespDTO successOf(String channelOrderNo, String channelUserId, LocalDateTime successTime, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.setStatus(PayOrderStatusResp.SUCCESS.getKey()); + respDTO.setChannelOrderNo(channelOrderNo); + respDTO.setChannelUserId(channelUserId); + respDTO.setSuccessTime(successTime); + // 相对通用的字段 + respDTO.setOutTradeNo(outTradeNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建指定状态的订单返回,适合支付渠道回调时 + */ + public static PayOrderRespDTO of(Integer status, String channelOrderNo, String channelUserId, LocalDateTime successTime, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.setStatus(status); + respDTO.setChannelOrderNo(channelOrderNo); + respDTO.setChannelUserId(channelUserId); + respDTO.setSuccessTime(successTime); + // 相对通用的字段 + respDTO.setOutTradeNo(outTradeNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【CLOSED】状态的订单返回,适合调用支付渠道失败时 + */ + public static PayOrderRespDTO closedOf(String channelErrorCode, String channelErrorMsg, + String outTradeNo, Object rawData) { + PayOrderRespDTO respDTO = new PayOrderRespDTO(); + respDTO.setStatus(PayOrderStatusResp.CLOSED.getKey()); + respDTO.setChannelErrorCode(channelErrorCode); + respDTO.setChannelErrorMsg(channelErrorMsg); + // 相对通用的字段 + respDTO.setOutTradeNo(outTradeNo); + respDTO.setRawData(rawData); + return respDTO; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderUnifiedReqDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderUnifiedReqDTO.java new file mode 100644 index 0000000..39066c7 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/order/PayOrderUnifiedReqDTO.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.order; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * @ClassName: PayOrderUnifiedReqDTO + * @Description: 统一下单 Request DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("统一下单 Request DTO") +public class PayOrderUnifiedReqDTO { + + @ApiModelProperty(value = "用户 IP", required = "required") + private String userIp; + + // ========== 商户相关字段 ========== + + @ApiModelProperty(value = "外部订单编号,对应 PayOrderExtensionDO 的 no 字段", required = "required") + private String outTradeNo; + + @ApiModelProperty(value = "商品标题", required = "required") + private String subject; + + @ApiModelProperty(value = "商品描述信息,长度不能超过128") + private String body; + + @ApiModelProperty(value = "支付结果的 notify 回调地址", required = "required") + private String notifyUrl; + + @ApiModelProperty(value = "支付结果的 return 回调地址") + private String returnUrl; + + // ========== 订单相关字段 ========== + + @ApiModelProperty(value = "支付金额,单位:分", required = "required") + private Integer price; + + @ApiModelProperty(value = "支付过期时间", required = "required") + private LocalDateTime expireTime; + + // ========== 拓展参数 ========== + @ApiModelProperty(value = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数") + private Map channelExtras; + + @ApiModelProperty(value = "展示模式,参考#PayOrderDisplayMode") + private String displayMode; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundRespDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundRespDTO.java new file mode 100644 index 0000000..0a9f638 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundRespDTO.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.refund; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.pay.enums.PayRefundStatusResp; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @ClassName: PayRefundRespDTO + * @Description: 渠道退款订单 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("渠道退款订单 Response DTO") +public class PayRefundRespDTO { + + @Property(value = "退款状态,参考#PayRefundStatusResp") + private Integer status; + + @Property(value = "外部退款号,对应 PayRefundDO 的 no 字段") + private String outRefundNo; + + @Property(value = "渠道退款单号,对应 PayRefundDO.channelRefundNo 字段") + private String channelRefundNo; + + @Property(value = "退款成功时间") + private LocalDateTime successTime; + + @Property(value = "原始的异步通知结果") + private Object rawData; + + @Property(value = "调用渠道的错误码。这里返回的是业务异常,而是不系统异常。如果是系统异常,则会抛出异常") + private String channelErrorCode; + + @Property(value = "调用渠道的错误信息") + private String channelErrorMsg; + + /** + * 创建【WAITING】状态的退款返回 + */ + public static PayRefundRespDTO waitingOf(String channelRefundNo, + String outRefundNo, Object rawData) { + PayRefundRespDTO respDTO = new PayRefundRespDTO(); + respDTO.setStatus(PayRefundStatusResp.WAITING.getKey()); + respDTO.setChannelRefundNo(channelRefundNo); + // 相对通用的字段 + respDTO.setOutRefundNo(outRefundNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【SUCCESS】状态的退款返回 + */ + public static PayRefundRespDTO successOf(String channelRefundNo, LocalDateTime successTime, + String outRefundNo, Object rawData) { + PayRefundRespDTO respDTO = new PayRefundRespDTO(); + respDTO.setStatus(PayRefundStatusResp.SUCCESS.getKey()); + respDTO.setChannelRefundNo(channelRefundNo); + respDTO.setSuccessTime(successTime); + // 相对通用的字段 + respDTO.setOutRefundNo(outRefundNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【FAILURE】状态的退款返回 + */ + public static PayRefundRespDTO failureOf(String outRefundNo, Object rawData) { + return failureOf(null, null, + outRefundNo, rawData); + } + + /** + * 创建【FAILURE】状态的退款返回 + */ + public static PayRefundRespDTO failureOf(String channelErrorCode, String channelErrorMsg, + String outRefundNo, Object rawData) { + PayRefundRespDTO respDTO = new PayRefundRespDTO(); + respDTO.setStatus(PayRefundStatusResp.FAILURE.getKey()); + respDTO.setChannelErrorCode(channelErrorCode); + respDTO.setChannelErrorMsg(channelErrorMsg); + // 相对通用的字段 + respDTO.setOutRefundNo(outRefundNo); + respDTO.setRawData(rawData); + return respDTO; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundUnifiedReqDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundUnifiedReqDTO.java new file mode 100644 index 0000000..9f91dd8 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/refund/PayRefundUnifiedReqDTO.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.refund; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +/** + * @ClassName: PayRefundUnifiedReqDTO + * @Description: 统一退款 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("统一退款") +public class PayRefundUnifiedReqDTO { + + @ApiModelProperty(value = "外部订单编号,对应 PayOrderExtensionDO 的 no 字段", required = "required") + private String outTradeNo; + + @ApiModelProperty(value = "外部退款号,对应 PayRefundDO 的 no 字段", required = "required") + private String outRefundNo; + + @ApiModelProperty(value = "退款原因", required = "required") + private String reason; + + @ApiModelProperty(value = "支付金额,单位:分", required = "required") + private Integer payPrice; + + @ApiModelProperty(value = "退款金额,单位:分", required = "required") + private Integer refundPrice; + + @ApiModelProperty(value = "支付结果的 notify 回调地址", required = "required") + private String notifyUrl; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferRespDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferRespDTO.java new file mode 100644 index 0000000..003d393 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferRespDTO.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.transfer; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.pay.enums.PayTransferStatusResp; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @ClassName: PayTransferRespDTO + * @Description: 统一转账 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("统一转账") +public class PayTransferRespDTO { + + @Property(value = "转账状态,参考#PayTransferStatusResp") + private Integer status; + + @Property(value = "外部转账单号") + private String outTransferNo; + + @Property(value = "支付渠道编号") + private String channelTransferNo; + + @Property(value = "支付成功时间") + private LocalDateTime successTime; + + @Property(value = "原始的返回结果") + private Object rawData; + + @Property(value = "调用渠道的错误码") + private String channelErrorCode; + + @Property(value = "调用渠道的错误信息") + private String channelErrorMsg; + + /** + * 创建【WAITING】状态的转账返回 + */ + public static PayTransferRespDTO waitingOf(String channelTransferNo, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.setStatus(PayTransferStatusResp.WAITING.getKey()); + respDTO.setChannelTransferNo(channelTransferNo); + respDTO.setOutTransferNo(outTransferNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【IN_PROGRESS】状态的转账返回 + */ + public static PayTransferRespDTO dealingOf(String channelTransferNo, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.setStatus(PayTransferStatusResp.IN_PROGRESS.getKey()); + respDTO.setChannelTransferNo(channelTransferNo); + respDTO.setOutTransferNo(outTransferNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【CLOSED】状态的转账返回 + */ + public static PayTransferRespDTO closedOf(String channelErrorCode, String channelErrorMsg, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.setStatus(PayTransferStatusResp.CLOSED.getKey()); + respDTO.setChannelErrorCode(channelErrorCode); + respDTO.setChannelErrorMsg(channelErrorMsg); + // 相对通用的字段 + respDTO.setOutTransferNo(outTransferNo); + respDTO.setRawData(rawData); + return respDTO; + } + + /** + * 创建【SUCCESS】状态的转账返回 + */ + public static PayTransferRespDTO successOf(String channelTransferNo, LocalDateTime successTime, + String outTransferNo, Object rawData) { + PayTransferRespDTO respDTO = new PayTransferRespDTO(); + respDTO.setStatus(PayTransferStatusResp.SUCCESS.getKey()); + respDTO.setChannelTransferNo(channelTransferNo); + respDTO.setSuccessTime(successTime); + // 相对通用的字段 + respDTO.setOutTransferNo(outTransferNo); + respDTO.setRawData(rawData); + return respDTO; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferUnifiedReqDTO.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferUnifiedReqDTO.java new file mode 100644 index 0000000..bed191e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/dto/transfer/PayTransferUnifiedReqDTO.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.dto.transfer; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: PayTransferUnifiedReqDTO + * @Description: 统一转账 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 9:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("统一转账") +public class PayTransferUnifiedReqDTO { + + @ApiModelProperty(value = "转账类型,参考#PayTransferType", required = "required") + private Integer type; + + @ApiModelProperty(value = "用户 IP", required = "required") + private String userIp; + + @ApiModelProperty(value = "外部转账单编号", required = "required") + private String outTransferNo; + + @ApiModelProperty(value = "转账金额,单位:分", required = "required") + private Integer price; + + @ApiModelProperty(value = "转账标题,长度不能超过 128", required = "required") + private String subject; + + @ApiModelProperty(value = "收款人姓名", required = "required") + private String userName; + + @ApiModelProperty(value = "支付宝登录号", required = "required") + private String alipayLogonId; + + @ApiModelProperty(value = "微信 openId", required = "required") + private String openid; + + @ApiModelProperty(value = "支付渠道的额外参数") + private Map channelExtras; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/AbstractPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/AbstractPayClient.java new file mode 100644 index 0000000..9ad81ac --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/AbstractPayClient.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service; + +import cn.hutool.json.JSONUtil; +import com.skyeye.pay.core.PayClient; +import com.skyeye.pay.core.PayClientConfig; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.core.dto.refund.PayRefundRespDTO; +import com.skyeye.pay.core.dto.refund.PayRefundUnifiedReqDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferRespDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferUnifiedReqDTO; +import com.skyeye.pay.enums.PayTransferType; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * @ClassName: AbstractPayClient + * @Description: 支付客户端的抽象类,提供模板方法,减少子类的冗余代码 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractPayClient implements PayClient { + + /** + * 渠道编号 + */ + private final String channelId; + /** + * 渠道编码 + */ + @SuppressWarnings("FieldCanBeLocal") + private final String channelCode; + /** + * 支付配置 + */ + protected Config config; + + public AbstractPayClient(String channelId, String channelCode, Config config) { + this.channelId = channelId; + this.channelCode = channelCode; + this.config = config; + } + + /** + * 初始化 + */ + public final void init() { + doInit(); + log.debug("[init][客户端({}) 初始化完成]", getId()); + } + + /** + * 自定义初始化 + */ + protected abstract void doInit(); + + public final void refresh(Config config) { + // 判断是否更新 + if (config.equals(this.config)) { + return; + } + log.info("[refresh][客户端({})发生变化,重新初始化]", getId()); + this.config = config; + // 初始化 + this.init(); + } + + @Override + public String getId() { + return channelId; + } + + // ============ 支付相关 ========== + + @Override + public final PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { + // 执行统一下单 + PayOrderRespDTO resp = null; + try { + resp = doUnifiedOrder(reqDTO); + } catch (Throwable ex) { + // 系统异常,则包装成 PayException 异常抛出 + log.error("[unifiedOrder][客户端({}) request({}) 发起支付异常]", + getId(), JSONUtil.toJsonStr(reqDTO), ex); + } + return resp; + } + + protected abstract PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) + throws Throwable; + + @Override + public final PayOrderRespDTO parseOrderNotify(Map params, String body) { + try { + return doParseOrderNotify(params, body); + } catch (Throwable ex) { + log.error("[parseOrderNotify][客户端({}) params({}) body({}) 解析失败]", + getId(), params, body, ex); + } + return null; + } + + protected abstract PayOrderRespDTO doParseOrderNotify(Map params, String body) + throws Throwable; + + @Override + public final PayOrderRespDTO getOrder(String outTradeNo) { + try { + return doGetOrder(outTradeNo); + } catch (Throwable ex) { + log.error("[getOrder][客户端({}) outTradeNo({}) 查询支付单异常]", + getId(), outTradeNo, ex); + } + return null; + } + + protected abstract PayOrderRespDTO doGetOrder(String outTradeNo) + throws Throwable; + + // ============ 退款相关 ========== + + @Override + public final PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) { + // 执行统一退款 + PayRefundRespDTO resp = null; + try { + resp = doUnifiedRefund(reqDTO); + } catch (Throwable ex) { + // 系统异常,则包装成 PayException 异常抛出 + log.error("[unifiedRefund][客户端({}) request({}) 发起退款异常]", + getId(), JSONUtil.toJsonStr(reqDTO), ex); + } + return resp; + } + + protected abstract PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; + + @Override + public final PayRefundRespDTO parseRefundNotify(Map params, String body) { + try { + return doParseRefundNotify(params, body); + } catch (Throwable ex) { + log.error("[parseRefundNotify][客户端({}) params({}) body({}) 解析失败]", + getId(), params, body, ex); + } + return null; + } + + protected abstract PayRefundRespDTO doParseRefundNotify(Map params, String body) + throws Throwable; + + @Override + public final PayRefundRespDTO getRefund(String outTradeNo, String outRefundNo) { + try { + return doGetRefund(outTradeNo, outRefundNo); + } catch (Throwable ex) { + log.error("[getRefund][客户端({}) outTradeNo({}) outRefundNo({}) 查询退款单异常]", + getId(), outTradeNo, outRefundNo, ex); + } + return null; + } + + protected abstract PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) + throws Throwable; + + @Override + public final PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + PayTransferRespDTO resp = null; + try { + resp = doUnifiedTransfer(reqDTO); + } catch (Throwable ex) { + // 系统异常,则包装成 PayException 异常抛出 + log.error("[unifiedTransfer][客户端({}) request({}) 发起转账异常]", + getId(), JSONUtil.toJsonStr(reqDTO), ex); + } + return resp; + } + + @Override + public final PayTransferRespDTO getTransfer(String outTradeNo, PayTransferType type) { + try { + return doGetTransfer(outTradeNo, type); + } catch (Throwable ex) { + log.error("[getTransfer][客户端({}) outTradeNo({}) type({}) 查询转账单异常]", + getId(), outTradeNo, type, ex); + } + return null; + } + + protected abstract PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) + throws Throwable; + + protected abstract PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferType type) + throws Throwable; + + // ========== 各种工具方法 ========== + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/NonePayClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/NonePayClientConfig.java new file mode 100644 index 0000000..5dbec70 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/NonePayClientConfig.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service; + +import com.skyeye.pay.core.PayClientConfig; +import lombok.Data; + +import javax.validation.Validator; + +/** + * @ClassName: NonePayClientConfig + * @Description: 无需任何配置 PayClientConfig 实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 9:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class NonePayClientConfig implements PayClientConfig { + + /** + * 配置名称 + *

+ * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称 + */ + private String name; + + public NonePayClientConfig() { + this.name = "none-config"; + } + + @Override + public void validate(Validator validator) { + // 无任何配置不需要校验 + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/PayClientFactoryImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/PayClientFactoryImpl.java new file mode 100644 index 0000000..ac654a5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/PayClientFactoryImpl.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ReflectUtil; +import com.skyeye.pay.core.PayClient; +import com.skyeye.pay.core.PayClientConfig; +import com.skyeye.pay.core.PayClientFactory; +import com.skyeye.pay.core.service.impl.alipay.*; +import com.skyeye.pay.core.service.impl.mock.MockPayClient; +import com.skyeye.pay.core.service.impl.weixin.*; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @ClassName: PayClientFactoryImpl + * @Description: 支付客户端的工厂实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 9:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class PayClientFactoryImpl implements PayClientFactory { + + /** + * 支付客户端 Map + *

+ * key:渠道编号 + */ + private final ConcurrentMap> clients = new ConcurrentHashMap<>(); + + /** + * 支付客户端 Class Map + */ + private final Map> clientClass = new ConcurrentHashMap<>(); + + public PayClientFactoryImpl() { + // 微信支付客户端 + clientClass.put(PayType.WX_PUB, WxPubPayClient.class); + clientClass.put(PayType.WX_LITE, WxLitePayClient.class); + clientClass.put(PayType.WX_APP, WxAppPayClient.class); + clientClass.put(PayType.WX_BAR, WxBarPayClient.class); + clientClass.put(PayType.WX_NATIVE, WxNativePayClient.class); + clientClass.put(PayType.WX_WAP, WxWapPayClient.class); + // 支付包支付客户端 + clientClass.put(PayType.ALIPAY_WAP, AlipayWapPayClient.class); + clientClass.put(PayType.ALIPAY_QR, AlipayQrPayClient.class); + clientClass.put(PayType.ALIPAY_APP, AlipayAppPayClient.class); + clientClass.put(PayType.ALIPAY_PC, AlipayPcPayClient.class); + clientClass.put(PayType.ALIPAY_BAR, AlipayBarPayClient.class); + // Mock 支付客户端 + clientClass.put(PayType.MOCK, MockPayClient.class); + } + + @Override + public void registerPayClientClass(PayType channel, Class payClientClass) { + clientClass.put(channel, payClientClass); + } + + @Override + public PayClient getPayClient(String channelId) { + AbstractPayClient client = clients.get(channelId); + if (client == null) { + log.error("[getPayClient][渠道编号({}) 找不到客户端]", channelId); + } + return client; + } + + @Override + public PayClient createOrUpdatePayClient(String channelId, String channelCode, + Config config) { + AbstractPayClient client = (AbstractPayClient) clients.get(channelId); + if (client == null) { + client = this.createPayClient(channelId, channelCode, config); + client.init(); + clients.put(client.getId(), client); + } else { + client.refresh(config); + } + return client; + } + + private AbstractPayClient createPayClient(String channelId, String channelCode, + Config config) { + PayType channelEnum = PayType.getByCode(channelCode); + Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelCode)); + Class payClientClass = clientClass.get(channelEnum); + Assert.notNull(payClientClass, String.format("支付渠道(%s) Class 为空", channelCode)); + return (AbstractPayClient) ReflectUtil.newInstance(payClientClass, channelId, config); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AbstractAlipayPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AbstractAlipayPayClient.java new file mode 100644 index 0000000..09e2c89 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AbstractAlipayPayClient.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConfig; +import com.alipay.api.AlipayResponse; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.domain.*; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.request.*; +import com.alipay.api.response.*; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.core.dto.refund.PayRefundRespDTO; +import com.skyeye.pay.core.dto.refund.PayRefundUnifiedReqDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferRespDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferUnifiedReqDTO; +import com.skyeye.pay.core.service.AbstractPayClient; +import com.skyeye.pay.enums.PayOrderStatusResp; +import com.skyeye.pay.enums.PayTransferType; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; + +import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; + +/** + * @ClassName: AbstractAlipayPayClient + * @Description: 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款) + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 8:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractAlipayPayClient extends AbstractPayClient { + + @Getter // 仅用于单测场景 + protected DefaultAlipayClient client; + + public AbstractAlipayPayClient(String channelId, String channelCode, AlipayPayClientConfig config) { + super(channelId, channelCode, config); + } + + @Override + @SneakyThrows + protected void doInit() { + AlipayConfig alipayConfig = new AlipayConfig(); + BeanUtil.copyProperties(config, alipayConfig, false); + this.client = new DefaultAlipayClient(alipayConfig); + } + + // ============ 支付相关 ========== + + /** + * 构造支付关闭的 {@link PayOrderRespDTO} 对象 + * + * @return 支付关闭的 {@link PayOrderRespDTO} 对象 + */ + protected PayOrderRespDTO buildClosedPayOrderRespDTO(PayOrderUnifiedReqDTO reqDTO, AlipayResponse response) { + Assert.isFalse(response.isSuccess()); + return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + reqDTO.getOutTradeNo(), response); + } + + @Override + public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws Throwable { + // 1. 校验回调数据 + Map bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8); + AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(), + StandardCharsets.UTF_8.name(), config.getSignType()); + + // 2. 解析订单的状态 + // 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂 + Integer status = parseStatus(bodyObj.get("trade_status")); + // 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功 + if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) { + status = PayOrderStatusResp.REFUND.getKey(); + } + Assert.notNull(status, (Supplier) () -> { + throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body)); + }); + return PayOrderRespDTO.of(status, bodyObj.get("trade_no"), bodyObj.get("seller_id"), parseTime(params.get("gmt_payment")), + bodyObj.get("out_trade_no"), body); + } + + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable { + // 1.1 构建 AlipayTradeRefundModel 请求 + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + model.setOutTradeNo(outTradeNo); + // 1.2 构建 AlipayTradeQueryRequest 请求 + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + request.setBizModel(model); + AlipayTradeQueryResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { + // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + if (!response.isSuccess()) { // 不成功,例如说订单不存在 + return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + outTradeNo, response); + } + // 2.2 解析订单的状态 + Integer status = parseStatus(response.getTradeStatus()); + Assert.notNull(status, () -> { + throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody())); + }); + return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()), + outTradeNo, response); + } + + private static Integer parseStatus(String tradeStatus) { + return Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusResp.WAITING.getKey() + : StrUtil.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusResp.SUCCESS.getKey() + : Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusResp.CLOSED.getKey() : null; + } + + // ============ 退款相关 ========== + + /** + * 支付宝统一的退款接口 alipay.trade.refund + * + * @param reqDTO 退款请求 request DTO + * @return 退款请求 Response + */ + @Override + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 构建 AlipayTradeRefundModel 请求 + AlipayTradeRefundModel model = new AlipayTradeRefundModel(); + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setOutRequestNo(reqDTO.getOutRefundNo()); + model.setRefundAmount(formatAmount(reqDTO.getRefundPrice())); + model.setRefundReason(reqDTO.getReason()); + // 1.2 构建 AlipayTradePayRequest 请求 + AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); + request.setBizModel(model); + + // 2.1 执行请求 + AlipayTradeRefundResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + if (!response.isSuccess()) { + // 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询 + if (StrUtil.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) { + return PayRefundRespDTO.waitingOf(null, reqDTO.getOutRefundNo(), response); + } + return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response); + } + // 2.2 创建返回结果 + // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。 + // 另外,支付宝没有退款单号,所以不用设置 + return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()), + reqDTO.getOutRefundNo(), response); + } + + @Override + public PayRefundRespDTO doParseRefundNotify(Map params, String body) { + // 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。 + // ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调 + // ② 全部退款:Wap 支付有订单状态的同步回调,但是 PC/扫码又没有 + // 所以,这里在解析时,即使是退款导致的订单状态同步,我们也忽略不做为“退款同步”,而是订单的回调。 + // 实际上,支付宝退款只要发起成功,就可以认为退款成功,不需要等待回调。 + throw new UnsupportedOperationException("支付宝无退款回调"); + } + + @Override + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws AlipayApiException { + // 1.1 构建 AlipayTradeFastpayRefundQueryModel 请求 + AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel(); + model.setOutTradeNo(outTradeNo); + model.setOutRequestNo(outRefundNo); + model.setQueryOptions(Collections.singletonList("gmt_refund_pay")); + // 1.2 构建 AlipayTradeFastpayRefundQueryRequest 请求 + AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); + request.setBizModel(model); + + // 2.1 执行请求 + AlipayTradeFastpayRefundQueryResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + if (!response.isSuccess()) { + // 明确不存在的情况,应该就是失败,可进行关闭 + if (StrUtil.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) { + return PayRefundRespDTO.failureOf(outRefundNo, response); + } + // 可能存在“ACQ.SYSTEM_ERROR”系统错误等情况,所以返回 WAIT 继续等待 + return PayRefundRespDTO.waitingOf(null, outRefundNo, response); + } + // 2.2 创建返回结果 + if (Objects.equals(response.getRefundStatus(), "REFUND_SUCCESS")) { + return PayRefundRespDTO.successOf(null, LocalDateTimeUtil.of(response.getGmtRefundPay()), + outRefundNo, response); + } + return PayRefundRespDTO.waitingOf(null, outRefundNo, response); + } + + @Override + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 校验公钥类型 必须使用公钥证书模式 + if (!Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { + throw new CustomException("支付宝单笔转账必须使用公钥证书模式"); + } + // 1.2 构建 AlipayFundTransUniTransferModel + AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel(); + // ① 通用的参数 + model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额 + model.setOrderTitle(reqDTO.getSubject()); // 转账业务的标题,用于在支付宝用户的账单里显示。 + model.setOutBizNo(reqDTO.getOutTransferNo()); + model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER + if (reqDTO.getChannelExtras() != null) { + model.setBusinessParams(JSONUtil.toJsonStr(reqDTO.getChannelExtras())); + } + // ② 个性化的参数 + Participant payeeInfo = new Participant(); + PayTransferType transferType = PayTransferType.typeOf(reqDTO.getType()); + switch (transferType) { + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦? + // @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试?? + case ALIPAY_BALANCE: { + payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); + payeeInfo.setIdentity(reqDTO.getAlipayLogonId()); // 支付宝登录号 + payeeInfo.setName(reqDTO.getUserName()); // 支付宝账号姓名 + model.setPayeeInfo(payeeInfo); + break; + } + case BANK_CARD: { + payeeInfo.setIdentityType("BANKCARD_ACCOUNT"); + // TODO 待实现 + throw new CustomException("功能未实现/未开启"); + } + default: { + throw new CustomException(StrUtil.format("不支持的转账类型: {}", transferType)); + } + } + // 1.3 构建 AlipayFundTransUniTransferRequest + AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest(); + request.setBizModel(model); + // 执行请求 + AlipayFundTransUniTransferResponse response = client.certificateExecute(request); + // 处理结果 + if (!response.isSuccess()) { + // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询,或相同 outBizNo 重新发起转账 + // 发现 outBizNo 相同 两次请求参数相同. 会返回 "PAYMENT_INFO_INCONSISTENCY", 不知道哪里的问题. 暂时返回 WAIT. 后续job 会轮询 + if (StrUtil.equalsAny(response.getSubCode(), "PAYMENT_INFO_INCONSISTENCY", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) { + return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response); + } + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + reqDTO.getOutTransferNo(), response); + } else { + if (StrUtil.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL" + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + reqDTO.getOutTransferNo(), response); + } + if (Objects.equals(response.getStatus(), "DEALING")) { // 转账到银行卡会出现 "DEALING" 处理中 + return PayTransferRespDTO.dealingOf(response.getOrderId(), reqDTO.getOutTransferNo(), response); + } + return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()), + response.getOutBizNo(), response); + } + + } + + @Override + protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferType type) throws Throwable { + // 1.1 构建 AlipayFundTransCommonQueryModel + AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel(); + model.setProductCode(type == PayTransferType.BANK_CARD ? "TRANS_BANKCARD_NO_PWD" : "TRANS_ACCOUNT_NO_PWD"); + model.setBizScene("DIRECT_TRANSFER"); //业务场景 + model.setOutBizNo(outTradeNo); + // 1.2 构建 AlipayFundTransCommonQueryRequest + AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest(); + request.setBizModel(model); + + // 2.1 执行请求 + AlipayFundTransCommonQueryResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + // 2.2 处理返回结果 + if (response.isSuccess()) { + if (StrUtil.equalsAny(response.getStatus(), "REFUND", "FAIL")) { // 转账到银行卡会出现 "REFUND" "FAIL" + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + outTradeNo, response); + } + if (Objects.equals(response.getStatus(), "DEALING")) { // 转账到银行卡会出现 "DEALING" 处理中 + return PayTransferRespDTO.dealingOf(response.getOrderId(), outTradeNo, response); + } + return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getPayDate()), + response.getOutBizNo(), response); + } else { + // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账 + // 当出现 ORDER_NOT_EXIST 可能是转账还在处理中,也可能是转账处理失败. 返回 WAIT 状态. 后续 job 会轮询, 或相同 outBizNo 重新发起转账 + if (StrUtil.equalsAny(response.getSubCode(), "ORDER_NOT_EXIST", "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) { + return PayTransferRespDTO.waitingOf(null, outTradeNo, response); + } + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), + outTradeNo, response); + } + } + + // ========== 各种工具方法 ========== + + protected String formatAmount(Integer amount) { + return String.valueOf(amount / 100.0); + } + + protected String formatTime(LocalDateTime time) { + return LocalDateTimeUtil.format(time, NORM_DATETIME_FORMATTER); + } + + protected LocalDateTime parseTime(String str) { + return LocalDateTimeUtil.parse(str, NORM_DATETIME_FORMATTER); + } + + @Override + public String generateRrCode(String outTradeNo, String body, String totalFee, String ip, String notifyUrl) { + return null; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayAppPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayAppPayClient.java new file mode 100644 index 0000000..9abba68 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayAppPayClient.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradeAppPayModel; +import com.alipay.api.request.AlipayTradeAppPayRequest; +import com.alipay.api.response.AlipayTradeAppPayResponse; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: AlipayAppPayClient + * @Description: 支付宝【App 支付】的 PayClient 实现类 + * 文档:App 支付 + * 未详细测试,因为手头没 App + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AlipayAppPayClient extends AbstractAlipayPayClient { + + public AlipayAppPayClient(String channelId, AlipayPayClientConfig config) { + super(channelId, PayType.ALIPAY_APP.getKey(), config); + } + + @Override + public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 构建 AlipayTradeAppPayModel 请求 + AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); + // ① 通用的参数 + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setSubject(reqDTO.getSubject()); + model.setBody(reqDTO.getBody() + "test"); + model.setTotalAmount(formatAmount(reqDTO.getPrice())); + model.setTimeExpire(formatTime(reqDTO.getExpireTime())); + model.setProductCode("QUICK_MSECURITY_PAY"); // 销售产品码:无线快捷支付产品 + // ② 个性化的参数【无】 + // ③ 支付宝扫码支付只有一种展示 + String displayMode = PayOrderDisplayMode.APP.getKey(); + + // 1.2 构建 AlipayTradePrecreateRequest 请求 + AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); + request.setBizModel(model); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setReturnUrl(reqDTO.getReturnUrl()); + + // 2.1 执行请求 + AlipayTradeAppPayResponse response = client.sdkExecute(request); + // 2.2 处理结果 + if (!response.isSuccess()) { + return buildClosedPayOrderRespDTO(reqDTO, response); + } + return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), + reqDTO.getOutTradeNo(), response); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayBarPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayBarPayClient.java new file mode 100644 index 0000000..a8fbe37 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayBarPayClient.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradePayModel; +import com.alipay.api.request.AlipayTradePayRequest; +import com.alipay.api.response.AlipayTradePayResponse; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * @ClassName: AlipayBarPayClient + * @Description: 支付宝【条码支付】的 PayClient 实现类 + * 文档:当面付 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AlipayBarPayClient extends AbstractAlipayPayClient { + + public AlipayBarPayClient(String channelId, AlipayPayClientConfig config) { + super(channelId, PayType.ALIPAY_BAR.getKey(), config); + } + + @Override + public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException { + String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "auth_code"); + if (StrUtil.isEmpty(authCode)) { + throw new CustomException("条形码不能为空"); + } + + // 1.1 构建 AlipayTradePayModel 请求 + AlipayTradePayModel model = new AlipayTradePayModel(); + // ① 通用的参数 + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setSubject(reqDTO.getSubject()); + model.setBody(reqDTO.getBody()); + model.setTotalAmount(formatAmount(reqDTO.getPrice())); + model.setScene("bar_code"); // 当面付条码支付场景 + // ② 个性化的参数 + model.setAuthCode(authCode); + // ③ 支付宝条码支付只有一种展示 + String displayMode = PayOrderDisplayMode.BAR_CODE.getKey(); + + // 1.2 构建 AlipayTradePayRequest 请求 + AlipayTradePayRequest request = new AlipayTradePayRequest(); + request.setBizModel(model); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setReturnUrl(reqDTO.getReturnUrl()); + + // 2.1 执行请求 + AlipayTradePayResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { + // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + // 2.2 处理结果 + if (!response.isSuccess()) { + return buildClosedPayOrderRespDTO(reqDTO, response); + } + if ("10000".equals(response.getCode())) { // 免密支付 + LocalDateTime successTime = LocalDateTimeUtil.of(response.getGmtPayment()); + return PayOrderRespDTO.successOf(response.getTradeNo(), response.getBuyerUserId(), successTime, + response.getOutTradeNo(), response) + .setDisplayMode(displayMode).setDisplayContent(""); + } + // 大额支付,需要用户输入密码,所以返回 waiting。此时,前端一般会进行轮询 + return PayOrderRespDTO.waitingOf(displayMode, "", + reqDTO.getOutTradeNo(), response); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPayClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPayClientConfig.java new file mode 100644 index 0000000..07b1079 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPayClientConfig.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import com.skyeye.pay.core.PayClientConfig; +import lombok.Data; + +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @ClassName: AlipayPayClientConfig + * @Description: 支付宝的 PayClientConfig 实现类 + * 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class AlipayPayClientConfig implements PayClientConfig { + + /** + * 公钥类型 - 公钥模式 + */ + public static final Integer MODE_PUBLIC_KEY = 1; + /** + * 公钥类型 - 证书模式 + */ + public static final Integer MODE_CERTIFICATE = 2; + + /** + * 接口内容加密方式 - AES 加密 + */ + public static final String ENC_TYPE_AES = "AES"; + + /** + * 签名算法类型 - RSA + */ + public static final String SIGN_TYPE_DEFAULT = "RSA2"; + + /** + * 网关地址 + *

+ * 1. 生产环境 + * 2. 沙箱环境 + */ + @NotBlank(message = "网关地址不能为空", groups = {ModePublicKey.class, ModeCertificate.class}) + private String serverUrl; + + /** + * 开放平台上创建的应用的 ID + */ + @NotBlank(message = "开放平台上创建的应用的 ID不能为空", groups = {ModePublicKey.class, ModeCertificate.class}) + private String appId; + + /** + * 签名算法类型,推荐:RSA2 + *

+ * {@link #SIGN_TYPE_DEFAULT} + */ + @NotBlank(message = "签名算法类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class}) + private String signType; + + /** + * 公钥类型 + * 1. {@link #MODE_PUBLIC_KEY} 情况,privateKey + alipayPublicKey + * 2. {@link #MODE_CERTIFICATE} 情况,appCertContent + alipayPublicCertContent + rootCertContent + */ + @NotNull(message = "公钥类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class}) + private Integer mode; + + // ========== 公钥模式 ========== + /** + * 商户私钥 + */ + @NotBlank(message = "商户私钥不能为空", groups = {ModePublicKey.class}) + private String privateKey; + + /** + * 支付宝公钥字符串 + */ + @NotBlank(message = "支付宝公钥字符串不能为空", groups = {ModePublicKey.class}) + private String alipayPublicKey; + + // ========== 证书模式 ========== + /** + * 指定商户公钥应用证书内容字符串 + */ + @NotBlank(message = "指定商户公钥应用证书内容不能为空", groups = {ModeCertificate.class}) + private String appCertContent; + /** + * 指定支付宝公钥证书内容字符串 + */ + @NotBlank(message = "指定支付宝公钥证书内容不能为空", groups = {ModeCertificate.class}) + private String alipayPublicCertContent; + /** + * 指定根证书内容字符串 + */ + @NotBlank(message = "指定根证书内容字符串不能为空", groups = {ModeCertificate.class}) + private String rootCertContent; + + /** + * 接口内容加密方式 + *

+ * 1. 如果为空,将使用无加密方式 + * 2. 如果要加密,目前支付宝只有 AES 一种加密方式 + * + * @see 支付宝开放平台 + * @see AlipayPayClientConfig#ENC_TYPE_AES + */ + private String encryptType; + + /** + * 接口内容加密的私钥 + */ + private String encryptKey; + + public interface ModePublicKey { + } + + public interface ModeCertificate { + } + + @Override + public void validate(Validator validator) { + validator.validate(this, MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPcPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPcPayClient.java new file mode 100644 index 0000000..b99aaa9 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayPcPayClient.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.Method; +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradePagePayModel; +import com.alipay.api.request.AlipayTradePagePayRequest; +import com.alipay.api.response.AlipayTradePagePayResponse; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +import java.util.Objects; + +/** + * @ClassName: AlipayPcPayClient + * @Description: 支付宝【PC 网站】的 PayClient 实现类 + * 文档:电脑网站支付 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AlipayPcPayClient extends AbstractAlipayPayClient { + + public AlipayPcPayClient(String channelId, AlipayPayClientConfig config) { + super(channelId, PayType.ALIPAY_PC.getKey(), config); + } + + @Override + public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 构建 AlipayTradePagePayModel 请求 + AlipayTradePagePayModel model = new AlipayTradePagePayModel(); + // ① 通用的参数 + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setSubject(reqDTO.getSubject()); + model.setBody(reqDTO.getBody()); + model.setTotalAmount(formatAmount(reqDTO.getPrice())); + model.setTimeExpire(formatTime(reqDTO.getExpireTime())); + model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 销售产品码. 目前 PC 支付场景下仅支持 FAST_INSTANT_TRADE_PAY + // ② 个性化的参数 + // 如果想弄更多个性化的参数,可参考 https://www.pingxx.com/api/支付渠道 extra 参数说明.html 的 alipay_pc_direct 部分进行拓展 + model.setQrPayMode("2"); // 跳转模式 - 订单码,效果参见:https://help.pingxx.com/article/1137360/ + // ③ 支付宝 PC 支付有两种展示模式:FORM、URL + String displayMode = ObjectUtil.defaultIfNull(reqDTO.getDisplayMode(), + PayOrderDisplayMode.URL.getKey()); + + // 1.2 构建 AlipayTradePagePayRequest 请求 + AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); + request.setBizModel(model); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setReturnUrl(reqDTO.getReturnUrl()); + + // 2.1 执行请求 + AlipayTradePagePayResponse response; + if (Objects.equals(displayMode, PayOrderDisplayMode.FORM.getKey())) { + response = client.pageExecute(request, Method.POST.name()); // 需要特殊使用 POST 请求 + } else { + response = client.pageExecute(request, Method.GET.name()); + } + // 2.2 处理结果 + if (!response.isSuccess()) { + return buildClosedPayOrderRespDTO(reqDTO, response); + } + return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), + reqDTO.getOutTradeNo(), response); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayQrPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayQrPayClient.java new file mode 100644 index 0000000..a942914 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayQrPayClient.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradePrecreateModel; +import com.alipay.api.request.AlipayTradePrecreateRequest; +import com.alipay.api.response.AlipayTradePrecreateResponse; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +import java.util.Objects; + +/** + * @ClassName: AlipayQrPayClient + * @Description: 支付宝【扫码支付】的 PayClient 实现类 + * 档:扫码支付 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AlipayQrPayClient extends AbstractAlipayPayClient { + + public AlipayQrPayClient(String channelId, AlipayPayClientConfig config) { + super(channelId, PayType.ALIPAY_QR.getKey(), config); + } + + @Override + public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 构建 AlipayTradePrecreateModel 请求 + AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); + // ① 通用的参数 + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setSubject(reqDTO.getSubject()); + model.setBody(reqDTO.getBody()); + model.setTotalAmount(formatAmount(reqDTO.getPrice())); + model.setProductCode("FACE_TO_FACE_PAYMENT"); // 销售产品码. 目前扫码支付场景下仅支持 FACE_TO_FACE_PAYMENT + // ② 个性化的参数【无】 + // ③ 支付宝扫码支付只有一种展示,考虑到前端可能希望二维码扫描后,手机打开 + String displayMode = PayOrderDisplayMode.QR_CODE.getKey(); + + // 1.2 构建 AlipayTradePrecreateRequest 请求 + AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); + request.setBizModel(model); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setReturnUrl(reqDTO.getReturnUrl()); + + // 2.1 执行请求 + AlipayTradePrecreateResponse response; + if (Objects.equals(config.getMode(), AlipayPayClientConfig.MODE_CERTIFICATE)) { + // 证书模式 + response = client.certificateExecute(request); + } else { + response = client.execute(request); + } + // 2.2 处理结果 + if (!response.isSuccess()) { + return buildClosedPayOrderRespDTO(reqDTO, response); + } + return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(), + reqDTO.getOutTradeNo(), response); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayWapPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayWapPayClient.java new file mode 100644 index 0000000..496a3ef --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/alipay/AlipayWapPayClient.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.alipay; + +import cn.hutool.http.Method; +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradeWapPayModel; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.alipay.api.response.AlipayTradeWapPayResponse; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: AlipayWapPayClient + * @Description: 支付宝【Wap 网站】的 PayClient 实现类 + * 文档:手机网站支付接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AlipayWapPayClient extends AbstractAlipayPayClient { + + public AlipayWapPayClient(String channelId, AlipayPayClientConfig config) { + super(channelId, PayType.ALIPAY_WAP.getKey(), config); + } + + @Override + public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException { + // 1.1 构建 AlipayTradeWapPayModel 请求 + AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); + // ① 通用的参数 + model.setOutTradeNo(reqDTO.getOutTradeNo()); + model.setSubject(reqDTO.getSubject()); + model.setBody(reqDTO.getBody()); + model.setTotalAmount(formatAmount(reqDTO.getPrice())); + model.setProductCode("QUICK_WAP_PAY"); // 销售产品码. 目前 Wap 支付场景下仅支持 QUICK_WAP_PAY + // ② 个性化的参数【无】 + // ③ 支付宝 Wap 支付只有一种展示:URL + String displayMode = PayOrderDisplayMode.URL.getKey(); + + // 1.2 构建 AlipayTradeWapPayRequest 请求 + AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); + request.setBizModel(model); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + request.setReturnUrl(reqDTO.getReturnUrl()); + model.setQuitUrl(reqDTO.getReturnUrl()); + model.setTimeExpire(formatTime(reqDTO.getExpireTime())); + + // 2.1 执行请求 + AlipayTradeWapPayResponse response = client.pageExecute(request, Method.GET.name()); + // 2.2 处理结果 + if (!response.isSuccess()) { + return buildClosedPayOrderRespDTO(reqDTO, response); + } + return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), + reqDTO.getOutTradeNo(), response); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/mock/MockPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/mock/MockPayClient.java new file mode 100644 index 0000000..940fbf0 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/mock/MockPayClient.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.mock; + +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.core.dto.refund.PayRefundRespDTO; +import com.skyeye.pay.core.dto.refund.PayRefundUnifiedReqDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferRespDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferUnifiedReqDTO; +import com.skyeye.pay.core.service.AbstractPayClient; +import com.skyeye.pay.core.service.NonePayClientConfig; +import com.skyeye.pay.enums.PayTransferType; +import com.skyeye.pay.enums.PayType; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * @ClassName: MockPayClient + * @Description: 模拟支付的 PayClient 实现类 + * 模拟支付返回结果都是成功,方便大家日常流畅 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 19:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class MockPayClient extends AbstractPayClient { + + private static final String MOCK_RESP_SUCCESS_DATA = "MOCK_SUCCESS"; + + public MockPayClient(String channelId, NonePayClientConfig config) { + super(channelId, PayType.MOCK.getKey(), config); + } + + @Override + protected void doInit() { + } + + @Override + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { + return PayOrderRespDTO.successOf("MOCK-P-" + reqDTO.getOutTradeNo(), "", LocalDateTime.now(), + reqDTO.getOutTradeNo(), MOCK_RESP_SUCCESS_DATA); + } + + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) { + return PayOrderRespDTO.successOf("MOCK-P-" + outTradeNo, "", LocalDateTime.now(), + outTradeNo, MOCK_RESP_SUCCESS_DATA); + } + + @Override + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { + return PayRefundRespDTO.successOf("MOCK-R-" + reqDTO.getOutRefundNo(), LocalDateTime.now(), + reqDTO.getOutRefundNo(), MOCK_RESP_SUCCESS_DATA); + } + + @Override + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { + return PayRefundRespDTO.successOf("MOCK-R-" + outRefundNo, LocalDateTime.now(), + outRefundNo, MOCK_RESP_SUCCESS_DATA); + } + + @Override + protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { + throw new UnsupportedOperationException("模拟支付无退款回调"); + } + + @Override + protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { + throw new UnsupportedOperationException("模拟支付无支付回调"); + } + + @Override + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + throw new UnsupportedOperationException("待实现"); + } + + @Override + protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferType type) { + throw new UnsupportedOperationException("待实现"); + } + + @Override + public String generateRrCode(String outTradeNo, String body, String totalFee, String ip, String notifyUrl) { + return null; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/AbstractWxPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/AbstractWxPayClient.java new file mode 100644 index 0000000..fd56abf --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/AbstractWxPayClient.java @@ -0,0 +1,500 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.date.TemporalAccessorUtil; +import cn.hutool.core.util.StrUtil; +import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result; +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; +import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; +import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import com.skyeye.common.util.FileUtil; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.core.dto.refund.PayRefundRespDTO; +import com.skyeye.pay.core.dto.refund.PayRefundUnifiedReqDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferRespDTO; +import com.skyeye.pay.core.dto.transfer.PayTransferUnifiedReqDTO; +import com.skyeye.pay.core.service.AbstractPayClient; +import com.skyeye.pay.enums.PayChannelVersion; +import com.skyeye.pay.enums.PayOrderStatusResp; +import com.skyeye.pay.enums.PayTransferType; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Map; +import java.util.Objects; + +import static cn.hutool.core.date.DatePattern.*; + +/** + * @ClassName: AbstractWxPayClient + * @Description: 微信支付抽象类,实现微信统一的接口、以及部分实现(退款) + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 19:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public abstract class AbstractWxPayClient extends AbstractPayClient { + + protected WxPayService client; + + public AbstractWxPayClient(String channelId, String channelCode, WxPayClientConfig config) { + super(channelId, channelCode, config); + } + + /** + * 初始化 client 客户端 + * + * @param tradeType 交易类型 + */ + protected void doInit(String tradeType) { + // 创建 config 配置 + WxPayConfig payConfig = new WxPayConfig(); + BeanUtil.copyProperties(config, payConfig, "keyContent", "privateKeyContent"); + payConfig.setTradeType(tradeType); + // weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决 + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + payConfig.setKeyPath(FileUtil.createTempFile(Base64.decode(config.getKeyContent())).getPath()); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + payConfig.setPrivateKeyPath(FileUtil.createTempFile(config.getPrivateKeyContent()).getPath()); + } + + // 创建 client 客户端 + client = new WxPayServiceImpl(); + client.setConfig(payConfig); + } + + // ============ 支付相关 ========== + + @Override + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Exception { + try { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doUnifiedOrderV2(reqDTO); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return doUnifiedOrderV3(reqDTO); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } catch (WxPayException e) { + String errorCode = getErrorCode(e); + String errorMessage = getErrorMessage(e); + return PayOrderRespDTO.closedOf(errorCode, errorMessage, + reqDTO.getOutTradeNo(), e.getXmlString()); + } + } + + /** + * 【V2】调用支付渠道,统一下单 + * + * @param reqDTO 下单信息 + * @return 各支付渠道的返回结果 + */ + protected abstract PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) + throws Exception; + + /** + * 【V3】调用支付渠道,统一下单 + * + * @param reqDTO 下单信息 + * @return 各支付渠道的返回结果 + */ + protected abstract PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) + throws WxPayException; + + /** + * 【V2】创建微信下单请求 + * + * @param reqDTO 下信息 + * @return 下单请求 + */ + protected WxPayUnifiedOrderRequest buildPayUnifiedOrderRequestV2(PayOrderUnifiedReqDTO reqDTO) { + return WxPayUnifiedOrderRequest.newBuilder() + .outTradeNo(reqDTO.getOutTradeNo()) + .body(reqDTO.getSubject()) + .detail(reqDTO.getBody()) + .totalFee(reqDTO.getPrice()) // 单位分 + .timeExpire(formatDateV2(reqDTO.getExpireTime())) + .spbillCreateIp(reqDTO.getUserIp()) + .notifyUrl(reqDTO.getNotifyUrl()) + .build(); + } + + /** + * 【V3】创建微信下单请求 + * + * @param reqDTO 下信息 + * @return 下单请求 + */ + protected WxPayUnifiedOrderV3Request buildPayUnifiedOrderRequestV3(PayOrderUnifiedReqDTO reqDTO) { + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); + request.setOutTradeNo(reqDTO.getOutTradeNo()); + request.setDescription(reqDTO.getSubject()); + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getPrice())); // 单位分 + request.setTimeExpire(formatDateV3(reqDTO.getExpireTime())); + request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); + request.setNotifyUrl(reqDTO.getNotifyUrl()); + return request; + } + + @Override + public PayOrderRespDTO doParseOrderNotify(Map params, String body) throws WxPayException { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doParseOrderNotifyV2(body); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return doParseOrderNotifyV3(body); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } + + private PayOrderRespDTO doParseOrderNotifyV2(String body) throws WxPayException { + // 1. 解析回调 + WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body); + // 2. 构建结果 + // V2 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂 + Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ? + PayOrderStatusResp.SUCCESS.getKey() : PayOrderStatusResp.CLOSED.getKey(); + return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), + response.getOutTradeNo(), body); + } + + private PayOrderRespDTO doParseOrderNotifyV3(String body) throws WxPayException { + // 1. 解析回调 + WxPayNotifyV3Result response = client.parseOrderNotifyV3Result(body, null); + WxPayNotifyV3Result.DecryptNotifyResult result = response.getResult(); + // 2. 构建结果 + Integer status = parseStatus(result.getTradeState()); + String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null; + return PayOrderRespDTO.of(status, result.getTransactionId(), openid, parseDateV3(result.getSuccessTime()), + result.getOutTradeNo(), body); + } + + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) throws Throwable { + try { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doGetOrderV2(outTradeNo); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return doGetOrderV3(outTradeNo); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } catch (WxPayException e) { + if (StrUtil.equalsAny(e.getErrCode(), "ORDERNOTEXIST", "ORDER_NOT_EXIST")) { + String errorCode = getErrorCode(e); + String errorMessage = getErrorMessage(e); + return PayOrderRespDTO.closedOf(errorCode, errorMessage, + outTradeNo, e.getXmlString()); + } + throw e; + } + } + + private PayOrderRespDTO doGetOrderV2(String outTradeNo) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayOrderQueryRequest request = WxPayOrderQueryRequest.newBuilder() + .outTradeNo(outTradeNo).build(); + // 执行请求 + WxPayOrderQueryResult response = client.queryOrder(request); + + // 转换结果 + Integer status = parseStatus(response.getTradeState()); + return PayOrderRespDTO.of(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), + outTradeNo, response); + } + + private PayOrderRespDTO doGetOrderV3(String outTradeNo) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request() + .setOutTradeNo(outTradeNo); + // 执行请求 + WxPayOrderQueryV3Result response = client.queryOrderV3(request); + + // 转换结果 + Integer status = parseStatus(response.getTradeState()); + String openid = response.getPayer() != null ? response.getPayer().getOpenid() : null; + return PayOrderRespDTO.of(status, response.getTransactionId(), openid, parseDateV3(response.getSuccessTime()), + outTradeNo, response); + } + + private static Integer parseStatus(String tradeState) { + switch (tradeState) { + case "NOTPAY": + case "USERPAYING": // 支付中,等待用户输入密码(条码支付独有) + return PayOrderStatusResp.WAITING.getKey(); + case "SUCCESS": + return PayOrderStatusResp.SUCCESS.getKey(); + case "REFUND": + return PayOrderStatusResp.REFUND.getKey(); + case "CLOSED": + case "REVOKED": // 已撤销(刷卡支付独有) + case "PAYERROR": // 支付失败(其它原因,如银行返回失败) + return PayOrderStatusResp.CLOSED.getKey(); + default: + throw new IllegalArgumentException(StrUtil.format("未知的支付状态({})", tradeState)); + } + } + + // ============ 退款相关 ========== + + @Override + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { + try { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doUnifiedRefundV2(reqDTO); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return doUnifiedRefundV3(reqDTO); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } catch (WxPayException e) { + String errorCode = getErrorCode(e); + String errorMessage = getErrorMessage(e); + return PayRefundRespDTO.failureOf(errorCode, errorMessage, + reqDTO.getOutTradeNo(), e.getXmlString()); + } + } + + private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable { + // 1. 构建 WxPayRefundRequest 请求 + WxPayRefundRequest request = new WxPayRefundRequest() + .setOutTradeNo(reqDTO.getOutTradeNo()) + .setOutRefundNo(reqDTO.getOutRefundNo()) + .setRefundFee(reqDTO.getRefundPrice()) + .setRefundDesc(reqDTO.getReason()) + .setTotalFee(reqDTO.getPayPrice()) + .setNotifyUrl(reqDTO.getNotifyUrl()); + // 2.1 执行请求 + WxPayRefundResult response = client.refundV2(request); + // 2.2 创建返回结果 + if (Objects.equals("SUCCESS", response.getResultCode())) { // V2 情况下,不直接返回退款成功,而是等待异步通知 + return PayRefundRespDTO.waitingOf(response.getRefundId(), + reqDTO.getOutRefundNo(), response); + } + return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response); + } + + private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable { + // 1. 构建 WxPayRefundRequest 请求 + WxPayRefundV3Request request = new WxPayRefundV3Request() + .setOutTradeNo(reqDTO.getOutTradeNo()) + .setOutRefundNo(reqDTO.getOutRefundNo()) + .setAmount(new WxPayRefundV3Request.Amount().setRefund(reqDTO.getRefundPrice()) + .setTotal(reqDTO.getPayPrice()).setCurrency("CNY")) + .setReason(reqDTO.getReason()) + .setNotifyUrl(reqDTO.getNotifyUrl()); + // 2.1 执行请求 + WxPayRefundV3Result response = client.refundV3(request); + // 2.2 创建返回结果 + if (Objects.equals("SUCCESS", response.getStatus())) { + return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()), + reqDTO.getOutRefundNo(), response); + } + if (Objects.equals("PROCESSING", response.getStatus())) { + return PayRefundRespDTO.waitingOf(response.getRefundId(), + reqDTO.getOutRefundNo(), response); + } + return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response); + } + + @Override + public PayRefundRespDTO doParseRefundNotify(Map params, String body) throws WxPayException { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doParseRefundNotifyV2(body); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return parseRefundNotifyV3(body); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } + + private PayRefundRespDTO doParseRefundNotifyV2(String body) throws WxPayException { + // 1. 解析回调 + WxPayRefundNotifyResult response = client.parseRefundNotifyResult(body); + WxPayRefundNotifyResult.ReqInfo result = response.getReqInfo(); + // 2. 构建结果 + if (Objects.equals("SUCCESS", result.getRefundStatus())) { + return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV2B(result.getSuccessTime()), + result.getOutRefundNo(), response); + } + return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response); + } + + private PayRefundRespDTO parseRefundNotifyV3(String body) throws WxPayException { + // 1. 解析回调 + WxPayRefundNotifyV3Result response = client.parseRefundNotifyV3Result(body, null); + WxPayRefundNotifyV3Result.DecryptNotifyResult result = response.getResult(); + // 2. 构建结果 + if (Objects.equals("SUCCESS", result.getRefundStatus())) { + return PayRefundRespDTO.successOf(result.getRefundId(), parseDateV3(result.getSuccessTime()), + result.getOutRefundNo(), response); + } + return PayRefundRespDTO.failureOf(result.getOutRefundNo(), response); + } + + @Override + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) throws WxPayException { + try { + if (Objects.equals(config.getApiVersion(), PayChannelVersion.V2_VERSION.getKey())) { + return doGetRefundV2(outTradeNo, outRefundNo); + } else if (Objects.equals(config.getApiVersion(), PayChannelVersion.V3_VERSION.getKey())) { + return doGetRefundV3(outTradeNo, outRefundNo); + } else { + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); + } + } catch (WxPayException e) { + if (StrUtil.equalsAny(e.getErrCode(), "REFUNDNOTEXIST", "RESOURCE_NOT_EXISTS")) { + String errorCode = getErrorCode(e); + String errorMessage = getErrorMessage(e); + return PayRefundRespDTO.failureOf(errorCode, errorMessage, + outRefundNo, e.getXmlString()); + } + throw e; + } + } + + private PayRefundRespDTO doGetRefundV2(String outTradeNo, String outRefundNo) throws WxPayException { + // 1. 构建 WxPayRefundRequest 请求 + WxPayRefundQueryRequest request = WxPayRefundQueryRequest.newBuilder() + .outTradeNo(outTradeNo) + .outRefundNo(outRefundNo) + .build(); + // 2.1 执行请求 + WxPayRefundQueryResult response = client.refundQuery(request); + // 2.2 创建返回结果 + if (!Objects.equals("SUCCESS", response.getResultCode())) { + return PayRefundRespDTO.waitingOf(null, + outRefundNo, response); + } + WxPayRefundQueryResult.RefundRecord refund = CollUtil.findOne(response.getRefundRecords(), + record -> record.getOutRefundNo().equals(outRefundNo)); + if (refund == null) { + return PayRefundRespDTO.failureOf(outRefundNo, response); + } + switch (refund.getRefundStatus()) { + case "SUCCESS": + return PayRefundRespDTO.successOf(refund.getRefundId(), parseDateV2B(refund.getRefundSuccessTime()), + outRefundNo, response); + case "PROCESSING": + return PayRefundRespDTO.waitingOf(refund.getRefundId(), + outRefundNo, response); + case "CHANGE": // 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,资金回流到商户的现金帐号,需要商户人工干预,通过线下或者财付通转账的方式进行退款 + case "FAIL": + return PayRefundRespDTO.failureOf(outRefundNo, response); + default: + throw new IllegalArgumentException(String.format("未知的退款状态(%s)", refund.getRefundStatus())); + } + } + + private PayRefundRespDTO doGetRefundV3(String outTradeNo, String outRefundNo) throws WxPayException { + // 1. 构建 WxPayRefundRequest 请求 + WxPayRefundQueryV3Request request = new WxPayRefundQueryV3Request(); + request.setOutRefundNo(outRefundNo); + // 2.1 执行请求 + WxPayRefundQueryV3Result response = client.refundQueryV3(request); + // 2.2 创建返回结果 + switch (response.getStatus()) { + case "SUCCESS": + return PayRefundRespDTO.successOf(response.getRefundId(), parseDateV3(response.getSuccessTime()), + outRefundNo, response); + case "PROCESSING": + return PayRefundRespDTO.waitingOf(response.getRefundId(), + outRefundNo, response); + case "ABNORMAL": // 退款异常 + case "CLOSED": + return PayRefundRespDTO.failureOf(outRefundNo, response); + default: + throw new IllegalArgumentException(String.format("未知的退款状态(%s)", response.getStatus())); + } + } + + @Override + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { + throw new UnsupportedOperationException("待实现"); + } + + @Override + protected PayTransferRespDTO doGetTransfer(String outTradeNo, PayTransferType type) { + throw new UnsupportedOperationException("待实现"); + } + + // ========== 各种工具方法 ========== + + static String formatDateV2(LocalDateTime time) { + return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), PURE_DATETIME_PATTERN); + } + + static LocalDateTime parseDateV2(String time) { + return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN); + } + + static LocalDateTime parseDateV2B(String time) { + return LocalDateTimeUtil.parse(time, NORM_DATETIME_PATTERN); + } + + static String formatDateV3(LocalDateTime time) { + return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN); + } + + static LocalDateTime parseDateV3(String time) { + return LocalDateTimeUtil.parse(time, UTC_WITH_XXX_OFFSET_PATTERN); + } + + static String getErrorCode(WxPayException e) { + if (StrUtil.isNotEmpty(e.getErrCode())) { + return e.getErrCode(); + } + if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) { + return "CUSTOM_ERROR"; + } + return e.getReturnCode(); + } + + static String getErrorMessage(WxPayException e) { + if (StrUtil.isNotEmpty(e.getErrCode())) { + return e.getErrCodeDes(); + } + if (StrUtil.isNotEmpty(e.getCustomErrorMsg())) { + return e.getCustomErrorMsg(); + } + return e.getReturnMsg(); + } + + @Override + public String generateRrCode(String outTradeNo, String body, String totalFee, String ip, String notifyUrl) { + // 创建统一下单请求 + WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); + request.setBody(body); + request.setOutTradeNo(outTradeNo); + request.setTotalFee(Integer.parseInt(totalFee)); // 单位为分 + request.setSpbillCreateIp(ip); + request.setTradeType("NATIVE"); + request.setNotifyUrl(notifyUrl); + + // 调用统一下单接口 + WxPayUnifiedOrderResult result; + try { + result = client.unifiedOrder(request); + } catch (WxPayException e) { + throw new RuntimeException(e); + } + // 生成支付二维码 + return result.getCodeURL(); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxAppPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxAppPayClient.java new file mode 100644 index 0000000..a9db503 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxAppPayClient.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import cn.hutool.json.JSONUtil; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: WxAppPayClient + * @Description: 微信支付【App 支付】的 PayClient 实现类 + * 档:App 支付 + * 未详细测试,因为手头没 App + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxAppPayClient extends AbstractWxPayClient { + + public WxAppPayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_APP.getKey(), config); + } + + @Override + protected void doInit() { + super.doInit(WxPayConstants.TradeType.APP); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO); + // 执行请求 + WxPayMpOrderResult response = client.createOrder(request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.APP.getKey(), JSONUtil.toJsonStr(response), + reqDTO.getOutTradeNo(), response); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderV3Request 对象 + WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO); + // 执行请求 + WxPayUnifiedOrderV3Result.AppResult response = client.createOrderV3(TradeTypeEnum.APP, request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.APP.getKey(), JSONUtil.toJsonStr(response), + reqDTO.getOutTradeNo(), response); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxBarPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxBarPayClient.java new file mode 100644 index 0000000..270e102 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxBarPayClient.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; +import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.concurrent.TimeUnit; + +/** + * @ClassName: WxBarPayClient + * @Description: 微信支付【付款码支付】的 PayClient 实现类 + * 档:付款码支付 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxBarPayClient extends AbstractWxPayClient { + + /** + * 微信付款码的过期时间 + */ + private static final Duration AUTH_CODE_EXPIRE = Duration.ofMinutes(3); + + public WxBarPayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_BAR.getKey(), config); + } + + @Override + protected void doInit() { + super.doInit(WxPayConstants.TradeType.MICROPAY); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 由于付款码需要不断轮询,所以需要在较短的时间完成支付 + LocalDateTime expireTime = LocalDateTime.now().plus(AUTH_CODE_EXPIRE); + if (expireTime.isAfter(reqDTO.getExpireTime())) { + expireTime = reqDTO.getExpireTime(); + } + // 构建 WxPayMicropayRequest 对象 + WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder() + .outTradeNo(reqDTO.getOutTradeNo()) + .body(reqDTO.getSubject()) + .detail(reqDTO.getBody()) + .totalFee(reqDTO.getPrice()) // 单位分 + .timeExpire(formatDateV2(expireTime)) + .spbillCreateIp(reqDTO.getUserIp()) + .authCode(getAuthCode(reqDTO)) + .build(); + // 执行请求,重试直到失败(过期),或者成功 + WxPayException lastWxPayException = null; + for (int i = 1; i < Byte.MAX_VALUE; i++) { + try { + WxPayMicropayResult response = client.micropay(request); + // 支付成功,例如说:1)用户输入了密码;2)用户免密支付 + return PayOrderRespDTO.successOf(response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()), + response.getOutTradeNo(), response) + .setDisplayMode(PayOrderDisplayMode.BAR_CODE.getKey()); + } catch (WxPayException ex) { + lastWxPayException = ex; + // 如果不满足这 3 种任一的,则直接抛出 WxPayException 异常,不仅需处理 + // 1. SYSTEMERROR:接口返回错误:请立即调用被扫订单结果查询API,查询当前订单状态,并根据订单的状态决定下一步的操作。 + // 2. USERPAYING:用户支付中,需要输入密码:等待 5 秒,然后调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。 + // 3. BANKERROR:银行系统异常:请立即调用被扫订单结果查询 API,查询当前订单的不同状态,决定下一步的操作。 + if (!StrUtil.equalsAny(ex.getErrCode(), "SYSTEMERROR", "USERPAYING", "BANKERROR")) { + throw ex; + } + // 等待 5 秒,继续下一轮重新发起支付 + log.info("[doUnifiedOrderV2][发起微信 Bar 支付第({})失败,等待下一轮重试,请求({}),响应({})]", i, + JSONUtil.toJsonStr(request), ex.getMessage()); + ThreadUtil.sleep(5, TimeUnit.SECONDS); + } + } + throw lastWxPayException; + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + return doUnifiedOrderV2(reqDTO); + } + + // ========== 各种工具方法 ========== + + static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) { + String authCode = MapUtil.getStr(reqDTO.getChannelExtras(), "authCode"); + if (StrUtil.isEmpty(authCode)) { + throw new CustomException("支付请求的 authCode 不能为空!"); + } + return authCode; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxLitePayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxLitePayClient.java new file mode 100644 index 0000000..806f924 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxLitePayClient.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: WxLitePayClient + * @Description: 微信支付【小程序】的 PayClient 实现类 + * 由于公众号和小程序的微信支付逻辑一致,所以直接进行继承 + * 文档:JSAPI 下单 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxLitePayClient extends WxPubPayClient { + + public WxLitePayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_LITE.getKey(), config); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxNativePayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxNativePayClient.java new file mode 100644 index 0000000..ce79d39 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxNativePayClient.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: WxNativePayClient + * @Description: 微信支付【Native 二维码】的 PayClient 实现类 + * 文档:Native 下单 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxNativePayClient extends AbstractWxPayClient { + + public WxNativePayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_NATIVE.getKey(), config); + } + + @Override + protected void doInit() { + super.doInit(WxPayConstants.TradeType.NATIVE); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO) + .setProductId(reqDTO.getOutTradeNo()); // V2 必须传递 productId,无需在微信配置。该参数在 V3 简化,无需传递! + // 执行请求 + WxPayNativeOrderResult response = client.createOrder(request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.QR_CODE.getKey(), response.getCodeUrl(), + reqDTO.getOutTradeNo(), response); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderV3Request 对象 + WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO); + // 执行请求 + String response = client.createOrderV3(TradeTypeEnum.NATIVE, request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.QR_CODE.getKey(), response, + reqDTO.getOutTradeNo(), response); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPayClientConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPayClientConfig.java new file mode 100644 index 0000000..ba02467 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPayClientConfig.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import cn.hutool.core.collection.CollUtil; +import com.skyeye.pay.core.PayClientConfig; +import com.skyeye.pay.enums.PayChannelVersion; +import lombok.Data; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; +import javax.validation.constraints.NotBlank; +import java.util.Set; + +/** + * @ClassName: WxPayClientConfig + * @Description: 微信支付的 PayClientConfig 实现类 + * 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 19:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class WxPayClientConfig implements PayClientConfig { + + /** + * 公众号或者小程序的 appid + *

+ * 只有公众号或小程序需要该字段 + */ + @NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class}) + private String appId; + /** + * 商户号 + */ + @NotBlank(message = "商户号不能为空", groups = {V2.class, V3.class}) + private String mchId; + /** + * API 版本 + */ + @NotBlank(message = "API 版本不能为空", groups = {V2.class, V3.class}) + private String apiVersion; + + // ========== V2 版本的参数 ========== + + /** + * 商户密钥 + */ + @NotBlank(message = "商户密钥不能为空", groups = V2.class) + private String mchKey; + /** + * apiclient_cert.p12 证书文件的对应字符串【base64 格式】 + *

+ * 为什么采用 base64 格式?因为 p12 读取后是二进制,需要转换成 base64 格式才好传输和存储 + */ + @NotBlank(message = "apiclient_cert.p12 不能为空", groups = V2.class) + private String keyContent; + + // ========== V3 版本的参数 ========== + /** + * apiclient_key.pem 证书文件的对应字符串 + */ + @NotBlank(message = "apiclient_key 不能为空", groups = V3.class) + private String privateKeyContent; + /** + * apiV3 密钥值 + */ + @NotBlank(message = "apiV3 密钥值不能为空", groups = V3.class) + private String apiV3Key; + /** + * 证书序列号 + */ + @NotBlank(message = "证书序列号不能为空", groups = V3.class) + private String certSerialNo; + + @Deprecated // TODO 待移除 + private String privateCertContent; + + /** + * 分组校验 v2版本 + */ + public interface V2 { + } + + /** + * 分组校验 v3版本 + */ + public interface V3 { + } + + @Override + public void validate(Validator validator) { + Set> constraintViolations = validator.validate(this, PayChannelVersion.V2_VERSION.getKey().equals(this.getApiVersion()) ? V2.class : V3.class); + if (CollUtil.isNotEmpty(constraintViolations)) { + throw new ConstraintViolationException(constraintViolations); + } + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPubPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPubPayClient.java new file mode 100644 index 0000000..0710e34 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxPubPayClient.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: WxPubPayClient + * @Description: 微信支付(公众号)的 PayClient 实现类 + * 文档:JSAPI 下单 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:40 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxPubPayClient extends AbstractWxPayClient { + + public WxPubPayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_PUB.getKey(), config); + } + + protected WxPubPayClient(String channelId, String channelCode, WxPayClientConfig config) { + super(channelId, channelCode, config); + } + + @Override + protected void doInit() { + super.doInit(WxPayConstants.TradeType.JSAPI); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO) + .setOpenid(getOpenid(reqDTO)); + // 执行请求 + WxPayMpOrderResult response = client.createOrder(request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.APP.getKey(), JSONUtil.toJsonStr(response), + reqDTO.getOutTradeNo(), response); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO) + .setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO))); + // 执行请求 + WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.APP.getKey(), JSONUtil.toJsonStr(response), + reqDTO.getOutTradeNo(), response); + } + + // ========== 各种工具方法 ========== + + static String getOpenid(PayOrderUnifiedReqDTO reqDTO) { + String openid = MapUtil.getStr(reqDTO.getChannelExtras(), "openid"); + if (StrUtil.isEmpty(openid)) { + throw new CustomException("支付请求的 openid 不能为空!"); + } + return openid; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxWapPayClient.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxWapPayClient.java new file mode 100644 index 0000000..31266e6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/core/service/impl/weixin/WxWapPayClient.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.core.service.impl.weixin; + +import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.enums.PayOrderDisplayMode; +import com.skyeye.pay.enums.PayType; +import lombok.extern.slf4j.Slf4j; + +/** + * @ClassName: WxWapPayClient + * @Description: 微信支付(H5 网页)的 PayClient 实现类 + * 文档:H5下单API + * @author: skyeye云系列--卫志强 + * @date: 2024/9/11 9:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class WxWapPayClient extends AbstractWxPayClient { + + public WxWapPayClient(String channelId, WxPayClientConfig config) { + super(channelId, PayType.WX_WAP.getKey(), config); + } + + protected WxWapPayClient(String channelId, String channelCode, WxPayClientConfig config) { + super(channelId, channelCode, config); + } + + @Override + protected void doInit() { + super.doInit(WxPayConstants.TradeType.MWEB); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderRequest request = buildPayUnifiedOrderRequestV2(reqDTO); + // 执行请求 + WxPayMwebOrderResult response = client.createOrder(request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.URL.getKey(), response.getMwebUrl(), + reqDTO.getOutTradeNo(), response); + } + + @Override + protected PayOrderRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { + // 构建 WxPayUnifiedOrderRequest 对象 + WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO); + // 执行请求 + String response = client.createOrderV3(TradeTypeEnum.H5, request); + + // 转换结果 + return PayOrderRespDTO.waitingOf(PayOrderDisplayMode.URL.getKey(), response, + reqDTO.getOutTradeNo(), response); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayAppDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayAppDao.java new file mode 100644 index 0000000..ef49d76 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayAppDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pay.entity.PayApp; +/** + * @ClassName: PayAppDao + * @Description: 支付应用信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayAppDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayChannelDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayChannelDao.java new file mode 100644 index 0000000..c43afe5 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/dao/PayChannelDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.pay.entity.PayChannel; + +/** + * @ClassName: PayChannelDao + * @Description: 支付渠道信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayChannelDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayApp.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayApp.java new file mode 100644 index 0000000..1bff05d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayApp.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.common.enumeration.EnableEnum; +import lombok.Data; + +/** + * @ClassName: PayApp + * @Description: 支付应用实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = "appKey") +@TableName(value = "skyeye_pay_app") +@ApiModel("支付应用实体类") +public class PayApp extends BaseGeneralInfo { + + @TableField("app_key") + @ApiModelProperty(value = "应用名", required = "required") + private String appKey; + + @TableField("enabled") + @ApiModelProperty(value = "状态", required = "required", enumClass = EnableEnum.class) + private Integer enabled; + + @TableField("order_notify_url") + @ApiModelProperty(value = "支付结果的回调地址", required = "required") + private String orderNotifyUrl; + + @TableField("refund_notify_url") + @ApiModelProperty(value = "退款结果的回调地址", required = "required") + private String refundNotifyUrl; + + @TableField("transfer_notify_url") + @ApiModelProperty(value = "转账结果的回调地址") + private String transferNotifyUrl; +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayChannel.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayChannel.java new file mode 100644 index 0000000..4ef8c26 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/entity/PayChannel.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.pay.core.PayClientConfig; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: PayChannel + * @Description: 支付渠道实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField({"codeNum", "appId"}) +@RedisCacheField(name = "skyeye:payChannel", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "skyeye_pay_channel", autoResultMap = true) +@ApiModel("支付渠道实体类") +public class PayChannel extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("code_num") + @ApiModelProperty(value = "渠道编码,参考#PayType", required = "required") + private String codeNum; + + @TableField(exist = false) + @Property("渠道编码对应的信息") + private Map codeNumMation; + + @TableField("enabled") + @ApiModelProperty(value = "启用状态", required = "required") + private Integer enabled; + + @TableField("feeRate") + @ApiModelProperty(value = "渠道费率,单位:百分比", required = "required") + private Long feeRate; + + @TableField("app_id") + @ApiModelProperty(value = "应用id", required = "required") + private String appId; + + @TableField(exist = false) + @Property("应用信息") + private PayApp appMation; + + @TableField(value = "config") + @ApiModelProperty(value = "支付渠道配置", required = "required") + private String config; + + @TableField(exist = false) + @Property(value = "支付渠道配置信息") + private PayClientConfig configMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayChannelVersion.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayChannelVersion.java new file mode 100644 index 0000000..50142b4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayChannelVersion.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PayChannelVersion + * @Description: 微信支付的API版本枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayChannelVersion implements SkyeyeEnumClass { + + // V2 协议说明 + V2_VERSION("V2", "V2 协议", true, false), + // V3 协议说明 + V3_VERSION("V3", "V3 协议", true, true); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderDisplayMode.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderDisplayMode.java new file mode 100644 index 0000000..c27a90f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderDisplayMode.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PayOrderDisplayMode + * @Description: 支付 UI 展示模式 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:30 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayOrderDisplayMode implements SkyeyeEnumClass { + + URL("url", "Redirect 跳转链接的方式", true, false), + IFRAME("iframe", "IFrame 内嵌链接的方式【目前暂时用不到】", true, false), + FORM("form", "HTML 表单提交", true, false), + QR_CODE("qr_code", "二维码的文字内容", true, false), + QR_CODE_URL("qr_code_url", "二维码的图片链接", true, false), + BAR_CODE("bar_code", "条形码", true, false), + APP("app", "应用:Android、iOS、微信小程序、微信公众号等,需要做自定义处理的", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderStatusResp.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderStatusResp.java new file mode 100644 index 0000000..8a2fb7c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayOrderStatusResp.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Objects; + +/** + * @ClassName: PayOrderStatusResp + * @Description: 渠道的支付状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:27 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayOrderStatusResp implements SkyeyeEnumClass { + + WAITING(0, "未支付", true, false), + SUCCESS(10, "支付成功", true, false), + REFUND(20, "已退款", true, false), + CLOSED(30, "支付关闭", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + /** + * 判断是否支付成功 + * + * @param status 状态 + * @return 是否支付成功 + */ + public static boolean isSuccess(Integer status) { + return Objects.equals(status, SUCCESS.getKey()); + } + + /** + * 判断是否已退款 + * + * @param status 状态 + * @return 是否支付成功 + */ + public static boolean isRefund(Integer status) { + return Objects.equals(status, REFUND.getKey()); + } + + /** + * 判断是否支付关闭 + * + * @param status 状态 + * @return 是否支付关闭 + */ + public static boolean isClosed(Integer status) { + return Objects.equals(status, CLOSED.getKey()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayRefundStatusResp.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayRefundStatusResp.java new file mode 100644 index 0000000..06d0033 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayRefundStatusResp.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PayRefundStatusResp + * @Description: 渠道的退款状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayRefundStatusResp implements SkyeyeEnumClass { + + WAITING(0, "等待退款", true, false), + SUCCESS(1, "退款成功", true, false), + FAILURE(2, "退款失败", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferStatusResp.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferStatusResp.java new file mode 100644 index 0000000..6dd42d2 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferStatusResp.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PayTransferStatusResp + * @Description: 渠道的转账状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayTransferStatusResp implements SkyeyeEnumClass { + + WAITING(0, "等待转账", true, false), + /** + * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现 + * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子? + */ + IN_PROGRESS(10, "转账进行中", true, false), + SUCCESS(20, "转账成功", true, false), + CLOSED(30, "转账关闭", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferType.java new file mode 100644 index 0000000..09f29c0 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayTransferType.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import cn.hutool.core.util.ArrayUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PayTransferType + * @Description: 转账类型枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/10 8:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayTransferType implements SkyeyeEnumClass { + + ALIPAY_BALANCE(1, "支付宝余额", true, false), + WX_BALANCE(2, "微信余额", true, false), + BANK_CARD(3, "银行卡", true, false), + WALLET_BALANCE(4, "钱包余额", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static PayTransferType typeOf(Integer type) { + return ArrayUtil.firstMatch(item -> item.getKey().equals(type), values()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayType.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayType.java new file mode 100644 index 0000000..a1cc0dc --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/enums/PayType.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.enums; + +import cn.hutool.core.util.ArrayUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.pay.core.PayClientConfig; +import com.skyeye.pay.core.service.NonePayClientConfig; +import com.skyeye.pay.core.service.impl.alipay.AlipayPayClientConfig; +import com.skyeye.pay.core.service.impl.weixin.WxPayClientConfig; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: PayType + * @Description: 付款类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PayType implements SkyeyeEnumClass { + + WX_PUB("wx_pub", "微信 JSAPI 支付", WxPayClientConfig.class, true, false), // 公众号网页 + WX_LITE("wx_lite", "微信小程序支付", WxPayClientConfig.class, true, false), + WX_APP("wx_app", "微信 App 支付", WxPayClientConfig.class, true, false), + WX_NATIVE("wx_native", "微信 Native 支付", WxPayClientConfig.class, true, false), + WX_WAP("wx_wap", "微信 Wap 网站支付", WxPayClientConfig.class, true, false), // H5 网页 + WX_BAR("wx_bar", "微信付款码支付", WxPayClientConfig.class, true, false), + + ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class, true, false), + ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class, true, false), + ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class, true, false), + ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class, true, false), + ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class, true, false), + MOCK("mock", "模拟支付", NonePayClientConfig.class, true, false), + + // TODO 钱包支付暂时不支持,后续再添加 + WALLET("wallet", "钱包支付", NonePayClientConfig.class, false, false); + + private String key; + + private String value; + + private Class configClass; + + private Boolean show; + + private Boolean isDefault; + + public static PayType getByCode(String code) { + return ArrayUtil.firstMatch(o -> o.getKey().equals(code), values()); + } + + public static boolean isAlipay(String channelCode) { + return channelCode != null && channelCode.startsWith("alipay"); + } + + public static Map getMation(String code) { + PayType type = getByCode(code); + Map result = new HashMap<>(); + result.put("id", type.getKey()); + result.put("name", type.getValue()); + return result; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayAppService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayAppService.java new file mode 100644 index 0000000..cf68dd9 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayAppService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.pay.entity.PayApp; + +/** + * @ClassName: PayAppService + * @Description: 支付应用服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayAppService extends SkyeyeBusinessService { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayChannelService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayChannelService.java new file mode 100644 index 0000000..5e1f10b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayChannelService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.pay.core.PayClient; +import com.skyeye.pay.entity.PayChannel; + +/** + * @ClassName: PayChannelService + * @Description: 支付渠道服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayChannelService extends SkyeyeBusinessService { + + PayClient getPayClient(String id); + + PayChannel getPayChannelByCode(String codeNum); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayService.java new file mode 100644 index 0000000..3d9a955 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/PayService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: PayService + * @Description: 统一支付接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PayService { + + void payment(InputObject inputObject, OutputObject outputObject); + + void generatePayRrCode(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayAppServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayAppServiceImpl.java new file mode 100644 index 0000000..1308fdb --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayAppServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.dao.PayAppDao; +import com.skyeye.pay.entity.PayApp; +import com.skyeye.pay.service.PayAppService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PayAppServiceImpl + * @Description: 支付应用服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "支付应用管理", groupName = "支付应用管理") +public class PayAppServiceImpl extends SkyeyeBusinessServiceImpl implements PayAppService { + + @Override + public void updatePrepose(PayApp payApp) { + verify(payApp.getId()); + } + + private void verify(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, id); + PayApp one = getOne(queryWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("该支付应用信息不存在"); + } + } + + @Override + protected void writePostpose(PayApp entity, String userId) { + if (entity.getEnabled().equals(EnableEnum.ENABLE_USING.getKey())) { + // 如果将当前数据修改为启动数据,则需要修改之前的数据为禁用 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.ne(CommonConstants.ID, entity.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(PayApp::getEnabled), EnableEnum.DISABLE_USING.getKey()); + update(updateWrapper); + } + } + + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PayApp::getEnabled), CommonNumConstants.NUM_ONE); + List list = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(list), null); + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayChannelServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayChannelServiceImpl.java new file mode 100644 index 0000000..4eec8c7 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayChannelServiceImpl.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.PayClient; +import com.skyeye.pay.core.PayClientConfig; +import com.skyeye.pay.core.PayClientFactory; +import com.skyeye.pay.dao.PayChannelDao; +import com.skyeye.pay.entity.PayApp; +import com.skyeye.pay.entity.PayChannel; +import com.skyeye.pay.enums.PayType; +import com.skyeye.pay.service.PayAppService; +import com.skyeye.pay.service.PayChannelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.validation.Validator; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PayChannelServiceImpl + * @Description: 支付渠道服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "支付渠道", groupName = "支付渠道") +public class PayChannelServiceImpl extends SkyeyeBusinessServiceImpl implements PayChannelService { + + @Autowired + private PayAppService payAppService; + + @Autowired + private PayClientFactory payClientFactory; + + @Autowired + private Validator validator; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + payAppService.setMationForMap(beans, "appId", "appMation"); + return beans; + } + + @Override + public PayChannel selectById(String id) { + PayChannel payChannel = super.selectById(id); + payAppService.setDataMation(payChannel, PayChannel::getAppId); + payChannel.setCodeNumMation(PayType.getMation(payChannel.getCodeNum())); + + // 解析配置 + Class payClass = PayType.getByCode(payChannel.getCodeNum()).getConfigClass(); + if (ObjectUtil.isNull(payClass)) { + throw new CustomException("支付渠道的配置不存在"); + } + PayClientConfig config = JSONUtil.toBean(payChannel.getConfig(), payClass); + payChannel.setConfigMation(config); + + return payChannel; + } + + @Override + public void validatorEntity(PayChannel entity) { + super.validatorEntity(entity); + // 解析配置 + Class payClass = PayType.getByCode(entity.getCodeNum()).getConfigClass(); + if (ObjectUtil.isNull(payClass)) { + throw new CustomException("支付渠道的配置不存在"); + } + PayClientConfig config = JSONUtil.toBean(entity.getConfig(), payClass); + Assert.notNull(config); + // 验证参数 + config.validate(validator); + } + + @Override + public void updatePrepose(PayChannel payChannel) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, payChannel.getId()); + PayChannel one = getOne(queryWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("该支付应用信息不存在"); + } + } + + @Override + public PayClient getPayClient(String id) { + PayChannel payChannel = selectById(id); + if (ObjectUtil.isEmpty(payChannel)) { + throw new CustomException("该支付渠道不存在"); + } + payClientFactory.createOrUpdatePayClient(id, payChannel.getCodeNum(), payChannel.getConfigMation()); + return null; + } + + @Override + public PayChannel getPayChannelByCode(String codeNum) { + MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper() + .innerJoin(PayApp.class, PayApp::getId, PayChannel::getAppId) + .eq(PayApp::getEnabled, EnableEnum.ENABLE_USING.getKey()) + .eq(PayChannel::getEnabled, EnableEnum.ENABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(PayChannel::getCodeNum), codeNum); + PayChannel one = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("该支付渠道不存在"); + } + return one; + } +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayServiceImpl.java new file mode 100644 index 0000000..39a11da --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/pay/service/impl/PayServiceImpl.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.pay.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.google.common.collect.Maps; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.pay.core.PayClient; +import com.skyeye.pay.core.dto.order.PayOrderRespDTO; +import com.skyeye.pay.core.dto.order.PayOrderUnifiedReqDTO; +import com.skyeye.pay.entity.PayChannel; +import com.skyeye.pay.enums.PayOrderStatusResp; +import com.skyeye.pay.enums.PayType; +import com.skyeye.pay.service.PayChannelService; +import com.skyeye.pay.service.PayService; +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 java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @ClassName: PayServiceImpl + * @Description: 统一支付接口实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "统一支付", groupName = "统一支付") +public class PayServiceImpl implements PayService { + + private static Logger log = LoggerFactory.getLogger(PayServiceImpl.class); + + @Autowired + private PayChannelService payChannelService; + + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void payment(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + Map data = JSONUtil.toBean(params.get("data").toString(), null); + String channelCode = params.get("channelCode").toString(); + String returnUrl = params.get("returnUrl").toString(); + String channelExtrasStr = params.get("channelExtras").toString(); + String notifyUrl = params.get("notifyUrl").toString(); + PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO(); + + // 1. 钱包支付事,需要额外传 user_id 和 user_type + if (Objects.equals(channelCode, PayType.WALLET.getKey())) { + Map channelExtras = StrUtil.isBlank(channelExtrasStr) ? + Maps.newHashMapWithExpectedSize(1) : JSONUtil.toBean(channelExtrasStr, null); + String userId = inputObject.getLogParams().get(CommonConstants.ID).toString(); + channelExtras.put(CommonConstants.USER_ID_KEY, userId); + reqDTO.setChannelExtras(channelExtras); + } + + // 支付渠道 + PayChannel payChannel = payChannelService.getPayChannelByCode(channelCode); + PayClient client = payChannelService.getPayClient(payChannel.getId()); + // 2. 调用支付渠道接口 + PayOrderUnifiedReqDTO unifiedReqDTO = new PayOrderUnifiedReqDTO(); + unifiedReqDTO.setOutTradeNo(data.get("oddNumber").toString()); + unifiedReqDTO.setSubject("购买商品"); + unifiedReqDTO.setBody("购买商品信息"); + unifiedReqDTO.setNotifyUrl(notifyUrl); + unifiedReqDTO.setReturnUrl(returnUrl); + unifiedReqDTO.setPrice(Integer.parseInt(data.get("payPrice").toString())); + PayOrderRespDTO payOrderRespDTO = client.unifiedOrder(unifiedReqDTO); + + // 3. 如果调用直接支付成功,则直接更新支付单状态为成功。例如说:付款码支付,免密支付时,就直接验证支付成功 + if (payOrderRespDTO != null) { + notifyOrder(payOrderRespDTO); + log.info("[submitOrder][order(%s) payChannel(%s) 支付结果(%s)]", + data, payChannel, payOrderRespDTO); + // 如有渠道错误码,则抛出业务异常,提示用户 + if (StrUtil.isNotEmpty(payOrderRespDTO.getChannelErrorCode())) { + throw new CustomException(String.format("发起支付报错,错误码:%s,错误提示:%s", payOrderRespDTO.getChannelErrorCode(), payOrderRespDTO.getChannelErrorMsg())); + } + Map result = new HashMap<>(); + result.put("payChannel", JSONUtil.toJsonStr(payChannel)); + result.put("payOrderRespDTO", JSONUtil.toJsonStr(payOrderRespDTO)); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } else { + throw new CustomException("发起支付失败,请稍后重试"); + } + } + + public void notifyOrder(PayOrderRespDTO notify) { + // 情况一:支付成功的回调 + if (PayOrderStatusResp.isSuccess(notify.getStatus())) { + return; + } + // 情况二:支付失败的回调 + if (PayOrderStatusResp.isClosed(notify.getStatus())) { + throw new CustomException("支付失败,请稍后重试"); + } + // 情况三:WAITING:无需处理 + // 情况四:REFUND:通过退款回调处理 + } + + @Override + public void generatePayRrCode(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + Map data = JSONUtil.toBean(params.get("data").toString(), null); + String channelCode = params.get("channelCode").toString(); + String notifyUrl = params.get("notifyUrl").toString(); + String ip = params.get("ip").toString(); + // 支付渠道 + PayChannel payChannel = payChannelService.getPayChannelByCode(channelCode); + PayClient client = payChannelService.getPayClient(payChannel.getId()); + String qrCodeUrl = client.generateRrCode(data.get("oddNumber").toString(), "购买商品", data.get("payPrice").toString(), ip, notifyUrl); + Map result = new HashMap<>(); + result.put("qrCodeUrl", qrCodeUrl); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/rest/IReportPageRest.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/rest/IReportPageRest.java new file mode 100644 index 0000000..f9b4efa --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/rest/IReportPageRest.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.report.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: IReportPageRest + * @Description: 报表管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-report}", configuration = ClientConfiguration.class) +public interface IReportPageRest { + + /** + * 根据id获取报表页面信息 + * + * @param id 主键id + */ + @GetMapping("/queryReportPageById") + String queryReportPageById(@RequestParam("id") String id); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/IReportPageService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/IReportPageService.java new file mode 100644 index 0000000..a66450b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/IReportPageService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.report.service; + +import com.skyeye.base.rest.service.IService; + +/** + * @ClassName: IReportPageService + * @Description: 报表管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IReportPageService extends IService { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/impl/IReportPageServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/impl/IReportPageServiceImpl.java new file mode 100644 index 0000000..6ba4b9c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/rest/report/service/impl/IReportPageServiceImpl.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.report.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.rest.report.rest.IReportPageRest; +import com.skyeye.rest.report.service.IReportPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: IReportPageServiceImpl + * @Description: 报表管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IReportPageServiceImpl extends IServiceImpl implements IReportPageService { + + @Autowired + private IReportPageRest iReportPageRest; + + @Override + public Map queryEntityMationById(String id) { + return ExecuteFeignClient.get(() -> iReportPageRest.queryReportPageById(id)).getBean(); + } + + @Override + public String queryCacheKeyById(String id) { + return String.format(Locale.ROOT, "%s:%s", CacheConstants.REPORT_PAGE_CACHE_KEY, id); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanController.java new file mode 100644 index 0000000..9792714 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanController.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.ServiceBeanApi; +import com.skyeye.server.service.ServiceBeanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ServiceBeanController + * @Description: 所有实现了SkyeyeBusinessService的服务类的注册服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:08 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "服务类注册", tags = "服务类注册", modelName = "系统公共模块") +public class ServiceBeanController { + + @Autowired + private ServiceBeanService serviceBeanService; + + /** + * 服务类注册 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "registerServiceBean", value = "服务类注册", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = ServiceBeanApi.class) + @RequestMapping("/post/ServiceBeanController/registerServiceBean") + public void registerServiceBean(InputObject inputObject, OutputObject outputObject) { + serviceBeanService.registerServiceBean(inputObject, outputObject); + } + + /** + * 获取服务类信息(树结构) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryServiceClassForTree", value = "获取服务类信息(树结构)", method = "GET", allUse = "2") + @RequestMapping("/post/ServiceBeanController/queryServiceClassForTree") + public void queryServiceClassForTree(InputObject inputObject, OutputObject outputObject) { + serviceBeanService.queryServiceClassForTree(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanCustomController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanCustomController.java new file mode 100644 index 0000000..fe1536f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/controller/ServiceBeanCustomController.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.ServiceBeanCustom; +import com.skyeye.server.service.ServiceBeanCustomService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ServerController + * @Description: 自定义服务管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/6 22:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "自定义服务管理", tags = "自定义服务管理", modelName = "系统公共模块") +public class ServiceBeanCustomController { + + @Autowired + private ServiceBeanCustomService serviceBeanCustomService; + + /** + * 获取服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryServiceBeanCustom", value = "获取服务信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "className", name = "className", value = "service的className", required = "required"), + @ApiImplicitParam(id = "appId", name = "appId", value = "服务的appId")}) + @RequestMapping("/post/ServiceBeanCustomController/queryServiceBeanCustom") + public void queryServiceBeanCustom(InputObject inputObject, OutputObject outputObject) { + serviceBeanCustomService.queryServiceBeanCustom(inputObject, outputObject); + } + + /** + * 保存自定义服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "saveServiceBeanCustom", value = "保存自定义服务信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ServiceBeanCustom.class) + @RequestMapping("/post/ServiceBeanCustomController/saveServiceBeanCustom") + public void saveServiceBeanCustom(InputObject inputObject, OutputObject outputObject) { + serviceBeanCustomService.saveOrUpdateEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanCustomDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanCustomDao.java new file mode 100644 index 0000000..4b17607 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanCustomDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.server.entity.ServiceBeanCustom; + +/** + * @ClassName: ServiceBeanCustomDao + * @Description: 自定义服务管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/6 22:43 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ServiceBeanCustomDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanDao.java new file mode 100644 index 0000000..89f64db --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/dao/ServiceBeanDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.dao; + +import com.skyeye.server.entity.ServiceBean; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SkyeyeClassServiceBeanDao + * @Description: 所有实现了SkyeyeBusinessService的服务类的注册服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:08 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ServiceBeanDao extends SkyeyeBaseMapper { + + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBean.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBean.java new file mode 100644 index 0000000..a33a5e6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBean.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ServiceBean + * @Description: 服务类注册实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 13:11 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_class_service_bean", autoResultMap = true) +@ApiModel("服务类注册实体类") +public class ServiceBean extends CommonInfo { + + @TableId("id") + @Property("主键id") + private String id; + + /** + * 服务名 + */ + @TableField(value = "spring_application_name") + private String springApplicationName; + + @TableField(exist = false) + @Property("服务名(中文名称)") + private String applicationName; + + @TableField(value = "app_id") + @Property("应用的appId") + private String appId; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField("`name`") + @ApiModelProperty(value = "服务名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("group_name") + @ApiModelProperty(value = "所属分组") + private String groupName; + + @TableField("tenant") + @ApiModelProperty(value = "租户类型") + private String tenant; + + @TableField("manage_show") + @ApiModelProperty(value = "是否可以在界面上进行管理") + private Boolean manageShow; + + @TableField("entity_class_name") + @ApiModelProperty(value = "实体类的className", required = "required") + private String entityClassName; + + @TableField(exist = false) + @ApiModelProperty(value = "实体类的属性集合", required = "json") + private List attrDefinitionList; + + @TableField("flowable") + @ApiModelProperty(value = "是否开启流程", required = "required") + private Boolean flowable; + + @TableField("team_auth") + @ApiModelProperty(value = "是否开启团队权限管理", required = "required") + private Boolean teamAuth; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanApi.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanApi.java new file mode 100644 index 0000000..00990de --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanApi.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: ServiceBeanApi + * @Description: 服务类注册实体类对应的实体类BOX + * @author: skyeye云系列--卫志强 + * @date: 2022/9/18 16:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("服务类注册实体类对应的实体类BOX") +public class ServiceBeanApi implements Serializable { + + @ApiModelProperty(value = "服务名", required = "required") + private String springApplicationName; + + @ApiModelProperty(value = "appId", required = "required") + private String appId; + + /** + * 服务类信息 + */ + @ApiModelProperty(value = "服务类信息") + private List classNameList; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanCustom.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanCustom.java new file mode 100644 index 0000000..fee588e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/entity/ServiceBeanCustom.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ServiceBeanCustom + * @Description: 自定义服务信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/6 22:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"className"}) +@TableName(value = "skyeye_class_service_bean_custom", autoResultMap = true) +@ApiModel("自定义服务信息实体类") +public class ServiceBeanCustom extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("class_name") + @ApiModelProperty(value = "服务类的className", required = "required") + private String className; + + @TableField(value = "app_id") + @ApiModelProperty(value = "应用的appId", required = "required") + private String appId; + + @TableField("code_rule_id") + @ApiModelProperty(value = "编码规则id", required = "required") + private String codeRuleId; + + @TableField(exist = false) + @Property(value = "编码规则信息") + private CodeRule codeRule; + + @TableField(exist = false) + @Property(value = "服务的原始信息") + private ServiceBean serviceBean; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanCustomService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanCustomService.java new file mode 100644 index 0000000..bde1a9c --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanCustomService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.ServiceBeanCustom; + +/** + * @ClassName: ServiceBeanCustomService + * @Description: 自定义服务管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/6 22:43 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ServiceBeanCustomService extends SkyeyeBusinessService { + + void queryServiceBeanCustom(InputObject inputObject, OutputObject outputObject); + + ServiceBeanCustom selectServiceBeanCustom(String appId, String className); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanService.java new file mode 100644 index 0000000..575bd5e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/ServiceBeanService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.server.entity.ServiceBean; + +import java.net.URI; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ServiceBeanService + * @Description: 所有实现了SkyeyeBusinessService的服务类的注册服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/29 22:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ServiceBeanService extends SkyeyeBusinessService { + + void registerServiceBean(InputObject inputObject, OutputObject outputObject); + + URI getServiceBean(String appId, String className); + + void queryServiceClassForTree(InputObject inputObject, OutputObject outputObject); + + ServiceBean queryServiceClass(String appId, String className); + + Map queryServiceClass(List classNames); + + ServiceBean getByEntityClassName(String entityClassName); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanCustomServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanCustomServiceImpl.java new file mode 100644 index 0000000..eec5dd6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanCustomServiceImpl.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.coderule.entity.CodeRule; +import com.skyeye.coderule.service.CodeRuleService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.server.dao.ServiceBeanCustomDao; +import com.skyeye.server.entity.ServiceBean; +import com.skyeye.server.entity.ServiceBeanCustom; +import com.skyeye.server.service.ServiceBeanCustomService; +import com.skyeye.server.service.ServiceBeanService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @ClassName: ServiceBeanCustomServiceImpl + * @Description: 自定义服务管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/1/6 22:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ServiceBeanCustomServiceImpl extends SkyeyeBusinessServiceImpl implements ServiceBeanCustomService { + + @Autowired + private ServiceBeanService serviceBeanService; + + @Autowired + private CodeRuleService codeRuleService; + + @Override + public void queryServiceBeanCustom(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String className = params.get("className").toString(); + String appId = params.get("appId").toString(); + ServiceBeanCustom serviceBeanCustom = selectServiceBeanCustom(appId, className); + outputObject.setBean(serviceBeanCustom); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public ServiceBeanCustom selectServiceBeanCustom(String appId, String className) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (StrUtil.isNotEmpty(appId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceBeanCustom::getAppId), appId); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceBeanCustom::getClassName), className); + ServiceBeanCustom serviceBeanCustom = getOne(queryWrapper, false); + ServiceBean serviceBean = serviceBeanService.queryServiceClass(appId, className); + if (serviceBeanCustom == null) { + serviceBeanCustom = new ServiceBeanCustom(); + } + serviceBeanCustom.setServiceBean(serviceBean); + if (StrUtil.isNotEmpty(serviceBeanCustom.getCodeRuleId())) { + CodeRule codeRule = codeRuleService.selectById(serviceBeanCustom.getCodeRuleId()); + serviceBeanCustom.setCodeRule(codeRule); + } + return serviceBeanCustom; + } + + @Override + public void builderByHandler(ServiceBeanCustom bean) { + if (bean != null) { + super.builderByHandler(bean); + } + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanServiceImpl.java new file mode 100644 index 0000000..7e60547 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/server/service/impl/ServiceBeanServiceImpl.java @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.server.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.application.service.ApplicationService; +import com.skyeye.attr.entity.AttrDefinition; +import com.skyeye.attr.service.AttrDefinitionService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.server.dao.ServiceBeanDao; +import com.skyeye.server.entity.ServiceBean; +import com.skyeye.server.entity.ServiceBeanApi; +import com.skyeye.server.service.ServiceBeanService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.net.URI; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ServiceBeanServiceImpl + * @Description: 所有实现了SkyeyeBusinessService的服务类的注册服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/29 22:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ServiceBeanServiceImpl extends SkyeyeBusinessServiceImpl implements ServiceBeanService { + + @Autowired + private DiscoveryClient discoveryClient; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private AttrDefinitionService attrDefinitionService; + + @Value("${spring.profiles.active}") + private String springProfilesActive; + + /** + * 服务类注册 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void registerServiceBean(InputObject inputObject, OutputObject outputObject) { + ServiceBeanApi serviceBeanApi = inputObject.getParams(ServiceBeanApi.class); + + // 获取数据库中的数据 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getSpringApplicationName), serviceBeanApi.getSpringApplicationName()); + List oldList = super.list(wrapper); + List oldKeys = oldList.stream().map(bean -> getKey(bean)).collect(Collectors.toList()); + + // 获取入参的数据 + List classNameList = serviceBeanApi.getClassNameList(); + classNameList.forEach(className -> { + className.setAppId(serviceBeanApi.getAppId()); + className.setSpringApplicationName(serviceBeanApi.getSpringApplicationName()); + }); + + List newKeys = classNameList.stream().map(bean -> getKey(bean)).collect(Collectors.toList()); + + // (旧数据 - 新数据) 从数据库删除 + List deleteBeans = oldList.stream().filter(item -> !newKeys.contains(getKey(item))).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(deleteBeans)) { + List classNames = deleteBeans.stream().map(bean -> bean.getClassName()).collect(Collectors.toList()); + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getSpringApplicationName), serviceBeanApi.getSpringApplicationName()); + deleteWrapper.in(MybatisPlusUtil.toColumns(ServiceBean::getClassName), classNames); + remove(deleteWrapper); + } + + // (新数据 - 旧数据) 添加到数据库 + List addBeans = classNameList.stream().filter(item -> !oldKeys.contains(getKey(item))).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(addBeans)) { + createEntity(addBeans, StringUtils.EMPTY); + } + + // 保存属性信息 + saveAttrDefinition(serviceBeanApi.getAppId(), classNameList); + } + + private String getKey(ServiceBean bean) { + return String.format(Locale.ROOT, "%s_%s_%s_%s_%s_%s_%s_%s", bean.getAppId(), bean.getClassName(), bean.getManageShow(), + bean.getTeamAuth(), bean.getTenant(), bean.getFlowable(), bean.getName(), bean.getGroupName()); + } + + private void saveAttrDefinition(String appId, List classNameList) { + List attrDefinitionList = classNameList.stream() + .filter(className -> CollectionUtil.isNotEmpty(className.getAttrDefinitionList())) + .flatMap(className -> className.getAttrDefinitionList().stream()) + .filter(Objects::nonNull).collect(Collectors.toList()); + attrDefinitionService.saveBarchAttrDefinition(appId, attrDefinitionList); + } + + @Override + public URI getServiceBean(String appId, String className) { + ServiceBean serviceBean = queryServiceClass(appId, className); + if (serviceBean == null) { + throw new CustomException("未找到 service bean 对应的业务类配置信息."); + } + // 根据服务名获取服务实例 + List allInstances = discoveryClient.getInstances(serviceBean.getSpringApplicationName()); + if (CollectionUtil.isEmpty(allInstances)) { + throw new CustomException(String.format(Locale.ROOT, "this service[%s] has no instance.", serviceBean.getSpringApplicationName())); + } + return allInstances.get(0).getUri(); + } + + /** + * 获取服务类信息(树结构) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryServiceClassForTree(InputObject inputObject, OutputObject outputObject) { + List> applications = applicationService.queryApplicationList(); + // 查询服务类信息 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getManageShow), true); + wrapper.likeLeft(MybatisPlusUtil.toColumns(ServiceBean::getSpringApplicationName), springProfilesActive); + List> serviceClass = list(wrapper) + .stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + List> result = buildResult(serviceClass); + applications.forEach(application -> { + result.add(getResultMap(application.get("appId").toString(), application.get("appName").toString(), "0", true)); + }); + // 转为树 + List> treeNodes = TreeUtil.build(result, String.valueOf(CommonNumConstants.NUM_ZERO), new TreeNodeConfig(), + (treeNode, tree) -> { + tree.setId(treeNode.get("key").toString()); + tree.setParentId(treeNode.get("parentKey").toString()); + tree.setName(treeNode.get("name").toString()); + tree.putExtra("appId", treeNode.get("appId")); + tree.putExtra("isParent", treeNode.get("isParent")); + tree.putExtra("disabled", treeNode.get("disabled")); + tree.putExtra("nocheck", treeNode.get("nocheck")); + tree.putExtra("classMation", treeNode.get("classMation")); + }); + outputObject.setBeans(treeNodes); + outputObject.settotal(treeNodes.size()); + + } + + private List> buildResult(List> serviceClass) { + List> result = new ArrayList<>(); + Map>> collect = serviceClass.stream().collect(Collectors.groupingBy(bean -> bean.get("appId").toString())); + collect.forEach((appId, classNameList) -> { + // 获取没有分组的业务对象服务类 + List noGroupNameClassNameIdList = classNameList.stream() + .filter(bean -> MapUtil.checkKeyIsNull(bean, "groupName")) + .map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(noGroupNameClassNameIdList)) { + String groupKey = appId + ".noGroupName"; + result.add(getResultMap(groupKey, "未分组", appId, true)); + setClassName(serviceClass, result, noGroupNameClassNameIdList, groupKey); + } + // 获取有分组的业务对象服务类 + Map>> hasGroupNameIdList = classNameList.stream() + .filter(bean -> !MapUtil.checkKeyIsNull(bean, "groupName")) + .collect(Collectors.groupingBy(bean -> bean.get("groupName").toString())); + hasGroupNameIdList.forEach((groupName, classNames) -> { + String groupKey = appId + ".hasGroupName" + "." + groupName; + result.add(getResultMap(groupKey, groupName, appId, true)); + List classNameIds = classNames.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + setClassName(classNames, result, classNameIds, groupKey); + }); + }); + return result; + } + + private void setClassName(List> serviceClass, List> result, List classNameIds, String groupKey) { + serviceClass.forEach(bean -> { + String id = bean.get("id").toString(); + if (classNameIds.indexOf(id) >= 0) { + String key = bean.get("appId").toString() + bean.get("className").toString(); + Map resultMap = getResultMap(key, bean.get("name").toString(), groupKey, false); + resultMap.put("classMation", bean); + result.add(resultMap); + } + }); + } + + private Map getResultMap(String key, String name, String parentKey, Boolean isParent) { + Map groupName = new HashMap<>(); + groupName.put("key", key); + groupName.put("name", name); + groupName.put("parentKey", parentKey); + groupName.put("isParent", isParent); + if (isParent) { + groupName.put("disabled", true); + groupName.put("nocheck", true); + } else { + groupName.put("disabled", false); + } + return groupName; + } + + @Override + public ServiceBean queryServiceClass(String appId, String className) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (StrUtil.isNotEmpty(appId)) { + wrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getAppId), appId); + } + wrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getClassName), className); + wrapper.likeLeft(MybatisPlusUtil.toColumns(ServiceBean::getSpringApplicationName), springProfilesActive); + ServiceBean skyeyeClassServiceBean = getOne(wrapper); + return skyeyeClassServiceBean; + } + + @Override + public Map queryServiceClass(List classNames) { + if (CollectionUtil.isEmpty(classNames)) { + return cn.hutool.core.map.MapUtil.newHashMap(); + } + // 获取所属应用信息 + List> applications = applicationService.queryApplicationList(); + Map applicationMap = applications.stream().collect(Collectors.toMap(bean -> bean.get("appId").toString(), bean -> bean.get("appName").toString())); + // 查询属性列表 + classNames = classNames.stream().distinct().collect(Collectors.toList()); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.in("CONCAT(" + MybatisPlusUtil.toColumns(ServiceBean::getAppId) + ", " + MybatisPlusUtil.toColumns(ServiceBean::getClassName) + ")", classNames); + wrapper.likeLeft(MybatisPlusUtil.toColumns(ServiceBean::getSpringApplicationName), springProfilesActive); + List serviceBeans = list(wrapper); + // 获取原始的属性列表 + Map> attrDefinitionMap = attrDefinitionService.queryAttrDefinitionList(classNames); + serviceBeans.forEach(serviceBean -> { + serviceBean.setApplicationName(applicationMap.get(serviceBean.getAppId())); + serviceBean.setAttrDefinitionList(attrDefinitionMap.get(serviceBean.getClassName())); + }); + Map serviceBeanMap = serviceBeans.stream().collect(Collectors.toMap(item -> item.getAppId() + item.getClassName(), bean -> bean)); + return serviceBeanMap; + } + + @Override + public ServiceBean getByEntityClassName(String entityClassName) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(ServiceBean::getEntityClassName), entityClassName); + return getOne(wrapper); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/FileConfigController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/FileConfigController.java new file mode 100644 index 0000000..e3988f9 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/FileConfigController.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.upload.entity.FileConfig; +import com.skyeye.upload.service.FileConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FileConfigController + * @Description: 文件配置控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "文件配置", tags = "文件配置", modelName = "文件配置") +public class FileConfigController { + + @Autowired + private FileConfigService fileConfigService; + + @ApiOperation(id = "queryFileConfigList", value = "获取文件配置列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/FileConfigController/queryFileConfigList") + public void queryFileConfigList(InputObject inputObject, OutputObject outputObject) { + fileConfigService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeFileConfig", value = "新增/编辑文件配置", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = FileConfig.class) + @RequestMapping("/post/FileConfigController/writeFileConfig") + public void writeFileConfig(InputObject inputObject, OutputObject outputObject) { + fileConfigService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryFileConfigById", value = "根据id查询文件配置", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConfigController/queryFileConfigById") + public void queryFileConfigById(InputObject inputObject, OutputObject outputObject) { + fileConfigService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "deleteFileConfigById", value = "删除文件配置", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/FileConfigController/deleteFileConfigById") + public void deleteFileConfigById(InputObject inputObject, OutputObject outputObject) { + fileConfigService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/UploadController.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/UploadController.java new file mode 100644 index 0000000..12bd295 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/controller/UploadController.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.upload.entity.Upload; +import com.skyeye.upload.entity.UploadChunks; +import com.skyeye.upload.service.UploadService; +import org.springframework.beans.factory.annotation.Autowired; +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 javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @ClassName: UploadController + * @Description: 文件上传、下载控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "文件上传、下载", tags = "文件上传、下载", modelName = "基础模块") +public class UploadController { + + @Autowired + private UploadService uploadService; + + /** + * 断点续传上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "skyeyeUploadFile", value = "断点续传上传文件", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Upload.class) + @RequestMapping("/post/UploadController/uploadFileResume") + public void uploadFileResume(InputObject inputObject, OutputObject outputObject) { + uploadService.uploadFileResume(inputObject, outputObject); + } + + /** + * 上传文件合并块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "skyeyeUploadFileChunks", value = "上传文件合并块", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = UploadChunks.class) + @RequestMapping("/post/UploadController/uploadFileChunks") + public void uploadFileChunks(InputObject inputObject, OutputObject outputObject) { + uploadService.uploadFileChunks(inputObject, outputObject); + } + + /** + * 文件分块上传检测是否上传 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "checkUploadFileChunks", value = "文件分块上传检测是否上传", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "md5", name = "md5", value = "文件唯一标示", required = "required"), + @ApiImplicitParam(id = "chunk", name = "chunk", value = "分块上传的块下标", required = "required"), + @ApiImplicitParam(id = "chunkSize", name = "chunkSize", value = "分块上传时,块的大小,用于最后合并", required = "required")}) + @RequestMapping("/post/UploadController/checkUploadFileChunks") + public void checkUploadFileChunks(InputObject inputObject, OutputObject outputObject) { + uploadService.checkUploadFileChunks(inputObject, outputObject); + } + + /** + * 上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "common003", value = "上传文件", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "type", name = "type", value = "文件类型", required = "required,num")}) + @RequestMapping("/post/UploadController/uploadFile") + public void uploadFile(InputObject inputObject, OutputObject outputObject) { + uploadService.uploadFile(inputObject, outputObject); + } + + /** + * 上传文件Base64 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "common004", value = "上传文件Base64", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "type", name = "type", value = "文件类型", required = "required,num"), + @ApiImplicitParam(id = "images", name = "images", value = "图片Base64", required = "required")}) + @RequestMapping("/post/UploadController/uploadFileBase64") + public void uploadFileBase64(InputObject inputObject, OutputObject outputObject) { + uploadService.uploadFileBase64(inputObject, outputObject); + } + + /** + * 文件下载 + * + * @param request + * @param response + * @param configId + */ + @GetMapping("/upload/{configId}/get/**") + public void getFileContent(HttpServletRequest request, + HttpServletResponse response, + @PathVariable("configId") String configId) { + uploadService.getFileContent(request, response, configId); + } + + /** + * 删除文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFileByPath", value = "删除文件", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "path", name = "path", value = "文件路径", required = "required")}) + @RequestMapping("/post/UploadController/deleteFileByPath") + public void deleteFileByPath(InputObject inputObject, OutputObject outputObject) { + uploadService.deleteFileByPath(inputObject, outputObject); + } + + /** + * 获取文件预签名地址,模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getFilePresignedUrl", value = "获取文件预签名地址,模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "path", name = "path", value = "文件路径", required = "required")}) + @RequestMapping("/post/UploadController/getFilePresignedUrl") + public void getFilePresignedUrl(InputObject inputObject, OutputObject outputObject) { + uploadService.getFilePresignedUrl(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileConfigDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileConfigDao.java new file mode 100644 index 0000000..6779dea --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileConfigDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.upload.entity.FileConfig; + +/** + * @ClassName: FileConfigDao + * @Description: 文件配置数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileConfigDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileContentDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileContentDao.java new file mode 100644 index 0000000..b075d65 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileContentDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.upload.entity.FileContent; + +/** + * @ClassName: FileContentDao + * @Description: 文件内容数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 20:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileContentDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileDao.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileDao.java new file mode 100644 index 0000000..18c837a --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/dao/FileDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.upload.entity.File; + +/** + * @ClassName: FileDao + * @Description: 文件数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 19:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/File.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/File.java new file mode 100644 index 0000000..4b6928e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/File.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: File + * @Description: 文件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 19:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_file", autoResultMap = true) +@ApiModel("文件实体类") +public class File extends BaseGeneralInfo { + + @TableField(value = "config_id") + @ApiModelProperty(value = "文件配置id") + private String configId; + + @TableField(value = "path") + @ApiModelProperty(value = "文件路径", required = "required") + private String path; + + @TableField(value = "url") + @ApiModelProperty(value = "文件 URL", required = "required") + private String url; + + @TableField(value = "type") + @ApiModelProperty(value = "文件类型") + private String type; + + @TableField(value = "size") + @ApiModelProperty(value = "文件大小") + private Integer size; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileConfig.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileConfig.java new file mode 100644 index 0000000..e62a264 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileConfig.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.framework.file.core.client.FileClientConfig; +import lombok.Data; + +/** + * @ClassName: FileConfig + * @Description: 文件配置实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "skyeye:fileConfig") +@TableName(value = "skyeye_file_config", autoResultMap = true) +@ApiModel("文件配置实体类") +public class FileConfig extends BaseGeneralInfo { + + @TableField(value = "is_default") + @ApiModelProperty(value = "是否默认,参考#IsDefaultEnum", required = "required,num") + private Integer isDefault; + + @TableField(value = "storage") + @ApiModelProperty(value = "存储器,参考#FileStorageEnum", required = "required,num") + private Integer storage; + + @TableField(value = "config") + @ApiModelProperty(value = "配置信息", required = "required") + private String config; + + @TableField(exist = false) + @Property(value = "配置信息") + private FileClientConfig configMation; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileContent.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileContent.java new file mode 100644 index 0000000..a9ae6f8 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/FileContent.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; +import org.apache.ibatis.type.ByteArrayTypeHandler; + +/** + * @ClassName: FileContent + * @Description: 文件内容实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "skyeye_file_content", autoResultMap = true) +@ApiModel("文件内容实体类") +public class FileContent extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "config_id") + @ApiModelProperty(value = "文件配置id") + private String configId; + + @TableField(value = "path") + @ApiModelProperty(value = "文件路径", required = "required") + private String path; + + @TableField(value = "path", typeHandler = ByteArrayTypeHandler.class) + @ApiModelProperty(value = "文件内容", required = "required") + private byte[] content; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/Upload.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/Upload.java new file mode 100644 index 0000000..516cf0d --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/Upload.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: Upload + * @Description: 文件分块上传的信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("文件分块上传的信息实体类") +public class Upload implements Serializable { + + @ApiModelProperty(value = "文件名", required = "required") + private String name; + + @ApiModelProperty(value = "文件大小", required = "required") + private String size; + + @ApiModelProperty(value = "文件类型", required = "required,num") + private Integer type; + + @ApiModelProperty(value = "文件唯一标示", required = "required") + private String md5; + + @ApiModelProperty(value = "分块上传,块下标", required = "required") + private String chunk; + + @ApiModelProperty(value = "分块上传时,块的大小,用于最后合并", required = "required") + private String chunkSize; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 文件大小单位 + */ + private String fileSizeType = "bytes"; + + /** + * 文件地址 + */ + private String fileAddress; + + /** + * 文件缩略图 + */ + private String fileThumbnail; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/UploadChunks.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/UploadChunks.java new file mode 100644 index 0000000..f2d8e88 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/entity/UploadChunks.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: UploadChunks + * @Description: 文件合并块的信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("文件合并块的信息实体类") +public class UploadChunks implements Serializable { + + @ApiModelProperty(value = "文件名", required = "required") + private String name; + + @ApiModelProperty(value = "文件大小", required = "required") + private String size; + + @ApiModelProperty(value = "文件类型", required = "required,num") + private Integer type; + + @ApiModelProperty(value = "文件唯一标示", required = "required") + private String md5; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 文件大小单位 + */ + private String fileSizeType = "bytes"; + + /** + * 文件地址 + */ + private String fileAddress; + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileFtpMode.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileFtpMode.java new file mode 100644 index 0000000..d04df0b --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileFtpMode.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.enums; + +import cn.hutool.extra.ftp.FtpMode; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FileFtpMode + * @Description: FTP上传模式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/10 10:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FileFtpMode implements SkyeyeEnumClass { + + ACTIVE(FtpMode.Active.toString(), "主动模式", true, false), + PASSIVE(FtpMode.Passive.toString(), "被动模式", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static FileFtpMode getByKey(String key) { + for (FileFtpMode fileFtpMode : FileFtpMode.values()) { + if (fileFtpMode.getKey().equals(key)) { + return fileFtpMode; + } + } + return null; + } + + public static FtpMode getFtpModeByKey(String key) { + for (FileFtpMode fileFtpMode : FileFtpMode.values()) { + if (fileFtpMode.getKey().equals(key)) { + return FtpMode.valueOf(fileFtpMode.getKey()); + } + } + return null; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileStorageEnum.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileStorageEnum.java new file mode 100644 index 0000000..ebde6e4 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/enums/FileStorageEnum.java @@ -0,0 +1,67 @@ +package com.skyeye.upload.enums; + +import cn.hutool.core.util.ArrayUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import com.skyeye.framework.file.core.client.FileClient; +import com.skyeye.framework.file.core.client.FileClientConfig; +import com.skyeye.framework.file.core.client.db.DBFileClient; +import com.skyeye.framework.file.core.client.db.DBFileClientConfig; +import com.skyeye.framework.file.core.client.ftp.FtpFileClient; +import com.skyeye.framework.file.core.client.ftp.FtpFileClientConfig; +import com.skyeye.framework.file.core.client.local.LocalFileClient; +import com.skyeye.framework.file.core.client.local.LocalFileClientConfig; +import com.skyeye.framework.file.core.client.s3.S3FileClient; +import com.skyeye.framework.file.core.client.s3.S3FileClientConfig; +import com.skyeye.framework.file.core.client.sftp.SftpFileClient; +import com.skyeye.framework.file.core.client.sftp.SftpFileClientConfig; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: FileStorageEnum + * @Description: 文件存储器枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 9:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum FileStorageEnum implements SkyeyeEnumClass { + + DB(1, "数据库存储", DBFileClientConfig.class, DBFileClient.class, true, true), + + LOCAL(10, "本地存储", LocalFileClientConfig.class, LocalFileClient.class, true, false), + FTP(11, "FTP存储", FtpFileClientConfig.class, FtpFileClient.class, true, false), + SFTP(12, "SFTP存储", SftpFileClientConfig.class, SftpFileClient.class, true, false), + + S3(20, "S3存储", S3FileClientConfig.class, S3FileClient.class, true, false); + + /** + * 存储器 + */ + private Integer key; + + private String value; + + /** + * 配置类 + */ + private Class configClass; + + /** + * 客户端类 + */ + private Class clientClass; + + private Boolean show; + + private Boolean isDefault; + + public static FileStorageEnum getByStorage(Integer storage) { + return ArrayUtil.firstMatch(o -> o.getKey().equals(storage), values()); + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileConfigService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileConfigService.java new file mode 100644 index 0000000..f7c0ba6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileConfigService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.framework.file.core.client.FileClient; +import com.skyeye.upload.entity.FileConfig; + +/** + * @ClassName: FileConfigService + * @Description: 文件配置服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileConfigService extends SkyeyeBusinessService { + + /** + * 获得默认的文件客户端 + * + * @return 文件客户端 + */ + FileClient getMasterFileClient(); + + FileClient getFileClient(String configId); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileContentService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileContentService.java new file mode 100644 index 0000000..02f3841 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileContentService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.upload.entity.FileContent; + +/** + * @ClassName: FileContentService + * @Description: 文件内容服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 20:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileContentService extends SkyeyeBusinessService { + + void deleteByPath(String path); + + FileContent queryByPath(String path); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileService.java new file mode 100644 index 0000000..e2e3300 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/FileService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.upload.entity.File; + +/** + * @ClassName: FileService + * @Description: 文件服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 19:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FileService extends SkyeyeBusinessService { + + File queryByPath(String path); + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/UploadService.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/UploadService.java new file mode 100644 index 0000000..7f2c901 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/UploadService.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @ClassName: UploadService + * @Description: 文件上传、下载服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UploadService { + + void uploadFileResume(InputObject inputObject, OutputObject outputObject); + + void uploadFileChunks(InputObject inputObject, OutputObject outputObject); + + void checkUploadFileChunks(InputObject inputObject, OutputObject outputObject); + + void uploadFile(InputObject inputObject, OutputObject outputObject); + + void uploadFileBase64(InputObject inputObject, OutputObject outputObject); + + void getFileContent(HttpServletRequest request, HttpServletResponse response, String configId); + + void deleteFileByPath(InputObject inputObject, OutputObject outputObject); + + void getFilePresignedUrl(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileConfigServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileConfigServiceImpl.java new file mode 100644 index 0000000..086312a --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileConfigServiceImpl.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.framework.file.core.client.FileClient; +import com.skyeye.framework.file.core.client.FileClientConfig; +import com.skyeye.framework.file.core.client.FileClientFactory; +import com.skyeye.upload.dao.FileConfigDao; +import com.skyeye.upload.entity.FileConfig; +import com.skyeye.upload.enums.FileStorageEnum; +import com.skyeye.upload.service.FileConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.validation.Validator; + +/** + * @ClassName: FileConfigServiceImpl + * @Description: 文件配置服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 17:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "文件配置", groupName = "文件配置") +public class FileConfigServiceImpl extends SkyeyeBusinessServiceImpl implements FileConfigService { + + @Autowired + private RedisCache redisCache; + + @Autowired + private FileClientFactory fileClientFactory; + + @Autowired + private Validator validator; + + private static final String FILE_CONFIG_IS_DEFAULT_CACHE_KEY = "skyeye:fileConfig:isDefault"; + + @Override + public void validatorEntity(FileConfig entity) { + super.validatorEntity(entity); + // 解析配置 + Class configClass = FileStorageEnum.getByStorage(entity.getStorage()).getConfigClass(); + if (ObjectUtil.isNull(configClass)) { + throw new CustomException("文件存储类型的配置不存在"); + } + FileClientConfig config = JSONUtil.toBean(entity.getConfig(), configClass); + entity.setConfigMation(config); + Assert.notNull(entity.getConfigMation()); + // 验证参数 + entity.getConfigMation().validate(validator); + } + + @Override + public void createPrepose(FileConfig entity) { + if (entity.getIsDefault() == IsDefaultEnum.IS_DEFAULT.getKey()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set(MybatisPlusUtil.toColumns(FileConfig::getIsDefault), IsDefaultEnum.NOT_DEFAULT.getKey()); + update(updateWrapper); + } + } + + @Override + public void updatePostpose(FileConfig entity, String userId) { + // 移除文件客户端 + fileClientFactory.removeFileClient(entity.getId()); + } + + @Override + public void writePostpose(FileConfig entity, String userId) { + if (entity.getIsDefault() == IsDefaultEnum.IS_DEFAULT.getKey()) { + jedisClientService.del(FILE_CONFIG_IS_DEFAULT_CACHE_KEY); + } + } + + @Override + public FileConfig selectById(String id) { + FileConfig fileConfig = super.selectById(id); + Class configClass = FileStorageEnum.getByStorage(fileConfig.getStorage()).getConfigClass(); + FileClientConfig config = JSONUtil.toBean(fileConfig.getConfig(), configClass); + fileConfig.setConfigMation(config); + return fileConfig; + } + + @Override + public void deletePostpose(FileConfig entity) { + if (entity.getIsDefault() == IsDefaultEnum.IS_DEFAULT.getKey()) { + jedisClientService.del(FILE_CONFIG_IS_DEFAULT_CACHE_KEY); + } + // 移除文件客户端 + fileClientFactory.removeFileClient(entity.getId()); + } + + @Override + public FileClient getMasterFileClient() { + FileConfig fileConfig = redisCache.getBean(FILE_CONFIG_IS_DEFAULT_CACHE_KEY, key -> { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(FileConfig::getIsDefault), IsDefaultEnum.IS_DEFAULT.getKey()); + FileConfig bean = getOne(wrapper, false); + Class configClass = FileStorageEnum.getByStorage(bean.getStorage()).getConfigClass(); + FileClientConfig config = JSONUtil.toBean(bean.getConfig(), configClass); + + if (bean != null) { + fileClientFactory.createOrUpdateFileClient(bean.getId(), bean.getStorage(), config); + } + return bean; + }, RedisConstants.THIRTY_DAY_SECONDS, FileClient.class); + if (fileConfig == null) { + throw new CustomException("没有设置默认文件存储"); + } + + return fileClientFactory.getFileClient(fileConfig.getId()); + } + + @Override + public FileClient getFileClient(String configId) { + FileClient fileClient = fileClientFactory.getFileClient(configId); + if (fileClient == null) { + FileConfig fileConfig = selectById(configId); + if (fileConfig == null) { + throw new CustomException("文件存储配置不存在"); + } + fileClientFactory.createOrUpdateFileClient(fileConfig.getId(), fileConfig.getStorage(), fileConfig.getConfigMation()); + fileClient = fileClientFactory.getFileClient(configId); + } + return fileClient; + } +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileContentServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileContentServiceImpl.java new file mode 100644 index 0000000..0b14551 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileContentServiceImpl.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.upload.dao.FileContentDao; +import com.skyeye.upload.entity.FileContent; +import com.skyeye.upload.service.FileContentService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: FileContentServiceImpl + * @Description: 文件内容服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 20:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "文件内容", groupName = "文件内容") +public class FileContentServiceImpl extends SkyeyeBusinessServiceImpl implements FileContentService { + + @Override + public void deleteByPath(String path) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(FileContent::getPath), path); + remove(queryWrapper); + } + + @Override + public FileContent queryByPath(String path) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FileContent::getPath), path); + FileContent fileContent = getOne(queryWrapper, false); + if (fileContent == null) { + throw new IllegalArgumentException("文件不存在"); + } + return fileContent; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..10ab9ff --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/FileServiceImpl.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.upload.dao.FileDao; +import com.skyeye.upload.entity.File; +import com.skyeye.upload.service.FileService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: FileServiceImpl + * @Description: 文件服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 19:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "文件", groupName = "文件") +public class FileServiceImpl extends SkyeyeBusinessServiceImpl implements FileService { + + @Override + public File queryByPath(String path) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(File::getPath), path); + File file = getOne(wrapper, false); + return file; + } + +} diff --git a/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/UploadServiceImpl.java b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/UploadServiceImpl.java new file mode 100644 index 0000000..56618a6 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/java/com/skyeye/upload/service/impl/UploadServiceImpl.java @@ -0,0 +1,412 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upload.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.URLUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.framework.file.core.client.FileClient; +import com.skyeye.framework.file.core.client.s3.FilePresignedUrlRespDTO; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.upload.entity.Upload; +import com.skyeye.upload.entity.UploadChunks; +import com.skyeye.upload.service.FileConfigService; +import com.skyeye.upload.service.FileService; +import com.skyeye.upload.service.UploadService; +import org.apache.commons.codec.binary.Base64; +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.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.util.*; + +/** + * @ClassName: UploadServiceImpl + * @Description: 文件上传、下载服务服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/28 21:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class UploadServiceImpl implements UploadService { + + private static final Logger LOGGER = LoggerFactory.getLogger(UploadServiceImpl.class); + + @Autowired + public JedisClientService jedisClient; + + @Autowired + private RedisCache redisCache; + + @Autowired + private FileConfigService fileConfigService; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private FileService fileService; + + /** + * 断点续传上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void uploadFileResume(InputObject inputObject, OutputObject outputObject) { + Upload upload = inputObject.getParams(Upload.class); + // 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器) + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(PutObject.getRequest().getSession().getServletContext()); + // 检查form中是否有enctype="multipart/form-data" + if (!multipartResolver.isMultipart(PutObject.getRequest())) { + return; + } + String userId = inputObject.getLogParams().get("id").toString(); + // 将request变成多部分request + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) PutObject.getRequest(); + // 获取multiRequest 中所有的文件名 + Iterator iter = multiRequest.getFileNames(); + while (iter.hasNext()) { + String fileAddress = uploadFile(multiRequest, iter, upload.getType(), userId); + upload.setFileType(fileAddress.substring(fileAddress.lastIndexOf(".") + 1).toLowerCase()); + upload.setFileSizeType("bytes"); + upload.setFileAddress(fileAddress); + upload.setFileThumbnail("-1"); + + String cacheKey = getCacheKey(upload.getMd5()); + List beans = redisCache.getList(cacheKey, key -> new ArrayList<>(), RedisConstants.ONE_DAY_SECONDS, Upload.class); + beans.add(upload); + jedisClient.set(cacheKey, JSONUtil.toJsonStr(beans)); + } + } + + private String uploadFile(MultipartHttpServletRequest multiRequest, Iterator iter, Integer type, String userId) { + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(type, userId); + MultipartFile file = multiRequest.getFile(iter.next().toString()); + if (file == null) { + throw new CustomException("file is not null."); + } + String fileName = file.getOriginalFilename(); + // 得到文件扩展名 + String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); + FileUtil.createDirs(basePath); + // 自定义的文件名称 + String newFileName = String.format(Locale.ROOT, "%s.%s", System.currentTimeMillis(), fileExtName); + String path = basePath + "/" + newFileName; + // 上传 + try { + file.transferTo(new File(path)); + } catch (IOException e) { + throw new CustomException(e); + } + return FileConstants.FileUploadPath.getVisitPath(type, userId) + newFileName; + } + + /** + * 上传文件合并块 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void uploadFileChunks(InputObject inputObject, OutputObject outputObject) { + UploadChunks uploadChunks = inputObject.getParams(UploadChunks.class); + String cacheKey = getCacheKey(uploadChunks.getMd5()); + List beans = redisCache.getList(cacheKey, key -> new ArrayList<>(), RedisConstants.ONE_DAY_SECONDS, Upload.class); + List fileList = new ArrayList<>(); + for (Upload bean : beans) { + File f = new File(tPath.replace("images", "") + bean.getFileAddress()); + fileList.add(f); + } + String userId = inputObject.getLogParams().get("id").toString(); + String fileName = uploadChunks.getName(); + String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); + String newFileName = String.format(Locale.ROOT, "%s.%s", System.currentTimeMillis(), fileExtName); + String path = tPath + FileConstants.FileUploadPath.getSavePath(uploadChunks.getType(), userId) + + CommonCharConstants.SLASH_MARK + newFileName; + FileChannel outChnnel = null; + try { + File outputFile = new File(path); + // 创建文件 + outputFile.createNewFile(); + // 输出流 + outChnnel = new FileOutputStream(outputFile).getChannel(); + FileChannel inChannel; + for (File file : fileList) { + inChannel = new FileInputStream(file).getChannel(); + inChannel.transferTo(0, inChannel.size(), outChnnel); + inChannel.close(); + // 删除分片 + file.delete(); + } + } catch (Exception e) { + throw new CustomException(e); + } finally { + FileUtil.close(outChnnel); + } + jedisClient.del(cacheKey); + uploadChunks.setFileType(fileExtName); + uploadChunks.setFileSizeType("bytes"); + newFileName = FileConstants.FileUploadPath.getVisitPath(uploadChunks.getType(), userId) + newFileName; + uploadChunks.setFileAddress(newFileName); + outputObject.setBean(uploadChunks); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private String getCacheKey(String md5) { + return String.format(Locale.ROOT, "upload:file:chunks:%s", md5); + } + + /** + * 文件分块上传检测是否上传 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void checkUploadFileChunks(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String md5 = map.get("md5").toString(); + String chunk = map.get("chunk").toString(); + String cacheKey = getCacheKey(md5); + List beans = redisCache.getList(cacheKey, key -> new ArrayList<>(), RedisConstants.ONE_DAY_SECONDS, Upload.class); + Upload bean = null; + int index = -1; + for (int i = 0; i < beans.size(); i++) { + Upload upload = beans.get(i); + if (chunk.equals(upload.getChunk())) { + bean = upload; + index = i; + break; + } + } + if (bean != null) { + String fileAddress = tPath.replace("images", "") + bean.getFileAddress(); + File checkFile = new File(fileAddress); + String chunkSize = map.get("chunkSize").toString(); + if (checkFile.exists() && checkFile.length() == Integer.parseInt(chunkSize)) { + } else { + beans.remove(index); + jedisClient.set(cacheKey, JSONUtil.toJsonStr(beans)); + outputObject.setreturnMessage("文件上传失败"); + } + } else { + outputObject.setreturnMessage("文件上传失败"); + } + } + + /** + * 上传文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void uploadFile(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器) + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(PutObject.getRequest().getSession().getServletContext()); + // 检查form中是否有enctype="multipart/form-data" + if (!multipartResolver.isMultipart(PutObject.getRequest())) { + return; + } + // 将request变成多部分request + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) PutObject.getRequest(); + // 获取multiRequest 中所有的文件名 + Iterator iter = multiRequest.getFileNames(); + int type = Integer.parseInt(map.get("type").toString()); + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(type); + Map bean = new HashMap<>(); + StringBuffer trueFileName = new StringBuffer(); + String fileName = ""; +// TODO 上传到文件存储器待测试 +// // 上传到文件存储器 +// FileClient client = fileConfigService.getMasterFileClient(); +// if (client == null) { +// throw new CustomException("客户端(master) 不能为空"); +// } + + byte[] content = null; + while (iter.hasNext()) { + MultipartFile file = multiRequest.getFile(iter.next().toString()); + if (file == null) { + break; + } + // 文件名称 + fileName = file.getOriginalFilename(); + // 得到文件扩展名 + String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1); + // 自定义的文件名称 + String newFileName = String.format(Locale.ROOT, "%s.%s", System.currentTimeMillis(), fileExtName); + String path = basePath + "/" + newFileName; +// try { +// content = IoUtil.readBytes(file.getInputStream()); +// String url = client.upload(content, path, fileExtName); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } + FileUtil.createDirs(basePath); + LOGGER.info("upload file type is: {}, path is: {}", type, path); + // 上传 + try { + file.transferTo(new File(path)); + } catch (IOException ex) { + throw new CustomException(ex); + } + newFileName = FileConstants.FileUploadPath.getVisitPath(type) + newFileName; + if (ToolUtil.isBlank(trueFileName.toString())) { + trueFileName.append(newFileName); + } else { + trueFileName.append(",").append(newFileName); + } + break; + } + bean.put("picUrl", trueFileName.toString()); + bean.put("type", type); + bean.put("fileName", fileName); + +// com.skyeye.upload.entity.File file = new com.skyeye.upload.entity.File(); +// file.setConfigId(client.getId()); +// file.setName(fileName); +// file.setPath(trueFileName.toString()); +// file.setUrl(trueFileName.toString()); +// file.setType(FileUtil.getMineType(fileName)); +// file.setSize(content.length); +// fileService.createEntity(file, StrUtil.EMPTY); + outputObject.setBean(bean); + } + + /** + * 上传文件Base64 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void uploadFileBase64(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + int type = Integer.parseInt(map.get("type").toString()); + String imgStr = map.get("images").toString(); + imgStr = imgStr.replaceAll("\\+", "%2B").replaceAll(" ", "+"); + String[] d = imgStr.split("base64,"); + // 上传数据是否合法 + if (d != null && d.length == 2) { + String dataPrix = d[0]; + String data = d[1]; + if (FileUtil.checkBase64IsImage(dataPrix)) { + try { + byte[] bytes = Base64.decodeBase64(data.getBytes()); + // 决定存储路径 + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(type); + FileUtil.createDirs(basePath); + // 自定义的文件名称 + String trueFileName = System.currentTimeMillis() + "." + FileUtil.getBase64FileTypeByPrix(dataPrix); + // 写入文件 + FileUtil.writeByteToPointPath(bytes, basePath + "/" + trueFileName); + Map bean = new HashMap<>(); + bean.put("picUrl", FileConstants.FileUploadPath.getVisitPath(type) + trueFileName); + bean.put("type", type); + outputObject.setBean(bean); + } catch (Exception ee) { + LOGGER.warn("uploadFileBase64 failed. {}", ee); + outputObject.setreturnMessage("上传失败,数据不合法"); + } + } else { + outputObject.setreturnMessage("文件类型不正确,只允许上传jpg,png,jpeg格式的图片"); + } + } else { + outputObject.setreturnMessage("上传失败,数据不合法"); + } + } + + @Override + public void getFileContent(HttpServletRequest request, HttpServletResponse response, String configId) { + // 获取请求的路径 + String path = StrUtil.subAfter(request.getRequestURI(), "/get/", false); + if (StrUtil.isEmpty(path)) { + throw new IllegalArgumentException("结尾的 path 路径必须传递"); + } + // 解码,解决中文路径的问题 https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/807/ + path = URLUtil.decode(path); + + // 读取内容 + FileClient client = fileConfigService.getFileClient(configId); + Assert.notNull(client, "客户端({}) 不能为空", configId); + try { + byte[] content = client.getContent(path); + if (content == null) { + LOGGER.warn("[getFileContent][configId({}) path({}) 文件不存在]", configId, path); + response.setStatus(HttpStatus.NOT_FOUND.value()); + return; + } + FileUtil.writeAttachment(response, path, content); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void deleteFileByPath(InputObject inputObject, OutputObject outputObject) { + String path = inputObject.getParams().get("path").toString(); + com.skyeye.upload.entity.File file = fileService.queryByPath(path); + if (file == null) { + throw new CustomException("文件不存在"); + } + // 从文件存储器中删除 + FileClient client = fileConfigService.getFileClient(file.getConfigId()); + Assert.notNull(client, "客户端({}) 不能为空", file.getConfigId()); + try { + client.delete(file.getPath()); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // 删除记录 + fileService.deleteById(file.getId()); + } + + @Override + public void getFilePresignedUrl(InputObject inputObject, OutputObject outputObject) { + String path = inputObject.getParams().get("path").toString(); + FileClient fileClient = fileConfigService.getMasterFileClient(); + try { + FilePresignedUrlRespDTO presignedObjectUrl = fileClient.getPresignedObjectUrl(path); + presignedObjectUrl.setConfigId(fileClient.getId()); + outputObject.setBean(presignedObjectUrl); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + +} diff --git a/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysDictDataMapper.xml b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysDictDataMapper.xml new file mode 100644 index 0000000..cde987f --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysDictDataMapper.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelMapper.xml b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelMapper.xml new file mode 100644 index 0000000..295e525 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelMapper.xml @@ -0,0 +1,106 @@ + + + + + + + + + + INSERT INTO sys_eve_model + (id, title, content, type, create_id, create_time, first_type_id, second_type_id, last_update_id, last_update_time, logo) + VALUES(#{id}, #{title}, #{content}, #{type}, #{userId}, #{createTime}, #{firstTypeId}, #{secondTypeId}, #{userId}, #{createTime}, #{logo}) + + + + DELETE + FROM + sys_eve_model + WHERE id = #{id} + + + + + + UPDATE sys_eve_model + + title = #{title}, + content = #{content}, + logo = #{logo}, + type = #{type}, + first_type_id = #{firstTypeId}, + second_type_id = #{secondTypeId}, + last_update_id = #{userId}, + last_update_time = #{lastUpdateTime} + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelTypeMapper.xml b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelTypeMapper.xml new file mode 100644 index 0000000..fb87db0 --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/resources/mapper/common/SysEveModelTypeMapper.xml @@ -0,0 +1,93 @@ + + + + + + + + INSERT INTO sys_eve_model_type + (id, type_name, parent_id, create_id, create_time, last_update_id, last_update_time) + VALUES + (#{id}, #{typeName}, #{parentId}, #{userId}, #{createTime}, #{userId}, #{createTime}) + + + + + + + + + + UPDATE sys_eve_model_type + SET + type_name = #{typeName}, + parent_id = #{parentId}, + last_update_id = #{userId}, + last_update_time = #{lastUpdateTime} + WHERE id = #{id} + + + + DELETE FROM + sys_eve_model_type + WHERE id = #{id} + + + + DELETE FROM + sys_eve_model_type + WHERE parent_id = #{parentId} + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-common/src/main/resources/reqmapping/mapping/common.xml b/skyeye-promote/skyeye-common/src/main/resources/reqmapping/mapping/common.xml new file mode 100644 index 0000000..309098e --- /dev/null +++ b/skyeye-promote/skyeye-common/src/main/resources/reqmapping/mapping/common.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-entity/.gitignore b/skyeye-promote/skyeye-entity/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-entity/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-entity/pom.xml b/skyeye-promote/skyeye-entity/pom.xml new file mode 100644 index 0000000..6161817 --- /dev/null +++ b/skyeye-promote/skyeye-entity/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + + skyeye-entity + skyeye-entity + + + 8 + 8 + + + + + com.skyeye + skyeye-common + 0.0.1-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/api/ApiMation.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/api/ApiMation.java new file mode 100644 index 0000000..f700972 --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/api/ApiMation.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.api; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ApiMation + * @Description: api接口信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/28 16:35 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "api_mation") +@ApiModel("api接口信息实体类") +public class ApiMation extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField(value = "request_url", fill = FieldFill.INSERT) + @ApiModelProperty(value = "请求地址", required = "required") + private String requestUrl; + + @TableField("request_body") + @ApiModelProperty(value = "请求入参") + private String requestBody; + + @TableField("response_body") + @ApiModelProperty(value = "请求出参") + private String responseBody; + + @TableField(value = "app_id", fill = FieldFill.INSERT) + @ApiModelProperty(value = "appId", required = "required") + private String appId; + +} diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/history/CodeModelHistoryQueryDo.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/history/CodeModelHistoryQueryDo.java new file mode 100644 index 0000000..6cf8a14 --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/history/CodeModelHistoryQueryDo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.codedoc.history; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: CodeModelGroupQueryDo + * @Description: 代码生成历史列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("代码生成历史列表查询条件实体类") +public class CodeModelHistoryQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "分组id", required = "required") + private String groupId; + +} diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/model/CodeModelQueryDo.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/model/CodeModelQueryDo.java new file mode 100644 index 0000000..63df07e --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/codedoc/model/CodeModelQueryDo.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.codedoc.model; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: CodeModelQueryDo + * @Description: 代码模板列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("代码模板列表查询条件实体类") +public class CodeModelQueryDo extends CommonPageInfo implements Serializable { + + + @ApiModelProperty(value = "分组id", required = "required") + private String groupId; + +} diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/mq/JobMateQueryDO.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/mq/JobMateQueryDO.java new file mode 100644 index 0000000..c0dca1e --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/mq/JobMateQueryDO.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.mq; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: JobMateQueryDO + * @Description: 任务管理查询实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:12 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("任务管理查询实体类") +public class JobMateQueryDO extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "任务大类", required = "required,num") + private Integer bigType; + + /** + * 用户id + */ + private String userId; + +} diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/xxljob/XxlJobInfo.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/xxljob/XxlJobInfo.java new file mode 100644 index 0000000..bb3bbfb --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/entity/xxljob/XxlJobInfo.java @@ -0,0 +1,56 @@ +package com.skyeye.eve.entity.xxljob; + +import lombok.Data; + +import java.util.Date; + +/** + * xxl-job info + * + * @author xuxueli 2016-1-12 18:25:49 + */ +@Data +public class XxlJobInfo { + + private int id; // 主键ID + + private int jobGroup; // 执行器主键ID + + private String jobGroupName; + + private String jobDesc; + + private Date addTime; + private Date updateTime; + + private String author; // 负责人 + private String alarmEmail; // 报警邮件 + + private String scheduleType; // 调度类型 + private String scheduleConf; // 调度配置,值含义取决于调度类型 + private String misfireStrategy; // 调度过期策略 + + private String executorRouteStrategy; // 执行器路由策略 + private String executorHandler; // 执行器,任务Handler名称 + private String executorParam; // 执行器,任务参数 + private String executorBlockStrategy; // 阻塞处理策略 + private int executorTimeout; // 任务执行超时时间,单位秒 + private int executorFailRetryCount; // 失败重试次数 + + private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum + private String glueSource; // GLUE源代码 + private String glueRemark; // GLUE备注 + private Date glueUpdatetime; // GLUE更新时间 + + private String childJobId; // 子任务ID,多个逗号分隔 + + private int triggerStatus; // 调度状态:0-停止,1-运行 + private long triggerLastTime; // 上次调度时间 + private long triggerNextTime; // 下次调度时间 + + /** + * 日程id,工作计划id等 + */ + private String objectId; + +} diff --git a/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/rest/xxljob/XxlJobService.java b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/rest/xxljob/XxlJobService.java new file mode 100644 index 0000000..ef9b174 --- /dev/null +++ b/skyeye-promote/skyeye-entity/src/main/java/com/skyeye/eve/rest/xxljob/XxlJobService.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.rest.xxljob; + +import com.skyeye.common.client.ClientConfiguration; +import com.skyeye.eve.entity.xxljob.XxlJobInfo; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: XxlJobService + * @Description: xxl-job任务服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/6 21:54 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.xxl-job}", configuration = ClientConfiguration.class) +public interface XxlJobService { + + /** + * 根据执行器的AppName获取执行器ID + * + * @param appname 执行器AppName + */ + @PostMapping("/xxl-job-admin/jobgroup/getGroupId") + String getGroupId(@RequestParam("appname") String appname); + + /** + * 启动定时任务 + * + * @param xxlJobInfo 任务信息 + */ + @PostMapping("/xxl-job-admin/jobinfo/addAndStart") + String addAndStart(XxlJobInfo xxlJobInfo); + + /** + * 删除定时任务 + * + * @param objectId 日程id,工作计划id等 + */ + @PostMapping("/xxl-job-admin/jobinfo/removeJob") + String removeJob(@RequestParam("objectId") String objectId); + +} diff --git a/skyeye-promote/skyeye-gateway/.gitignore b/skyeye-promote/skyeye-gateway/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-gateway/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-gateway/.project b/skyeye-promote/skyeye-gateway/.project new file mode 100644 index 0000000..43ef4cc --- /dev/null +++ b/skyeye-promote/skyeye-gateway/.project @@ -0,0 +1,23 @@ + + + skyeye-gateway + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-gateway/pom.xml b/skyeye-promote/skyeye-gateway/pom.xml new file mode 100644 index 0000000..df20179 --- /dev/null +++ b/skyeye-promote/skyeye-gateway/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + com.skyeye + skyeye-promote + 0.0.1-SNAPSHOT + + + skyeye-gateway + skyeye-gateway + http://maven.apache.org + + + UTF-8 + + + + + + com.skyeye + skyeye-quartz + 0.0.1-SNAPSHOT + + + + diff --git a/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/controller/MainPageController.java b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/controller/MainPageController.java new file mode 100644 index 0000000..54079b3 --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/controller/MainPageController.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.MainPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MainPageController { + + @Autowired + private MainPageService mainPageService; + + /** + * 获取本月考勤天数,我的文件数,我的论坛帖数 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/MainPageController/queryFourNumListByUserId") + public void queryFourNumListByUserId(InputObject inputObject, OutputObject outputObject) { + mainPageService.queryFourNumListByUserId(inputObject, outputObject); + } + + /** + * 获取前八条热门论坛帖 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/MainPageController/queryHotForumList") + public void queryHotForumList(InputObject inputObject, OutputObject outputObject) { + mainPageService.queryHotForumList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/dao/MainPageDao.java b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/dao/MainPageDao.java new file mode 100644 index 0000000..f3a7cdd --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/dao/MainPageDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface MainPageDao { + + String queryCheckOnWorkNumByUserId(@Param("userId") String userId); + + String queryDiskCloudFileNumByUserId(@Param("userId") String userId); + + String queryForumNumByUserId(@Param("userId") String userId); + + List> queryHotForumList(Map map); + +} diff --git a/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/MainPageService.java b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/MainPageService.java new file mode 100644 index 0000000..7221242 --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/MainPageService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface MainPageService { + + void queryFourNumListByUserId(InputObject inputObject, OutputObject outputObject); + + void queryHotForumList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/impl/MainPageServiceImpl.java b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/impl/MainPageServiceImpl.java new file mode 100644 index 0000000..af85129 --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/java/com/skyeye/eve/service/impl/MainPageServiceImpl.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.skyeye.common.constans.ForumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.MainPageDao; +import com.skyeye.eve.service.MainPageService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class MainPageServiceImpl implements MainPageService { + + @Autowired + private MainPageDao mainPageDao; + + @Autowired + public JedisClientService jedisClient; + + /** + * 获取本月考勤天数,我的文件数,我的论坛帖数 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFourNumListByUserId(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + // 1.获取本月考勤天数 + String checkOnWorkNum = mainPageDao.queryCheckOnWorkNumByUserId(userId); + // 2.获取我的文件数 + String diskCloudFileNum = mainPageDao.queryDiskCloudFileNumByUserId(userId); + // 3.获取我的论坛帖数 + String forumNum = mainPageDao.queryForumNumByUserId(userId); + Map map = new HashMap<>(); + map.put("checkOnWorkNum", checkOnWorkNum); + map.put("diskCloudFileNum", diskCloudFileNum); + map.put("forumNum", forumNum); + outputObject.setBean(map); + } + + /** + * 获取前八条热门论坛帖 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryHotForumList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("userId", inputObject.getLogParams().get("id")); + List> beans = mainPageDao.queryHotForumList(map); + for (Map m : beans) { + String createTime = ToolUtil.timeFormat(m.get("createTime").toString()); + m.put("createTime", createTime); + String key = ForumConstants.forumBrowseNumsByForumId(m.get("id").toString()); + if (ToolUtil.isBlank(jedisClient.get(key))) { + // 浏览量 + m.put("browseNum", 0); + } else { + String browseNum = jedisClient.get(key); + m.put("browseNum", browseNum); + } + } + //按浏览量和评论数给集合排序 + beans.sort(new Comparator>() { + @Override + public int compare(Map m1, Map m2) { + Integer m1num = Integer.parseInt(m1.get("browseNum").toString()) + Integer.parseInt(m1.get("commentNum").toString()); + Integer m2num = Integer.parseInt(m2.get("browseNum").toString()) + Integer.parseInt(m2.get("commentNum").toString()); + int flag = m1num.compareTo(m2num); + return -flag; // 不取反,则按正序排列 + } + }); + int count = beans.size(); + int pageMaxSize = 6; + if (count < pageMaxSize) { + pageMaxSize = count; + } + outputObject.setBeans(beans.subList(0, pageMaxSize)); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-promote/skyeye-gateway/src/main/resources/mapper/gateway/MainPageMapper.xml b/skyeye-promote/skyeye-gateway/src/main/resources/mapper/gateway/MainPageMapper.xml new file mode 100644 index 0000000..bb77b2b --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/resources/mapper/gateway/MainPageMapper.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-gateway/src/main/resources/reqmapping/mapping/gateway.xml b/skyeye-promote/skyeye-gateway/src/main/resources/reqmapping/mapping/gateway.xml new file mode 100644 index 0000000..940530f --- /dev/null +++ b/skyeye-promote/skyeye-gateway/src/main/resources/reqmapping/mapping/gateway.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-mq/.gitignore b/skyeye-promote/skyeye-mq/.gitignore new file mode 100644 index 0000000..1dd3331 --- /dev/null +++ b/skyeye-promote/skyeye-mq/.gitignore @@ -0,0 +1,2 @@ +/target/ +/target/ diff --git a/skyeye-promote/skyeye-mq/.project b/skyeye-promote/skyeye-mq/.project new file mode 100644 index 0000000..56f9a01 --- /dev/null +++ b/skyeye-promote/skyeye-mq/.project @@ -0,0 +1,23 @@ + + + skyeye-mq + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-mq/pom.xml b/skyeye-promote/skyeye-mq/pom.xml new file mode 100644 index 0000000..cda67ce --- /dev/null +++ b/skyeye-promote/skyeye-mq/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + + skyeye-mq + + skyeye-mq + http://www.example.com + + + + + + com.skyeye + skyeye-userauth + 0.0.1-SNAPSHOT + + + + + diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/controller/JobMateMationController.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/controller/JobMateMationController.java new file mode 100644 index 0000000..a624b17 --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/controller/JobMateMationController.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.mq.JobMateQueryDO; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.service.JobMateMationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "任务管理", tags = "任务管理", modelName = "任务模块") +public class JobMateMationController { + + @Autowired + private JobMateMationService jobMateMationService; + + /** + * 根据大类获取任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "jobmatemation001", value = "根据大类获取任务信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = JobMateQueryDO.class) + @RequestMapping("/post/JobMateMationController/queryJobMateMationByBigTypeList") + public void queryJobMateMationByBigTypeList(InputObject inputObject, OutputObject outputObject) { + jobMateMationService.queryJobMateMationByBigTypeList(inputObject, outputObject); + } + + /** + * 其他模块同步生产消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sendMQProducer", value = "其他模块同步生产消息", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = JobMateMation.class) + @RequestMapping("/post/JobMateMationController/sendMQProducer") + public void sendMQProducer(InputObject inputObject, OutputObject outputObject) { + jobMateMationService.sendMQProducer(inputObject, outputObject); + } + + /** + * 修改任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "comMQJobMation", value = "修改任务信息", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = JobMateUpdateMation.class) + @RequestMapping("/post/JobMateMationController/comMQJobMation") + public void comMQJobMation(InputObject inputObject, OutputObject outputObject) { + jobMateMationService.comMQJobMation(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/dao/JobMateMationDao.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/dao/JobMateMationDao.java new file mode 100644 index 0000000..04b8bef --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/dao/JobMateMationDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.eve.entity.mq.JobMateQueryDO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface JobMateMationDao { + + List> queryJobMateMationByBigTypeList(JobMateQueryDO jobMateQuery); + + int insertJobMation(Map parentJob); + + Map queryJobMationByJobId(@Param("jobId") String jobId); + + int editJobMationByJobId(@Param("jobId") String jobId, @Param("status") String status, + @Param("responseBody") String responseBody, @Param("complateTime") String complateTime); + + List> queryNoComChildJobMationByJobId(@Param("jobId") String jobId); + + List> queryFailChildJobMationByJobId(@Param("jobId") String jobId); + + int editJobRequestBodyMation(Map parentJob); + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/NoticeSendServiceImpl.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/NoticeSendServiceImpl.java new file mode 100644 index 0000000..4551f32 --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/NoticeSendServiceImpl.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.mq.job.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.service.JobMateMationService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: NoticeSendServiceImpl + * @Description: 消息通知 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.notice-send-service}", + consumerGroup = "${topic.notice-send-service}", + selectorExpression = "${spring.profiles.active}") +public class NoticeSendServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(NoticeSendServiceImpl.class); + + @Autowired + private JobMateMationService jobMateMationService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + String email = map.get("email").toString(); + List> beans = JSONUtil.toList(email, null); + for (int i = 0; i < beans.size(); i++) { + Map bean = beans.get(i); + if (CollectionUtil.isNotEmpty(bean)) { + // 邮件账号不为空,发送邮件 + new MailUtil().send(bean.get("email").toString(), map.get("title").toString(), map.get("content").toString()); + } + } + // 任务完成 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("notification failed, reason is {}.", e); + // 任务失败 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/OrdinaryMailDeliveryServiceImpl.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/OrdinaryMailDeliveryServiceImpl.java new file mode 100644 index 0000000..cfa0d0a --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/OrdinaryMailDeliveryServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.util.MailUtil; +import com.skyeye.service.JobMateMationService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author 卫志强 + * @ClassName: OrdinaryMailDeliveryServiceImpl + * @Description: 普通邮件发送任务 + * @date 2020年8月22日 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.ordinary-mail-delivery-service}", + consumerGroup = "${topic.ordinary-mail-delivery-service}", + selectorExpression = "${spring.profiles.active}") +public class OrdinaryMailDeliveryServiceImpl implements RocketMQListener { + + private static Logger LOGGER = LoggerFactory.getLogger(OrdinaryMailDeliveryServiceImpl.class); + + @Autowired + private JobMateMationService jobMateMationService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + String email = map.get("email").toString(); + String content = map.get("content").toString(); + LOGGER.info("resever is {}, content is {}", email, content); + new MailUtil().send(email, map.get("title").toString(), content); + // 任务完成 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("Normal mail sending task failed, reason is {}.", e); + // 任务失败 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/SmsSendConsumer.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/SmsSendConsumer.java new file mode 100644 index 0000000..b8de715 --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/mq/job/impl/SmsSendConsumer.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.service.JobMateMationService; +import com.skyeye.sms.entity.SmsSendMessage; +import com.skyeye.sms.service.SmsSendService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @ClassName: SmsSendConsumer + * @Description: 短信发送消费者 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 21:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.sms-send-service}", + consumerGroup = "${topic.sms-send-service}", + selectorExpression = "${spring.profiles.active}") +public class SmsSendConsumer implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(SmsSendConsumer.class); + + @Autowired + private JobMateMationService jobMateMationService; + + @Autowired + private SmsSendService smsSendService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + String content = map.get("content").toString(); + try { + // 任务开始 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, ""); + // 发送短信 + SmsSendMessage message = JSONUtil.toBean(content, SmsSendMessage.class); + smsSendService.doSendSms(message); + // 任务完成 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, ""); + } catch (Exception e) { + LOGGER.warn("notification failed, reason is {}.", e); + // 任务失败 + jobMateMationService.comMQJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, ""); + } + } + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/JobMateMationService.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/JobMateMationService.java new file mode 100644 index 0000000..4e60491 --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/JobMateMationService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface JobMateMationService { + + void queryJobMateMationByBigTypeList(InputObject inputObject, OutputObject outputObject); + + void sendMQProducer(String jsonStr, String userId); + + void comMQJobMation(InputObject inputObject, OutputObject outputObject); + + void comMQJobMation(String jobId, String status, String responseBody); + + void sendMQProducer(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/impl/JobMateMationServiceImpl.java b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/impl/JobMateMationServiceImpl.java new file mode 100644 index 0000000..7668b2e --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/java/com/skyeye/service/impl/JobMateMationServiceImpl.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.constans.SocketConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.dao.JobMateMationDao; +import com.skyeye.eve.entity.mq.JobMateQueryDO; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.exception.CustomException; +import com.skyeye.service.JobMateMationService; +import com.skyeye.websocket.TalkWebSocket; +import org.apache.rocketmq.client.producer.SendResult; +import org.apache.rocketmq.spring.core.RocketMQTemplate; +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.messaging.support.MessageBuilder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: JobMateMationServiceImpl + * @Description: 任务管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class JobMateMationServiceImpl implements JobMateMationService { + + private static final Logger LOGGER = LoggerFactory.getLogger(JobMateMationServiceImpl.class); + + @Autowired + private JobMateMationDao jobMateMationDao; + + @Autowired + private RocketMQTemplate rocketMQTemplate; + + @Autowired + private TalkWebSocket talkWebSocket; + + @Value("${spring.profiles.active}") + private String tag; + + /** + * 根据大类获取任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryJobMateMationByBigTypeList(InputObject inputObject, OutputObject outputObject) { + JobMateQueryDO jobMateQuery = inputObject.getParams(JobMateQueryDO.class); + jobMateQuery.setUserId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(jobMateQuery.getPage(), jobMateQuery.getLimit()); + List> beans = jobMateMationDao.queryJobMateMationByBigTypeList(jobMateQuery); + beans.forEach(bean -> bean.put("jobTypeName", MqConstants.JobMateMationJobType.getTypeNameByJobType(bean.get("jobType").toString()))); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 其他模块同步生产消息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void sendMQProducer(InputObject inputObject, OutputObject outputObject) { + JobMateMation jobMateMation = inputObject.getParams(JobMateMation.class); + this.sendMQProducer(jobMateMation.getJsonStr(), jobMateMation.getUserId()); + } + + /** + * 开始生产消息 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void sendMQProducer(String jsonStr, String userId) { + Map jobBody = JSONUtil.toBean(jsonStr, null); + String topic; + SendResult sendResult; + if (!MapUtil.checkKeyIsNull(jobBody, "whetherCreatTask") && !Boolean.valueOf(jobBody.get("whetherCreatTask").toString())) { + // jobBody中是否包含whetherCreatTask参数,如果包含并且为false则不创建任务 + topic = jobBody.get("topic").toString(); + // 同步发送 + sendResult = rocketMQTemplate.syncSend(topic + ":" + tag, + MessageBuilder.withPayload(jsonStr).build()); + } else { + // 父任务 + Map parentJob; + try { + parentJob = resetParentJobMation(jsonStr, userId); + } catch (UnknownHostException e) { + LOGGER.warn("sendMQProducer failed, reason is {}.", e); + throw new CustomException(e); + } + jobMateMationDao.insertJobMation(parentJob); + LOGGER.info("create job mation is {}", JSONUtil.toJsonStr(parentJob)); + // 重置请求体中的任务id + jobBody.put("jobMateId", parentJob.get("jobId")); + parentJob.put("requestBody", JSONUtil.toJsonStr(jobBody)); + jobMateMationDao.editJobRequestBodyMation(parentJob); + String jobType = parentJob.get("jobType").toString(); + // 发起消息 + topic = MqConstants.JobMateMationJobType.getTopicByJobType(jobType); + // 同步发送 + sendResult = rocketMQTemplate.syncSend(topic + ":" + tag, + MessageBuilder.withPayload(parentJob.get("requestBody").toString()).build()); + } + LOGGER.info("mq send topic is [{}], send result: [{}]", topic, sendResult); + } + + /** + * 构造父任务对象 + * + * @param jsonStr + * @param userId + * @return + * @throws UnknownHostException + */ + public Map resetParentJobMation(String jsonStr, String userId) throws UnknownHostException { + Map map = JSONUtil.toBean(jsonStr, null); + String jobType = map.get("type").toString(); + Map job = new HashMap<>(); + job.put("title", map.containsKey("title") ? map.get("title") : MqConstants.JobMateMationJobType.getTypeNameByJobType(jobType)); + job.put("jobType", jobType); + job.put("bigType", MqConstants.JobMateMationJobType.getBigTypeByJobType(jobType)); + // 父任务 + job.put("type", 1); + job.put("parentId", 0); + job.put("requestBody", jsonStr); + // 父任务默认处理中,子任务默认等待处理 + job.put("status", MqConstants.JOB_TYPE_IS_PROCESSING); + job.put("createId", userId); + InetAddress address = InetAddress.getLocalHost(); + job.put("createIp", address.getHostAddress()); + job.put("createTime", DateUtil.getTimeAndToString()); + return job; + } + + /** + * 修改任务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void comMQJobMation(InputObject inputObject, OutputObject outputObject) { + JobMateUpdateMation jobMateUpdateMation = inputObject.getParams(JobMateUpdateMation.class); + LOGGER.info("update job [{}], status is {}", jobMateUpdateMation.getJobId(), jobMateUpdateMation.getStatus()); + this.comMQJobMation(jobMateUpdateMation.getJobId(), jobMateUpdateMation.getStatus(), jobMateUpdateMation.getResponseBody()); + } + + /** + * 任务状态修改 + * + * @param jobId + * @param status + * @param responseBody + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void comMQJobMation(String jobId, String status, String responseBody) { + Map jobMation = jobMateMationDao.queryJobMationByJobId(jobId); + // 类型 1.父任务2.子任务 + String type = jobMation.get("type").toString(); + jobMateMationDao.editJobMationByJobId(jobId, status, responseBody, DateUtil.getTimeAndToString()); + if (MqConstants.JOB_TYPE_IS_SUCCESS.equals(status) || MqConstants.JOB_TYPE_IS_FAIL.equals(status)) { + // 任务修改为成功或者失败时执行 + if ("2".equals(type)) { + // 子任务类型 + String parentJobId = jobMation.get("jobId").toString(); + // 获取未完成的子任务 + List> noComChildJob = jobMateMationDao.queryNoComChildJobMationByJobId(parentJobId); + if (noComChildJob == null || noComChildJob.isEmpty()) { + // 如果已经没有未完成的子任务,获取失败的子任务 + List> failChildJob = jobMateMationDao.queryFailChildJobMationByJobId(parentJobId); + if (failChildJob == null || failChildJob.isEmpty()) { + // 如果没有失败的子任务,则父任务执行成功 + jobMateMationDao.editJobMationByJobId(parentJobId, MqConstants.JOB_TYPE_IS_SUCCESS, responseBody, DateUtil.getTimeAndToString()); + sendJobResultMseeage(parentJobId, MqConstants.JOB_TYPE_IS_SUCCESS); + } else { + // 父任务部分成功 + jobMateMationDao.editJobMationByJobId(parentJobId, MqConstants.JOB_TYPE_IS_PARTIAL_SUCCESS, responseBody, DateUtil.getTimeAndToString()); + sendJobResultMseeage(parentJobId, MqConstants.JOB_TYPE_IS_PARTIAL_SUCCESS); + } + } + } else { + // 父任务类型 + sendJobResultMseeage(jobId, status); + } + } + } + + /** + * 推送任务消息给前台 + * + * @param jobId + * @param status + */ + private void sendJobResultMseeage(String jobId, String status) { + Map jobMation = jobMateMationDao.queryJobMationByJobId(jobId); + String userId = jobMation.get("createId").toString(); + LOGGER.info("job is success, jobId is {}", jobId); + if (MqConstants.JOB_TYPE_IS_SUCCESS.equals(status) || MqConstants.JOB_TYPE_IS_FAIL.equals(status) + || MqConstants.JOB_TYPE_IS_PARTIAL_SUCCESS.equals(status)) { + // 成功/失败/部分成功 + String jobType = jobMation.get("jobType").toString(); + // 所属大类 + int bigType = MqConstants.JobMateMationJobType.getBigTypeByJobType(jobType); + boolean sendMsgToPage = MqConstants.JobMateMationJobType.getSendMsgToPageByJobType(jobType); + if (sendMsgToPage) { + talkWebSocket.sendMessageTo(JSONUtil.toJsonStr(getMsg(status, bigType, jobType)), userId); + } + } + } + + private Map getMsg(String status, int bigType, String jobType) { + Map result = new HashMap<>(); + result.put("messageType", SocketConstants.MessageType.Fifth.getType()); + result.put("bigType", bigType); + result.put("jobType", jobType); + result.put("state", status); + return result; + } + +} diff --git a/skyeye-promote/skyeye-mq/src/main/resources/mapper/mqmapper/JobMateMationMapper.xml b/skyeye-promote/skyeye-mq/src/main/resources/mapper/mqmapper/JobMateMationMapper.xml new file mode 100644 index 0000000..62c6037 --- /dev/null +++ b/skyeye-promote/skyeye-mq/src/main/resources/mapper/mqmapper/JobMateMationMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + INSERT INTO job_mate_mation + (title, job_type, big_type, type, request_body, `status`, parent_id, create_id, create_ip, create_time) + VALUES + (#{title}, #{jobType}, #{bigType}, #{type}, #{requestBody}, #{status}, #{parentId}, #{createId}, #{createIp}, #{createTime}) + + + + + + UPDATE job_mate_mation + + `status` = #{status}, + response_body = #{responseBody}, + complate_time = #{complateTime}, + + WHERE job_id = #{jobId} + + + + + + + + UPDATE job_mate_mation + + request_body = #{requestBody}, + + WHERE job_id = #{jobId} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/.gitignore b/skyeye-promote/skyeye-organization/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-organization/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-organization/pom.xml b/skyeye-promote/skyeye-organization/pom.xml new file mode 100644 index 0000000..203d9b8 --- /dev/null +++ b/skyeye-promote/skyeye-organization/pom.xml @@ -0,0 +1,29 @@ + + + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + skyeye-organization + + + UTF-8 + + + + + + + com.skyeye + skyeye-entity + 0.0.1-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyDepartmentController.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyDepartmentController.java new file mode 100644 index 0000000..87996e0 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyDepartmentController.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.Department; +import com.skyeye.organization.service.CompanyDepartmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CompanyDepartmentController + * @Description: 部门管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/4/8 19:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "部门管理", tags = "部门管理", modelName = "组织模块") +public class CompanyDepartmentController { + + @Autowired + private CompanyDepartmentService companyDepartmentService; + + /** + * 获取部门信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companydepartment001", value = "获取部门信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CompanyDepartmentController/queryCompanyDepartmentList") + public void queryCompanyDepartmentList(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑部门信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDepartmentMation", value = "添加/编辑公司部门信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Department.class) + @RequestMapping("/post/CompanyDepartmentController/writeDepartmentMation") + public void writeDepartmentMation(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除部门信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDepartmentMationById", value = "删除部门信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyDepartmentController/deleteCompanyDepartmentMationById") + public void deleteCompanyDepartmentMationById(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询部门详情信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepartmentMationById", value = "根据id查询部门详情信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyDepartmentController/queryDepartmentMationById") + public void queryDepartmentMationById(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.selectById(inputObject, outputObject); + } + + /** + * 根据公司id获取部门信息列表展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companydepartment006", value = "根据公司id获取部门信息列表展示为树", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "companyId", name = "companyId", value = "公司id", required = "required")}) + @RequestMapping("/post/CompanyDepartmentController/queryCompanyDepartmentListTreeByCompanyId") + public void queryCompanyDepartmentListTreeByCompanyId(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.queryCompanyDepartmentListTreeByCompanyId(inputObject, outputObject); + } + + /** + * 根据公司id获取部门列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companydepartment007", value = "根据公司id获取部门列表展示为下拉选择框", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "companyId", name = "companyId", value = "公司id", required = "required")}) + @RequestMapping("/post/CompanyDepartmentController/queryCompanyDepartmentListByCompanyIdToSelect") + public void queryCompanyDepartmentListByCompanyIdToSelect(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.queryCompanyDepartmentListByCompanyIdToSelect(inputObject, outputObject); + } + + /** + * 获取部门列表展示为表格供其他选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companydepartment008", value = "获取部门列表展示为表格供其他选择", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CompanyDepartmentController/queryCompanyDepartmentListToChoose") + public void queryCompanyDepartmentListToChoose(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.queryCompanyDepartmentListToChoose(inputObject, outputObject); + } + + /** + * 根据部门ids获取部门信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepartmentListByIds", value = "根据部门ids获取部门信息列表", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "部门ids,逗号隔开", required = "required")}) + @RequestMapping("/post/CompanyDepartmentController/queryDepartmentListByIds") + public void queryDepartmentListByIds(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.selectByIds(inputObject, outputObject); + } + + /** + * 获取当前登录用户所属企业的所有部门信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDepartmentListByCurrentUserBelong", value = "获取当前登录用户所属企业的所有部门信息", method = "GET", allUse = "2") + @RequestMapping("/post/CompanyDepartmentController/queryDepartmentListByCurrentUserBelong") + public void queryDepartmentListByCurrentUserBelong(InputObject inputObject, OutputObject outputObject) { + companyDepartmentService.queryDepartmentListByCurrentUserBelong(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobController.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobController.java new file mode 100644 index 0000000..15c9ad9 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobController.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.CompanyJob; +import com.skyeye.organization.service.CompanyJobService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "职位管理", tags = "职位管理", modelName = "组织模块") +public class CompanyJobController { + + @Autowired + private CompanyJobService companyJobService; + + /** + * 获取职位信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjob001", value = "获取职位信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TableSelectInfo.class) + @RequestMapping("/post/CompanyJobController/queryCompanyJobList") + public void queryCompanyJobList(InputObject inputObject, OutputObject outputObject) { + companyJobService.queryList(inputObject, outputObject); + } + + /** + * 添加/编辑职位信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCompanyJobMation", value = "添加/编辑职位信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CompanyJob.class) + @RequestMapping("/post/CompanyJobController/writeCompanyJobMation") + public void writeCompanyJobMation(InputObject inputObject, OutputObject outputObject) { + companyJobService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除职位信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCompanyJobMationById", value = "删除职位信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyJobController/deleteCompanyJobMationById") + public void deleteCompanyJobMationById(InputObject inputObject, OutputObject outputObject) { + companyJobService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取职位信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjob004", value = "根据id获取职位信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyJobController/queryCompanyJobMationToEditById") + public void queryCompanyJobMationToEditById(InputObject inputObject, OutputObject outputObject) { + companyJobService.selectById(inputObject, outputObject); + } + + /** + * 根据部门id获取该部门所有的职位信息展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjob006", value = "根据部门id获取该部门所有的职位信息展示为树", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "departmentId", name = "departmentId", value = "部门id", required = "required")}) + @RequestMapping("/post/CompanyJobController/queryCompanyJobListTreeByDepartmentId") + public void queryCompanyJobListTreeByDepartmentId(InputObject inputObject, OutputObject outputObject) { + companyJobService.queryCompanyJobListTreeByDepartmentId(inputObject, outputObject); + } + + /** + * 根据部门id获取职位列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjob007", value = "根据部门id获取职位列表展示为下拉选择框", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "departmentId", name = "departmentId", value = "部门id", required = "required")}) + @RequestMapping("/post/CompanyJobController/queryCompanyJobListByToSelect") + public void queryCompanyJobListByToSelect(InputObject inputObject, OutputObject outputObject) { + companyJobService.queryCompanyJobListByToSelect(inputObject, outputObject); + } + + /** + * 根据部门id获取职位同级列表且不包含当前id的值展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjob008", value = "根据部门id获取职位同级列表且不包含当前id的值展示为下拉选择框", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "departmentId", name = "departmentId", value = "部门id", required = "required"), + @ApiImplicitParam(id = "id", name = "id", value = "不包含的职位id"), + @ApiImplicitParam(id = "pId", name = "pId", value = "父职位id", required = "required")}) + @RequestMapping("/post/CompanyJobController/queryCompanyJobSimpleListByToSelect") + public void queryCompanyJobSimpleListByToSelect(InputObject inputObject, OutputObject outputObject) { + companyJobService.queryCompanyJobSimpleListByToSelect(inputObject, outputObject); + } + + /** + * 根据岗位ids获取岗位信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryJobListByIds", value = "根据岗位ids获取岗位信息列表", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "岗位ids,逗号隔开", required = "required")}) + @RequestMapping("/post/CompanyJobController/queryJobListByIds") + public void queryJobListByIds(InputObject inputObject, OutputObject outputObject) { + companyJobService.selectByIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobScoreController.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobScoreController.java new file mode 100644 index 0000000..e879ec6 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyJobScoreController.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.JobScore; +import com.skyeye.organization.entity.JobScoreQueryDo; +import com.skyeye.organization.service.CompanyJobScoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CompanyJobScoreController + * @Description: 职位定级管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 22:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "职位定级管理", tags = "职位定级管理", modelName = "组织模块") +public class CompanyJobScoreController { + + @Autowired + private CompanyJobScoreService companyJobScoreService; + + /** + * 获取职位定级信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjobscore001", value = "获取职位定级信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = JobScoreQueryDo.class) + @RequestMapping("/post/CompanyJobScoreController/queryCompanyJobScoreList") + public void queryCompanyJobScoreList(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑职位定级信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCompanyJobScoreMation", value = "获取职位定级信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = JobScore.class) + @RequestMapping("/post/CompanyJobScoreController/writeCompanyJobScoreMation") + public void writeCompanyJobScoreMation(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id获取职位定级信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjobscore003", value = "根据id获取职位定级信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyJobScoreController/queryCompanyJobScoreMationById") + public void queryCompanyJobScoreMationById(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.selectById(inputObject, outputObject); + } + + /** + * 删除职位定级信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCompanyJobScoreMationById", value = "删除职位定级信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyJobScoreController/deleteCompanyJobScoreMationById") + public void deleteCompanyJobScoreMationById(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.deleteById(inputObject, outputObject); + } + + /** + * 获取已经启用的职位定级信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companyjobscore008", value = "获取已经启用的职位定级信息列表", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "jobId", name = "jobId", value = "职位id", required = "required")}) + @RequestMapping("/post/CompanyJobScoreController/queryEnableCompanyJobScoreList") + public void queryEnableCompanyJobScoreList(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.queryEnableCompanyJobScoreList(inputObject, outputObject); + } + + /** + * 根据职位定级ids批量获取信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCompanyJobScoreListByIds", value = "根据职位定级ids批量获取信息列表", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "职位定级ids,逗号隔开", required = "required")}) + @RequestMapping("/post/CompanyJobScoreController/queryCompanyJobScoreListByIds") + public void queryCompanyJobScoreListByIds(InputObject inputObject, OutputObject outputObject) { + companyJobScoreService.selectByIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyMationController.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyMationController.java new file mode 100644 index 0000000..e090a07 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/controller/CompanyMationController.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.Company; +import com.skyeye.organization.service.CompanyMationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CompanyMationController + * @Description: 企业管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/18 10:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "企业管理", tags = "企业管理", modelName = "组织模块") +public class CompanyMationController { + + @Autowired + private CompanyMationService companyMationService; + + /** + * 获取公司信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companymation001", value = "获取公司信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TableSelectInfo.class) + @RequestMapping("/post/CompanyMationController/queryCompanyMationList") + public void queryCompanyMationList(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryList(inputObject, outputObject); + } + + /** + * 添加/编辑公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCompanyMation", value = "添加/编辑公司信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Company.class) + @RequestMapping("/post/CompanyMationController/writeCompanyMation") + public void writeCompanyMation(InputObject inputObject, OutputObject outputObject) { + companyMationService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCompanyMationById", value = "删除公司信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyMationController/deleteCompanyMationById") + public void deleteCompanyMationById(InputObject inputObject, OutputObject outputObject) { + companyMationService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCompanyMationById", value = "根据id查询公司信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CompanyMationController/queryCompanyMationById") + public void queryCompanyMationById(InputObject inputObject, OutputObject outputObject) { + companyMationService.selectById(inputObject, outputObject); + } + + /** + * 获取总公司信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companymation006", value = "获取总公司信息列表", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "notId", name = "notId", value = "不包含的企业id")}) + @RequestMapping("/post/CompanyMationController/queryOverAllCompanyMationList") + public void queryOverAllCompanyMationList(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryOverAllCompanyMationList(inputObject, outputObject); + } + + /** + * 获取公司信息列表展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCompanyMationListTree", value = "获取公司信息列表展示为树", method = "POST", allUse = "2") + @RequestMapping("/post/CompanyMationController/queryCompanyMationListTree") + public void queryCompanyMationListTree(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryCompanyMationListTree(inputObject, outputObject); + } + + /** + * 获取公司列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companymation008", value = "获取公司列表展示为下拉选择框", method = "GET", allUse = "2") + @RequestMapping("/post/CompanyMationController/queryCompanyListToSelect") + public void queryCompanyListToSelect(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryCompanyListToSelect(inputObject, outputObject); + } + + /** + * 获取企业组织机构图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companymation009", value = "获取公司列表展示为下拉选择框", method = "GET", allUse = "1") + @RequestMapping("/post/CompanyMationController/queryCompanyOrganization") + public void queryCompanyOrganization(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryCompanyOrganization(inputObject, outputObject); + } + + /** + * 获取公司信息列表展示为表格供其他需要选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "companymation010", value = "获取公司信息列表展示为表格供其他需要选择", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CompanyMationController/queryCompanyMationListToChoose") + public void queryCompanyMationListToChoose(InputObject inputObject, OutputObject outputObject) { + companyMationService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id批量查询公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCompanyListByIds", value = "根据id批量查询公司信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个用逗号隔开", required = "required")}) + @RequestMapping("/post/CompanyMationController/queryCompanyListByIds") + public void queryCompanyListByIds(InputObject inputObject, OutputObject outputObject) { + companyMationService.selectByIds(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyDepartmentDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyDepartmentDao.java new file mode 100644 index 0000000..66a14d9 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyDepartmentDao.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.Department; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyDepartmentDao + * @Description: 企业部门信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/30 19:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CompanyDepartmentDao extends SkyeyeBaseMapper { + + List> queryCompanyDepartmentList(CommonPageInfo commonPageInfo); + + Map queryCompanyDepartmentUserMationById(@Param("id") String id); + + List> queryCompanyDepartmentListTreeByCompanyId(Map map); + + Map queryCompanyJobNumMationById(@Param("id") String id); + + List> queryCompanyDepartmentOrganization(Map map); + + List> queryDepartmentList(@Param("companyIds") List companyIds, @Param("departmentIds") List departmentIds); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobDao.java new file mode 100644 index 0000000..eba1d06 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.CompanyJob; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface CompanyJobDao extends SkyeyeBaseMapper { + + List> queryCompanyJobList(TableSelectInfo tableSelectInfo); + + List> queryCompanyJobListTreeByDepartmentId(Map map); + + List> queryCompanyJobSimpleList(Map map); + + List> queryJobList(@Param("companyIds") List companyIds, @Param("departmentIds") List departmentIds); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreDao.java new file mode 100644 index 0000000..43188cb --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.JobScore; +import com.skyeye.organization.entity.JobScoreQueryDo; + +import java.util.List; +import java.util.Map; + +public interface CompanyJobScoreDao extends SkyeyeBaseMapper { + + List> queryCompanyJobScoreList(JobScoreQueryDo pageInfo); + + List> queryEnableCompanyJobScoreList(Map map); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreFieldDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreFieldDao.java new file mode 100644 index 0000000..e8fbce8 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyJobScoreFieldDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.JobScoreField; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface CompanyJobScoreFieldDao extends SkyeyeBaseMapper { + + int deleteCompanyJobScoreFieldByJobScoreId(@Param("jobScoreIdList") List jobScoreIdList); + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyMationDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyMationDao.java new file mode 100644 index 0000000..ec24730 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyMationDao.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.Company; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyMationDao + * @Description: 企业管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 16:05 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface CompanyMationDao extends SkyeyeBaseMapper { + + List> queryCompanyMationList(Map map); + + Map queryCompanyMationById(@Param("id") String id); + + List> queryCompanyMationListTree(Map map); + + Map queryCompanyUserNumMationById(@Param("id") String id); + + Map queryCompanyDepartMentNumMationById(@Param("id") String id); + + List> queryCompanyListToSelect(Map map); + + List> queryCompanyList(@Param("id") String id); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyTaxRateDao.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyTaxRateDao.java new file mode 100644 index 0000000..c4ce5ce --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/dao/CompanyTaxRateDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.organization.entity.CompanyTaxRate; + +/** + * @ClassName: CompanyTaxRateDao + * @Description: 公司个人所得税税率信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 15:47 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface CompanyTaxRateDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Company.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Company.java new file mode 100644 index 0000000..f0473ae --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Company.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.AreaInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Company + * @Description: 企业信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/19 1:09 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("企业信息实体类") +@UniqueField +@RedisCacheField(name = CacheConstants.ORGANIZATION_COMPANY_CACHE_KEY) +@TableName(value = "company_mation") +public class Company extends AreaInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "企业名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "公司简介") + private String remark; + + @TableField("p_id") + @ApiModelProperty(value = "所属公司ID,一级公司为0", required = "required") + private String pId; + + @TableField(exist = false) + @ApiModelProperty(value = "公司个人所得税税率信息", required = "json") + private List taxRate; + + public String getpId() { + return pId; + } +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyJob.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyJob.java new file mode 100644 index 0000000..73680b1 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyJob.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: CompanyJob + * @Description: 部门职位信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/23 23:17 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("部门职位信息实体类") +@UniqueField(value = {"departmentId", "name"}) +@RedisCacheField(name = CacheConstants.ORGANIZATION_JOB_CACHE_KEY) +@TableName(value = "company_job") +public class CompanyJob extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("company_id") + @ApiModelProperty(value = "所属公司id", required = "required") + private String companyId; + + @TableField("department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "简介") + private String remark; + + @TableField("parent_id") + @ApiModelProperty(value = "父职位id,一级职位为0", required = "required") + private String parentId; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyTaxRate.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyTaxRate.java new file mode 100644 index 0000000..18d6ce6 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/CompanyTaxRate.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: CompanyTaxRate + * @Description: 公司个人所得税税率信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 15:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("公司个人所得税税率信息实体类") +@TableName(value = "company_tax_rate") +public class CompanyTaxRate extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("company_id") + @Property(value = "企业id") + private String companyId; + + @TableField("min_money") + @ApiModelProperty(value = "薪资范围-最小值(大于等于)", required = "required") + private String minMoney; + + @TableField("max_money") + @ApiModelProperty(value = "薪资范围-最大值(小于)", required = "required") + private String maxMoney; + + @TableField("jan_rate") + @ApiModelProperty(value = "一月份税率信息", required = "required") + private String janRate; + + @TableField("feb_rate") + @ApiModelProperty(value = "二月份税率信息", required = "required") + private String febRate; + + @TableField("mar_rate") + @ApiModelProperty(value = "三月份税率信息", required = "required") + private String marRate; + + @TableField("apr_rate") + @ApiModelProperty(value = "四月份税率信息", required = "required") + private String aprRate; + + @TableField("may_rate") + @ApiModelProperty(value = "五月份税率信息", required = "required") + private String mayRate; + + @TableField("jun_rate") + @ApiModelProperty(value = "六月份税率信息", required = "required") + private String junRate; + + @TableField("jul_rate") + @ApiModelProperty(value = "七月份税率信息", required = "required") + private String julRate; + + @TableField("aug_rate") + @ApiModelProperty(value = "八月份税率信息", required = "required") + private String augRate; + + @TableField("sept_rate") + @ApiModelProperty(value = "九月份税率信息", required = "required") + private String septRate; + + @TableField("oct_rate") + @ApiModelProperty(value = "十月份税率信息", required = "required") + private String octRate; + + @TableField("nov_rate") + @ApiModelProperty(value = "十一月份税率信息", required = "required") + private String novRate; + + @TableField("dec_rate") + @ApiModelProperty(value = "十二月份税率信息", required = "required") + private String decRate; + + @TableField("sort_no") + @ApiModelProperty(value = "值越大越往后", required = "required") + private Integer sortNo; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Department.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Department.java new file mode 100644 index 0000000..c0c915d --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/Department.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Department + * @Description: 部门信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/20 21:27 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("部门信息实体类") +@UniqueField +@RedisCacheField(name = CacheConstants.ORGANIZATION_DEPARTMENT_CACHE_KEY) +@TableName(value = "company_department") +public class Department extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("company_id") + @ApiModelProperty(value = "所属公司id", required = "required") + private String companyId; + + @TableField("`name`") + @ApiModelProperty(value = "部门名称", required = "required") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "部门简介") + private String remark; + + @TableField("parent_id") + @ApiModelProperty(value = "父部门id,一级公司为0", required = "required") + private String parentId; + + @TableField("overtime_settlement_type") + @ApiModelProperty(value = "部门加班结算方式 1.单倍薪资结算 2.1.5倍薪资结算 3.双倍薪资结算 6.补休结算", required = "required,num") + private Integer overtimeSettlementType; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScore.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScore.java new file mode 100644 index 0000000..d636eab --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScore.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: JobScore + * @Description: 职位定级信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 22:28 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("职位定级信息实体类") +@UniqueField(value = {"name", "jobId"}) +@RedisCacheField(name = CacheConstants.ORGANIZATION_JOB_SCORE_CACHE_KEY) +@TableName(value = "company_job_score") +public class JobScore extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("job_id") + @ApiModelProperty(value = "职位id", required = "required") + private String jobId; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField("enabled") + @ApiModelProperty(value = "状态(1 启用 2.停用)", required = "required,num") + private Integer enabled; + + @TableField(exist = false) + @ApiModelProperty(value = "职位定级薪资字段设计范围实体类", required = "json") + private List scoreFields; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreField.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreField.java new file mode 100644 index 0000000..6481a00 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreField.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: JobScoreField + * @Description: 职位定级薪资字段设计范围实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 22:28 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("职位定级薪资字段设计范围实体类") +@UniqueField(value = {"jobScoreId", "fieldKey"}) +@TableName(value = "company_job_score_field") +public class JobScoreField extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("job_score_id") + @Property("职位定级id") + private String jobScoreId; + + @TableField("field_key") + @ApiModelProperty(value = "薪资字段key", required = "required") + private String fieldKey; + + @TableField(exist = false) + @Property("薪资字段名称") + private String fieldName; + + @TableField("min_money") + @ApiModelProperty(value = "该级别的职位在该薪资字段中的薪资最小值", required = "required,double") + private Integer minMoney; + + @TableField("max_money") + @ApiModelProperty(value = "该级别的职位在该薪资字段中的薪资最大值", required = "required,double") + private Integer maxMoney; + + @TableField("sort_no") + @ApiModelProperty(value = "排序,值越大越往后", required = "required,num") + private Integer sortNo; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private Integer remark; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreQueryDo.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreQueryDo.java new file mode 100644 index 0000000..88d63e8 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/entity/JobScoreQueryDo.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +/** + * @ClassName: JobScoreQueryDo + * @Description: 职位定级信息搜索实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 22:49 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("职位定级信息搜索实体类") +public class JobScoreQueryDo extends CommonPageInfo { + + @ApiModelProperty(value = "职位id") + private String jobId; + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyDepartmentService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyDepartmentService.java new file mode 100644 index 0000000..06ddfab --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyDepartmentService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.Department; + +import java.util.List; +import java.util.Map; + +public interface CompanyDepartmentService extends SkyeyeBusinessService { + + void queryCompanyDepartmentListTreeByCompanyId(InputObject inputObject, OutputObject outputObject); + + void queryCompanyDepartmentListByCompanyIdToSelect(InputObject inputObject, OutputObject outputObject); + + void queryCompanyDepartmentListToChoose(InputObject inputObject, OutputObject outputObject); + + void queryDepartmentListByCurrentUserBelong(InputObject inputObject, OutputObject outputObject); + + List> queryDepartmentList(List companyIds, List departmentIds); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreFieldService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreFieldService.java new file mode 100644 index 0000000..1a83d50 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreFieldService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.organization.entity.JobScoreField; + +import java.util.List; + +/** + * @ClassName: CompanyJobScoreFieldService + * @Description: 职位定级薪资字段设计范围服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 23:00 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CompanyJobScoreFieldService extends SkyeyeBusinessService { + + void saveJobScoreFieldList(String jobScoreId, List scoreFields, String userId); + + List queryJobScoreFieldListByJobScoreId(String... jobScoreIds); + + void deleteJobScoreFieldByJobScoreId(String... jobScoreIds); + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreService.java new file mode 100644 index 0000000..62e2e66 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobScoreService.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.JobScore; + +public interface CompanyJobScoreService extends SkyeyeBusinessService { + + void queryEnableCompanyJobScoreList(InputObject inputObject, OutputObject outputObject); + + void deleteByJobId(String jobId); + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobService.java new file mode 100644 index 0000000..9bdef0e --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyJobService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.CompanyJob; + +import java.util.List; +import java.util.Map; + +public interface CompanyJobService extends SkyeyeBusinessService { + + void queryCompanyJobListTreeByDepartmentId(InputObject inputObject, OutputObject outputObject); + + void queryCompanyJobListByToSelect(InputObject inputObject, OutputObject outputObject); + + void queryCompanyJobSimpleListByToSelect(InputObject inputObject, OutputObject outputObject); + + List> queryJobList(List companyIds, List departmentIds); + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyMationService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyMationService.java new file mode 100644 index 0000000..ad008f5 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyMationService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.organization.entity.Company; + +import java.util.List; +import java.util.Map; + +public interface CompanyMationService extends SkyeyeBusinessService { + + void queryOverAllCompanyMationList(InputObject inputObject, OutputObject outputObject); + + void queryCompanyMationListTree(InputObject inputObject, OutputObject outputObject); + + void queryCompanyListToSelect(InputObject inputObject, OutputObject outputObject); + + void queryCompanyOrganization(InputObject inputObject, OutputObject outputObject); + + List> queryCompanyList(String companyId); +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyTaxRateService.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyTaxRateService.java new file mode 100644 index 0000000..d962052 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/CompanyTaxRateService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.organization.entity.CompanyTaxRate; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyTaxRateService + * @Description: 公司个人所得税税率信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 15:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface CompanyTaxRateService extends SkyeyeBusinessService { + + void deleteCompanyTaxRateByPId(String companyId); + + void saveCompanyTaxRate(String companyId, List companyTaxRateList); + + List queryCompanyTaxRateByPId(String companyId); + + Map> queryCompanyTaxRateByPId(List companyId); + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyDepartmentServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyDepartmentServiceImpl.java new file mode 100644 index 0000000..6bbd74f --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyDepartmentServiceImpl.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.OvertimeSettlementType; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.dao.CompanyDepartmentDao; +import com.skyeye.organization.entity.Department; +import com.skyeye.organization.service.CompanyDepartmentService; +import com.skyeye.organization.service.CompanyMationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CompanyDepartmentServiceImpl + * @Description: 公司部门信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CompanyDepartmentServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyDepartmentService { + + @Autowired + private CompanyDepartmentDao companyDepartmentDao; + + @Autowired + private CompanyMationService companyMationService; + + /** + * 获取公司部门信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + */ + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = companyDepartmentDao.queryCompanyDepartmentList(commonPageInfo); + companyMationService.setNameMationForMap(beans, "companyId", "companyName", StrUtil.EMPTY); + beans.forEach(bean -> { + Integer overtimeSettlementType = Integer.parseInt(bean.get("overtimeSettlementType").toString()); + bean.put("overtimeSettlementTypeName", OvertimeSettlementType.getTitleByType(overtimeSettlementType)); + }); + return beans; + } + + @Override + public void deletePreExecution(String id) { + // 判断是否有员工 + Map bean = companyDepartmentDao.queryCompanyDepartmentUserMationById(id); + if (Integer.parseInt(bean.get("childsNum").toString()) > 0) { + throw new CustomException("该部门下存在员工,无法直接删除。"); + } + // 判断是否有职位 + bean = companyDepartmentDao.queryCompanyJobNumMationById(id); + if (Integer.parseInt(bean.get("companyJobNum").toString()) > 0) { + throw new CustomException("该部门下存在职位,无法直接删除。"); + } + } + + /** + * 获取公司部门信息列表展示为树根据公司id + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyDepartmentListTreeByCompanyId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = companyDepartmentDao.queryCompanyDepartmentListTreeByCompanyId(map); + beans = ToolUtil.listToTree(beans, "id", "parentId", "children"); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 根据公司id获取部门列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyDepartmentListByCompanyIdToSelect(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String companyId = map.get("companyId").toString(); + List> beans = queryDepartmentList(Arrays.asList(companyId), new ArrayList<>()); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取部门列表展示为表格供其他选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + + @Override + public void queryCompanyDepartmentListToChoose(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = queryPageDataList(inputObject); + companyMationService.setNameMationForMap(beans, "companyId", "companyName", StrUtil.EMPTY); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取当前登录用户所属企业的所有部门信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDepartmentListByCurrentUserBelong(InputObject inputObject, OutputObject outputObject) { + Map user = inputObject.getLogParams(); + String companyId = user.get("companyId").toString(); + List> list = queryDepartmentList(Arrays.asList(companyId), new ArrayList<>()); + outputObject.setBean(user); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + @Override + public List> queryDepartmentList(List companyIds, List departmentIds) { + companyIds = companyIds.stream().filter(str -> !ToolUtil.isBlank(str)).collect(Collectors.toList()); + departmentIds = departmentIds.stream().filter(str -> !ToolUtil.isBlank(str)).collect(Collectors.toList()); + List> beans = companyDepartmentDao.queryDepartmentList(companyIds, departmentIds); + return CollectionUtil.isNotEmpty(beans) ? beans : new ArrayList<>(); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreFieldServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreFieldServiceImpl.java new file mode 100644 index 0000000..4e06df0 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreFieldServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.organization.entity.JobScoreField; +import com.skyeye.organization.dao.CompanyJobScoreFieldDao; +import com.skyeye.organization.service.CompanyJobScoreFieldService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: CompanyJobScoreFieldServiceImpl + * @Description: 职位定级薪资字段设计范围服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/25 23:01 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CompanyJobScoreFieldServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyJobScoreFieldService { + + @Autowired + private CompanyJobScoreFieldDao companyJobScoreFieldDao; + + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void saveJobScoreFieldList(String jobScoreId, List scoreFields, String userId) { + deleteJobScoreFieldByJobScoreId(jobScoreId); + scoreFields.forEach(jobScoreField -> jobScoreField.setJobScoreId(jobScoreId)); + super.createEntity(scoreFields, userId); + } + + @Override + public List queryJobScoreFieldListByJobScoreId(String... jobScoreIds) { + List jobScoreIdList = Arrays.asList(jobScoreIds); + jobScoreIdList = jobScoreIdList.stream().filter(str -> !ToolUtil.isBlank(str)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(jobScoreIdList)) { + return new ArrayList<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(JobScoreField::getJobScoreId), jobScoreIdList); + return list(queryWrapper); + } + + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteJobScoreFieldByJobScoreId(String... jobScoreIds) { + List jobScoreIdList = Arrays.asList(jobScoreIds); + jobScoreIdList = jobScoreIdList.stream().filter(str -> !ToolUtil.isBlank(str)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(jobScoreIdList)) { + return; + } + companyJobScoreFieldDao.deleteCompanyJobScoreFieldByJobScoreId(jobScoreIdList); + } + + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreServiceImpl.java new file mode 100644 index 0000000..3f1a91c --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobScoreServiceImpl.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.organization.entity.JobScore; +import com.skyeye.organization.entity.JobScoreField; +import com.skyeye.organization.entity.JobScoreQueryDo; +import com.skyeye.organization.dao.CompanyJobScoreDao; +import com.skyeye.organization.service.CompanyJobScoreFieldService; +import com.skyeye.organization.service.CompanyJobScoreService; +import com.skyeye.wages.service.IWagesFieldTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CompanyJobScoreServiceImpl + * @Description: 职位定级信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CompanyJobScoreServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyJobScoreService { + + @Autowired + private CompanyJobScoreDao companyJobScoreDao; + + @Autowired + private CompanyJobScoreFieldService companyJobScoreFieldService; + + @Autowired + private IWagesFieldTypeService iWagesFieldTypeService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + JobScoreQueryDo pageInfo = inputObject.getParams(JobScoreQueryDo.class); + List> beans = companyJobScoreDao.queryCompanyJobScoreList(pageInfo); + return beans; + } + + @Override + public void writePostpose(JobScore entity, String userId) { + super.writePostpose(entity, userId); + companyJobScoreFieldService.saveJobScoreFieldList(entity.getId(), entity.getScoreFields(), userId); + } + + @Override + public JobScore getDataFromDb(String id) { + JobScore jobScore = super.getDataFromDb(id); + List jobScoreFields = companyJobScoreFieldService.queryJobScoreFieldListByJobScoreId(jobScore.getId()); + jobScore.setScoreFields(jobScoreFields); + return jobScore; + } + + @Override + public List getDataFromDb(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return new ArrayList<>(); + } + List jobScoreList = super.getDataFromDb(ids); + // 批量获取关联的薪资字段信息 + List jobScoreFields = companyJobScoreFieldService.queryJobScoreFieldListByJobScoreId(ids.toArray(new String[]{})); + Map> collect = jobScoreFields.stream().collect(Collectors.groupingBy(JobScoreField::getJobScoreId)); + + jobScoreList.forEach(jobScore -> jobScore.setScoreFields(collect.get(jobScore.getId()))); + return jobScoreList; + } + + @Override + public JobScore selectById(String id) { + JobScore jobScore = super.selectById(id); + List jobScoreFields = jobScore.getScoreFields(); + if (CollectionUtil.isNotEmpty(jobScoreFields)) { + List keys = jobScoreFields.stream().map(JobScoreField::getFieldKey).collect(Collectors.toList()); + String keyStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(keys); + List> list = iWagesFieldTypeService.queryWagesFieldListByKeys(keyStr); + Map fieldMation = list.stream() + .collect(Collectors.toMap(bean -> bean.get("key").toString(), bean -> bean.get("name").toString())); + jobScoreFields.forEach(jobScoreField -> { + jobScoreField.setFieldName(fieldMation.get(jobScoreField.getFieldKey())); + }); + jobScore.setScoreFields(jobScoreFields); + } + return jobScore; + } + + @Override + public void deletePostpose(String id) { + companyJobScoreFieldService.deleteJobScoreFieldByJobScoreId(id); + } + + @Override + public void deletePostpose(List ids) { + companyJobScoreFieldService.deleteJobScoreFieldByJobScoreId(ids.toArray(new String[]{})); + } + + /** + * 获取已经启用的职位定级信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnableCompanyJobScoreList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("enabled", EnableEnum.ENABLE_USING.getKey()); + List> beans = companyJobScoreDao.queryEnableCompanyJobScoreList(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void deleteByJobId(String jobId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JobScore::getJobId), jobId); + List jobScoreList = list(queryWrapper); + if (CollectionUtil.isEmpty(jobScoreList)) { + return; + } + List jobScoreIds = jobScoreList.stream().map(JobScore::getId).collect(Collectors.toList()); + super.deleteById(jobScoreIds); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobServiceImpl.java new file mode 100644 index 0000000..857c70b --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyJobServiceImpl.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.organization.entity.CompanyJob; +import com.skyeye.organization.dao.CompanyJobDao; +import com.skyeye.organization.service.CompanyJobScoreService; +import com.skyeye.organization.service.CompanyJobService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CompanyJobServiceImpl + * @Description: 公司部门职位信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CompanyJobServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyJobService { + + @Autowired + private CompanyJobDao companyJobDao; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private CompanyJobScoreService companyJobScoreService; + + /** + * 获取公司部门职位信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + */ + @Override + public List> queryDataList(InputObject inputObject) { + TableSelectInfo tableSelectInfo = inputObject.getParams(TableSelectInfo.class); + List> beans = companyJobDao.queryCompanyJobList(tableSelectInfo); + iCompanyService.setNameForMap(beans, "companyId", "companyName"); + iDepmentService.setNameForMap(beans, "departmentId", "departmentName"); + String[] s; + for (Map bean : beans) { + s = bean.get("parentId").toString().split(","); + if (s.length > 0) { + bean.put("parentId", s[s.length - 1]); + } else { + bean.put("parentId", "0"); + } + } + return beans; + } + + @Override + public void deletePostpose(String id) { + // 删除职位等级信息 + companyJobScoreService.deleteByJobId(id); + } + + /** + * 获取公司部门职位信息列表展示为树根据公司id + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyJobListTreeByDepartmentId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = companyJobDao.queryCompanyJobListTreeByDepartmentId(map); + String[] s; + for (Map bean : beans) { + s = bean.get("parentId").toString().split(","); + bean.put("level", s.length); + if (s.length > 0) { + bean.put("parentId", s[s.length - 1]); + } else { + bean.put("parentId", "0"); + } + } + beans = ToolUtil.listToTree(beans, "id", "parentId", "children"); + if (!beans.isEmpty()) { + ToolUtil.setLastIdentification(beans); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + /** + * 根据部门id获取职位列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyJobListByToSelect(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = companyJobDao.queryCompanyJobSimpleList(map); + if (CollectionUtil.isNotEmpty(beans)) { + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + /** + * 根据部门id获取职位同级列表且不包含当前id的值展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyJobSimpleListByToSelect(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = companyJobDao.queryCompanyJobSimpleList(map); + if (CollectionUtil.isNotEmpty(beans)) { + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + @Override + public List> queryJobList(List companyIds, List departmentIds) { + companyIds = companyIds.stream().filter(str -> !ToolUtil.isBlank(str)).collect(Collectors.toList()); + departmentIds = departmentIds.stream().filter(str -> !ToolUtil.isBlank(str)).collect(Collectors.toList()); + List> beans = companyJobDao.queryJobList(companyIds, departmentIds); + return CollectionUtil.isNotEmpty(beans) ? beans : new ArrayList<>(); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyMationServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyMationServiceImpl.java new file mode 100644 index 0000000..b968628 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyMationServiceImpl.java @@ -0,0 +1,244 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.service.IAreaService; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.dao.CompanyDepartmentDao; +import com.skyeye.organization.dao.CompanyJobDao; +import com.skyeye.organization.dao.CompanyMationDao; +import com.skyeye.organization.entity.Company; +import com.skyeye.organization.entity.CompanyTaxRate; +import com.skyeye.organization.service.CompanyMationService; +import com.skyeye.organization.service.CompanyTaxRateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyMationServiceImpl + * @Description: 公司信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "企业管理", groupName = "组织模块") +public class CompanyMationServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyMationService { + + @Autowired + private CompanyDepartmentDao companyDepartmentDao; + + @Autowired + private CompanyJobDao companyJobDao; + + @Autowired + private IAreaService iAreaService; + + @Autowired + private CompanyTaxRateService companyTaxRateService; + + @Override + public List> queryDataList(InputObject inputObject) { + Map map = inputObject.getParams(); + List> beans = skyeyeBaseMapper.queryCompanyMationList(map); + iAreaService.setNameForMap(beans, "provinceId", "provinceName"); + iAreaService.setNameForMap(beans, "cityId", "cityName"); + iAreaService.setNameForMap(beans, "areaId", "areaName"); + iAreaService.setNameForMap(beans, "townshipId", "townshipName"); + return beans; + } + + @Override + public void writePostpose(Company entity, String userId) { + super.writePostpose(entity, userId); + companyTaxRateService.saveCompanyTaxRate(entity.getId(), entity.getTaxRate()); + } + + @Override + public void deletePreExecution(String id) { + // 判断是否有子公司 + Map bean = skyeyeBaseMapper.queryCompanyMationById(id); + if (Integer.parseInt(bean.get("childsNum").toString()) > 0) { + throw new CustomException("该公司下存在子公司,无法直接删除。"); + } + // 判断是否有部门 + bean = skyeyeBaseMapper.queryCompanyDepartMentNumMationById(id); + if (Integer.parseInt(bean.get("departmentNum").toString()) > 0) { + throw new CustomException("该公司下存在部门,无法直接删除。"); + } + // 判断是否有员工 + bean = skyeyeBaseMapper.queryCompanyUserNumMationById(id); + if (Integer.parseInt(bean.get("companyUserNum").toString()) > 0) { + throw new CustomException("该公司下存在员工,无法直接删除。"); + } + } + + @Override + public void deletePostpose(String id) { + // 删除完成后的后置执行事件,根据公司id删除该公司拥有的个人所得税税率信息 + companyTaxRateService.deleteCompanyTaxRateByPId(id); + } + + @Override + public Company getDataFromDb(String id) { + Company company = super.getDataFromDb(id); + // 个人所得税税率信息 + company.setTaxRate(companyTaxRateService.queryCompanyTaxRateByPId(id)); + return company; + } + + @Override + public List getDataFromDb(List ids) { + List companyList = super.getDataFromDb(ids); + if (CollectionUtil.isEmpty(companyList)) { + return new ArrayList<>(); + } + Map> companyTaxRateMap = companyTaxRateService.queryCompanyTaxRateByPId(ids); + companyList.forEach(company -> { + company.setTaxRate(companyTaxRateMap.get(company.getId())); + }); + return companyList; + } + + /** + * 获取总公司信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryOverAllCompanyMationList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String notId = map.get("notId").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Company::getpId), CommonNumConstants.NUM_ZERO.toString()); + if (StrUtil.isNotEmpty(notId)) { + queryWrapper.ne(CommonConstants.ID, notId); + } + List companyList = list(queryWrapper); + outputObject.setBeans(companyList); + outputObject.settotal(companyList.size()); + } + + /** + * 获取公司信息列表展示为树 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyMationListTree(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = skyeyeBaseMapper.queryCompanyMationListTree(map); + String[] s; + for (Map bean : beans) { + s = bean.get("parentId").toString().split(","); + bean.put("level", s.length); + if (s.length > 0) { + bean.put("parentId", s[s.length - 1]); + } else { + bean.put("parentId", "0"); + } + } + beans = ToolUtil.listToTree(beans, "id", "parentId", "children"); + if (CollectionUtil.isNotEmpty(beans)) { + ToolUtil.setLastIdentification(beans); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + } + + /** + * 获取公司列表展示为下拉选择框 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyListToSelect(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = skyeyeBaseMapper.queryCompanyListToSelect(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取企业组织机构图 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyOrganization(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = new ArrayList<>(); + // 1.获取企业 + List> company = skyeyeBaseMapper.queryCompanyListToSelect(map); + beans.addAll(company); + // 2.获取部门 + List> department = companyDepartmentDao.queryCompanyDepartmentOrganization(map); + for (Map bean : department) { + String[] s = bean.get("parentId").toString().split(","); + if (s.length > 0 && !"0".equals(bean.get("parentId").toString())) { + bean.put("parentId", s[s.length - 1]); + } else { + bean.put("parentId", bean.get("companyId")); + } + } + beans.addAll(department); + // 3.获取职位 + List> job = companyJobDao.queryCompanyJobSimpleList(new HashMap<>()); + for (Map bean : job) { + String[] s = bean.get("parentId").toString().split(","); + if (s.length > 0 && !"0".equals(bean.get("parentId").toString())) { + bean.put("parentId", s[s.length - 1]); + } else { + bean.put("parentId", bean.get("departmentId")); + } + } + beans.addAll(job); + beans = ToolUtil.listToTree(beans, "id", "parentId", "children"); + outputObject.setBeans(getParentMap(beans)); + } + + private List> getParentMap(List> children) { + List> beans = new ArrayList<>(); + Map map = new HashMap<>(); + map.put("name", "所有"); + map.put("title", "企业组织结构图"); + map.put("children", children); + beans.add(map); + return beans; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + return this.queryDataList(inputObject); + } + + @Override + public List> queryCompanyList(String companyId) { + List> beans = skyeyeBaseMapper.queryCompanyList(companyId); + return CollectionUtil.isNotEmpty(beans) ? beans : new ArrayList<>(); + } + +} diff --git a/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyTaxRateServiceImpl.java b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyTaxRateServiceImpl.java new file mode 100644 index 0000000..7f03de2 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/java/com/skyeye/organization/service/impl/CompanyTaxRateServiceImpl.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.organization.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.organization.dao.CompanyTaxRateDao; +import com.skyeye.organization.entity.CompanyTaxRate; +import com.skyeye.organization.service.CompanyTaxRateService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CompanyTaxRateServiceImpl + * @Description: 公司个人所得税税率信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 15:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "公司个人所得税税率信息", groupName = "组织模块", manageShow = false) +public class CompanyTaxRateServiceImpl extends SkyeyeBusinessServiceImpl implements CompanyTaxRateService { + + @Override + public void deleteCompanyTaxRateByPId(String companyId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CompanyTaxRate::getCompanyId), companyId); + remove(queryWrapper); + } + + @Override + public void saveCompanyTaxRate(String companyId, List companyTaxRateList) { + deleteCompanyTaxRateByPId(companyId); + if (CollectionUtil.isNotEmpty(companyTaxRateList)) { + for (CompanyTaxRate companyTaxRate : companyTaxRateList) { + companyTaxRate.setCompanyId(companyId); + } + createEntity(companyTaxRateList, StrUtil.EMPTY); + } + } + + @Override + public List queryCompanyTaxRateByPId(String companyId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CompanyTaxRate::getCompanyId), companyId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(CompanyTaxRate::getSortNo)); + List companyTaxRates = list(queryWrapper); + return companyTaxRates; + } + + @Override + public Map> queryCompanyTaxRateByPId(List companyId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CompanyTaxRate::getCompanyId), companyId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(CompanyTaxRate::getSortNo)); + List companyTaxRates = list(queryWrapper); + Map> listMap = companyTaxRates.stream() + .collect(Collectors.groupingBy(CompanyTaxRate::getCompanyId)); + return listMap; + } +} diff --git a/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyDepartmentMapper.xml b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyDepartmentMapper.xml new file mode 100644 index 0000000..8a1425b --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyDepartmentMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobMapper.xml b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobMapper.xml new file mode 100644 index 0000000..168370c --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobMapper.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreFieldMapper.xml b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreFieldMapper.xml new file mode 100644 index 0000000..061ac22 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreFieldMapper.xml @@ -0,0 +1,17 @@ + + + + + + DELETE + FROM + company_job_score_field + + AND job_score_id IN + + #{jobScoreId} + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreMapper.xml b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreMapper.xml new file mode 100644 index 0000000..71b8d85 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyJobScoreMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyMationMapper.xml b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyMationMapper.xml new file mode 100644 index 0000000..46df241 --- /dev/null +++ b/skyeye-promote/skyeye-organization/src/main/resources/mapper/organization/CompanyMationMapper.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-quartz/.gitignore b/skyeye-promote/skyeye-quartz/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-quartz/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-quartz/.project b/skyeye-promote/skyeye-quartz/.project new file mode 100644 index 0000000..2d67d0e --- /dev/null +++ b/skyeye-promote/skyeye-quartz/.project @@ -0,0 +1,23 @@ + + + skyeye-quartz + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-quartz/pom.xml b/skyeye-promote/skyeye-quartz/pom.xml new file mode 100644 index 0000000..070369a --- /dev/null +++ b/skyeye-promote/skyeye-quartz/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + + skyeye-quartz + + skyeye-quartz + http://www.example.com + + + + + + com.skyeye + skyeye-mq + 0.0.1-SNAPSHOT + + + + com.skyeye + skyeye-entity + 0.0.1-SNAPSHOT + + + + + + + diff --git a/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/controller/SysQuartzController.java b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/controller/SysQuartzController.java new file mode 100644 index 0000000..dacb5ab --- /dev/null +++ b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/controller/SysQuartzController.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.SysQuartzService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "定时任务", tags = "定时任务", modelName = "定时任务模块") +public class SysQuartzController { + + @Autowired + private SysQuartzService sysQuartzService; + + /** + * 启动定时任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "startUpTaskQuartz", value = "启动定时任务", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SysQuartzMation.class) + @RequestMapping("/post/SysQuartzController/startUpTaskQuartz") + public void startUpTaskQuartz(InputObject inputObject, OutputObject outputObject) { + sysQuartzService.startUpTaskQuartz(inputObject, outputObject); + } + + /** + * 停止并删除定时任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "stopAndDeleteTaskQuartz", value = "停止并删除定时任务", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "任务的唯一值,例如:工作计划的id等", required = "required")}) + @RequestMapping("/post/SysQuartzController/stopAndDeleteTaskQuartz") + public void stopAndDeleteTaskQuartz(InputObject inputObject, OutputObject outputObject) { + sysQuartzService.stopAndDeleteTaskQuartz(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/SysQuartzService.java b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/SysQuartzService.java new file mode 100644 index 0000000..2b23f9a --- /dev/null +++ b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/SysQuartzService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: SysQuartzService + * @Description: 定时任务service接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/25 22:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SysQuartzService { + + void startUpTaskQuartz(InputObject inputObject, OutputObject outputObject); + + void stopAndDeleteTaskQuartz(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/impl/SysQuartzServiceImpl.java b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/impl/SysQuartzServiceImpl.java new file mode 100644 index 0000000..0718b6a --- /dev/null +++ b/skyeye-promote/skyeye-quartz/src/main/java/com/skyeye/eve/service/impl/SysQuartzServiceImpl.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSON; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.entity.xxljob.XxlJobInfo; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.rest.xxljob.XxlJobService; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.eve.service.SysQuartzService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: SysQuartzServiceImpl + * @Description: 定时任务服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/12/3 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SysQuartzServiceImpl implements SysQuartzService { + + private static final Logger LOGGER = LoggerFactory.getLogger(SysQuartzServiceImpl.class); + + @Autowired + private XxlJobService xxlJobService; + + @Autowired + private IAuthUserService iAuthUserService; + + /** + * 启动定时任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void startUpTaskQuartz(InputObject inputObject, OutputObject outputObject) { + SysQuartzMation sysQuartz = inputObject.getParams(SysQuartzMation.class); + String userId = inputObject.getLogParams().get("id").toString(); + LOGGER.info("start quartz, title is {}, userId is {}", sysQuartz.getTitle(), userId); + String groupId = ExecuteFeignClient.get(() -> xxlJobService.getGroupId(sysQuartz.getAppName())).getBean().get("id").toString(); + LOGGER.info("xxl-job groupId is {}", groupId); + XxlJobInfo xxlJobInfo = this.getXxlJobInfo(sysQuartz.getName(), groupId, sysQuartz.getDelayedTime(), sysQuartz.getTitle(), sysQuartz.getGroupId(), userId); + ExecuteFeignClient.get(() -> xxlJobService.addAndStart(xxlJobInfo)); + } + + private XxlJobInfo getXxlJobInfo(String objectId, String groupId, String delayedTime, String jobDesc, String taskType, String userId) { + XxlJobInfo xxlJobInfo = new XxlJobInfo(); + Map user = iAuthUserService.queryDataMationById(userId); + String author = "商城用户"; + if (CollectionUtil.isNotEmpty(user)) { + author = user.get("name").toString(); + } + xxlJobInfo.setAuthor(author); + xxlJobInfo.setJobGroup(Integer.parseInt(groupId)); + xxlJobInfo.setJobDesc(QuartzConstants.QuartzMateMationJobType.getRemarkPrefixByTaskType(taskType, jobDesc)); + xxlJobInfo.setScheduleType("CRON"); + String cron = ToolUtil.getCrons1(delayedTime); + xxlJobInfo.setScheduleConf(cron); + xxlJobInfo.setGlueType("BEAN"); + xxlJobInfo.setExecutorRouteStrategy("FIRST"); + xxlJobInfo.setExecutorHandler(QuartzConstants.QuartzMateMationJobType.getServiceNameByTaskType(taskType)); + xxlJobInfo.setObjectId(objectId); + xxlJobInfo.setExecutorParam(this.getExecutorParam(objectId, userId)); + xxlJobInfo.setMisfireStrategy("DO_NOTHING"); + xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION"); + xxlJobInfo.setExecutorTimeout(0); + xxlJobInfo.setExecutorFailRetryCount(0); + xxlJobInfo.setGlueRemark("GLUE代码初始化"); + return xxlJobInfo; + } + + private String getExecutorParam(String objectId, String userId) { + Map executorParam = new HashMap<>(); + executorParam.put("objectId", objectId); + executorParam.put("userId", userId); + return JSON.toJSONString(executorParam); + } + + /** + * 停止并删除定时任务 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void stopAndDeleteTaskQuartz(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String objectId = map.get("objectId").toString(); + LOGGER.info("stop quartz, name is {}", objectId); + ExecuteFeignClient.get(() -> xxlJobService.removeJob(objectId)); + } + +} diff --git a/skyeye-promote/skyeye-threed/.gitignore b/skyeye-promote/skyeye-threed/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-threed/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-threed/.project b/skyeye-promote/skyeye-threed/.project new file mode 100644 index 0000000..3028b77 --- /dev/null +++ b/skyeye-promote/skyeye-threed/.project @@ -0,0 +1,23 @@ + + + skyeye-threed + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-threed/pom.xml b/skyeye-promote/skyeye-threed/pom.xml new file mode 100644 index 0000000..dc37950 --- /dev/null +++ b/skyeye-promote/skyeye-threed/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + + com.skyeye + skyeye-promote + 0.0.1-SNAPSHOT + + + skyeye-threed + skyeye-threed + http://maven.apache.org + + + UTF-8 + + + + + + diff --git a/skyeye-promote/skyeye-userauth/.gitignore b/skyeye-promote/skyeye-userauth/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-userauth/.project b/skyeye-promote/skyeye-userauth/.project new file mode 100644 index 0000000..4e58975 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/.project @@ -0,0 +1,23 @@ + + + skyeye-userauth + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-userauth/pom.xml b/skyeye-promote/skyeye-userauth/pom.xml new file mode 100644 index 0000000..51d68a1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + com.skyeye + skyeye-promote + 0.0.1-SNAPSHOT + + + skyeye-userauth + skyeye-userauth + http://maven.apache.org + + + UTF-8 + + + + + + com.skyeye + skyeye-organization + 0.0.1-SNAPSHOT + + + + + diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/controller/AuthorityController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/controller/AuthorityController.java new file mode 100644 index 0000000..317e06e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/controller/AuthorityController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.authority.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.authority.service.AuthorityService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AuthorityController + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/3/22 14:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "权限管理", tags = "权限管理", modelName = "权限管理") +public class AuthorityController { + + @Autowired + private AuthorityService authorityService; + + /** + * 获取角色拥有的PC端菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getRoleHasMenuListByRoleId", value = "获取角色拥有的PC端菜单", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "roleId", name = "roleId", value = "角色id", required = "required")}) + @RequestMapping("/post/ApiController/getRoleHasMenuListByRoleId") + public void getRoleHasMenuListByRoleId(InputObject inputObject, OutputObject outputObject) { + authorityService.getRoleHasMenuListByRoleId(inputObject, outputObject); + } + + /** + * 获取角色拥有的APP端菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getRoleHasAppMenuByRoleId", value = "获取角色拥有的APP端菜单", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "roleId", name = "roleId", value = "角色id", required = "required")}) + @RequestMapping("/post/ApiController/getRoleHasAppMenuByRoleId") + public void getRoleHasAppMenuByRoleId(InputObject inputObject, OutputObject outputObject) { + authorityService.getRoleHasAppMenuByRoleId(inputObject, outputObject); + } + + /** + * 获取角色拥有的PC端权限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getRoleHasAuthPointsByRoleId", value = "获取角色拥有的PC端权限", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "roleId", name = "roleId", value = "角色id", required = "required")}) + @RequestMapping("/post/ApiController/getRoleHasAuthPointsByRoleId") + public void getRoleHasAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject) { + authorityService.getRoleHasAuthPointsByRoleId(inputObject, outputObject); + } + + /** + * 获取角色拥有的PC端权限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getRoleHasAppAuthPointsByRoleId", value = "获取角色拥有的PC端权限", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "roleId", name = "roleId", value = "角色id", required = "required")}) + @RequestMapping("/post/ApiController/getRoleHasAppAuthPointsByRoleId") + public void getRoleHasAppAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject) { + authorityService.getRoleHasAppAuthPointsByRoleId(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/dao/AuthorityDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/dao/AuthorityDao.java new file mode 100644 index 0000000..4eea37d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/dao/AuthorityDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.authority.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AuthorityDao + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/3/22 14:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AuthorityDao { + + List> getRoleHasMenuListByRoleId(@Param("roleId") String roleId); + + List> getRoleHasAppMenuByRoleId(@Param("roleId") String roleId); + + List> getRoleHasAuthPointsByRoleId(@Param("roleId") String roleId); + + List> getRoleHasAppAuthPointsByRoleId(@Param("roleId") String roleId); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/AuthorityService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/AuthorityService.java new file mode 100644 index 0000000..1f8c3d9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/AuthorityService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.authority.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AuthorityService + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/3/22 14:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AuthorityService { + + void getRoleHasMenuListByRoleId(InputObject inputObject, OutputObject outputObject); + + void getRoleHasAppMenuByRoleId(InputObject inputObject, OutputObject outputObject); + + void getRoleHasAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject); + + void getRoleHasAppAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/impl/AuthorityServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/impl/AuthorityServiceImpl.java new file mode 100644 index 0000000..3ba9fb7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/authority/service/impl/AuthorityServiceImpl.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.authority.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.authority.dao.AuthorityDao; +import com.skyeye.authority.service.AuthorityService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AuthorityServiceImpl + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/3/22 14:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "权限管理", groupName = "权限管理", manageShow = false) +public class AuthorityServiceImpl implements AuthorityService { + + @Autowired + private AuthorityDao authorityDao; + + @Override + public void getRoleHasMenuListByRoleId(InputObject inputObject, OutputObject outputObject) { + String roleId = inputObject.getParams().get("roleId").toString(); + List> beans = authorityDao.getRoleHasMenuListByRoleId(roleId); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void getRoleHasAppMenuByRoleId(InputObject inputObject, OutputObject outputObject) { + String roleId = inputObject.getParams().get("roleId").toString(); + List> beans = authorityDao.getRoleHasAppMenuByRoleId(roleId); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void getRoleHasAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject) { + String roleId = inputObject.getParams().get("roleId").toString(); + List> beans = authorityDao.getRoleHasAuthPointsByRoleId(roleId); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public void getRoleHasAppAuthPointsByRoleId(InputObject inputObject, OutputObject outputObject) { + String roleId = inputObject.getParams().get("roleId").toString(); + List> beans = authorityDao.getRoleHasAppAuthPointsByRoleId(roleId); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CommonController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CommonController.java new file mode 100644 index 0000000..796d499 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CommonController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.CommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "公共接口", tags = "公共接口", modelName = "基础模块") +public class CommonController { + + @Autowired + private CommonService commonService; + + /** + * 代码生成器生成下载文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CommonController/downloadFileByJsonData") + public void downloadFileByJsonData(InputObject inputObject, OutputObject outputObject) { + commonService.downloadFileByJsonData(inputObject, outputObject); + } + + /** + * 获取win系统桌列表信息供展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysevewinmation001", value = "获取win系统桌列表信息供展示", method = "POST", allUse = "2") + @RequestMapping("/post/CommonController/querySysWinMationById") + public void querySysWinMationById(InputObject inputObject, OutputObject outputObject) { + commonService.querySysWinMationById(inputObject, outputObject); + } + + /** + * 根据文件类型获取文件的保存地址以及访问地址 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFilePathByFileType", value = "根据文件类型获取文件的保存地址以及访问地址", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "fileType", name = "fileType", value = "文件类型", required = "required,num")}) + @RequestMapping("/post/CommonController/queryFilePathByFileType") + public void queryFilePathByFileType(InputObject inputObject, OutputObject outputObject) { + commonService.queryFilePathByFileType(inputObject, outputObject); + } + + /** + * 验证接口是否正确 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformpage010", value = "验证接口是否正确", method = "P0ST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "interfa", name = "interfa", value = "数据")}) + @RequestMapping("/post/CommonController/queryInterfaceIsTrueOrNot") + public void queryInterfaceIsTrueOrNot(InputObject inputObject, OutputObject outputObject) { + commonService.queryInterfaceIsTrueOrNot(inputObject, outputObject); + } + + /** + * 获取接口中的值 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "dsformpage011", value = "获取接口中的值", method = "P0ST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "interfa", name = "interfa", value = "数据")}) + @RequestMapping("/post/CommonController/queryInterfaceValue") + public void queryInterfaceValue(InputObject inputObject, OutputObject outputObject) { + commonService.queryInterfaceValue(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyChatController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyChatController.java new file mode 100644 index 0000000..de79e26 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyChatController.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.CompanyChatService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CompanyChatController { + + @Autowired + private CompanyChatService companyChatService; + + /** + * 获取好友列表,群聊信息,个人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyChatController/getList") + public void getList(InputObject inputObject, OutputObject outputObject) { + companyChatService.getList(inputObject, outputObject); + } + + /** + * 编辑签名 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyChatController/editUserSignByUserId") + public void editUserSignByUserId(InputObject inputObject, OutputObject outputObject) { + companyChatService.editUserSignByUserId(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyTalkGroupController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyTalkGroupController.java new file mode 100644 index 0000000..249ca50 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/CompanyTalkGroupController.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.CompanyTalkGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CompanyTalkGroupController { + + @Autowired + private CompanyTalkGroupService companyTalkGroupService; + + /** + * 添加群组信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/insertGroupMation") + public void queryCodeModelList(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.insertGroupMation(inputObject, outputObject); + } + + /** + * 获取邀请信息/入群信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/queryGroupInvitationMation") + public void queryGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.queryGroupInvitationMation(inputObject, outputObject); + } + + /** + * 同意入群 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/editAgreeInGroupInvitationMation") + public void editAgreeInGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.editAgreeInGroupInvitationMation(inputObject, outputObject); + } + + /** + * 拒绝入群 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/editRefuseInGroupInvitationMation") + public void editRefuseInGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.editRefuseInGroupInvitationMation(inputObject, outputObject); + } + + /** + * 搜索群组列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/queryGroupMationList") + public void queryGroupMationList(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.queryGroupMationList(inputObject, outputObject); + } + + /** + * 申请加入群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/insertGroupMationToTalk") + public void insertGroupMationToTalk(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.insertGroupMationToTalk(inputObject, outputObject); + } + + /** + * 获取群成员 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/queryGroupMemberByGroupId") + public void queryGroupMemberByGroupId(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.queryGroupMemberByGroupId(inputObject, outputObject); + } + + /** + * 获取聊天记录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/queryChatLogByType") + public void queryChatLogByType(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.queryChatLogByType(inputObject, outputObject); + } + + /** + * 退出群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/editUserToExitGroup") + public void editUserToExitGroup(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.editUserToExitGroup(inputObject, outputObject); + } + + /** + * 解散群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/CompanyTalkGroupController/editCreateToExitGroup") + public void editCreateToExitGroup(InputObject inputObject, OutputObject outputObject) { + companyTalkGroupService.editCreateToExitGroup(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/ExExplainController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/ExExplainController.java new file mode 100644 index 0000000..743a124 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/ExExplainController.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.ExExplainService; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ExExplainController + * @Description: 部分功能的使用说明管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/15 18:46 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "功能使用说明", tags = "功能使用说明", modelName = "基础模块") +public class ExExplainController { + + @Autowired + private ExExplainService exExplainService; + + /** + * 添加使用说明信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ExExplainController/insertExExplainMation") + public void insertExExplainMation(InputObject inputObject, OutputObject outputObject) { + exExplainService.insertExExplainMation(inputObject, outputObject); + } + + /** + * 编辑使用说明信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ExExplainController/queryExExplainMation") + public void queryExExplainMation(InputObject inputObject, OutputObject outputObject) { + exExplainService.queryExExplainMation(inputObject, outputObject); + } + + /** + * 编辑使用说明信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/ExExplainController/editExExplainMationById") + public void editExExplainMationById(InputObject inputObject, OutputObject outputObject) { + exExplainService.editExExplainMationById(inputObject, outputObject); + } + + /** + * 获取使用说明信息供展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryExExplainMationToShow", value = "获取使用说明信息供展示", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "type", name = "type", value = "说明介绍类型", required = "required,num")}) + @RequestMapping("/post/ExExplainController/queryExExplainMationToShow") + public void queryExExplainMationToShow(InputObject inputObject, OutputObject outputObject) { + exExplainService.queryExExplainMationToShow(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/StickyNotesController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/StickyNotesController.java new file mode 100644 index 0000000..ef24cb4 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/StickyNotesController.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.StickyNotesService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: StickyNotesController + * @Description: 便签模块控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/20 22:00 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "便签模块", tags = "便签模块", modelName = "便签模块") +public class StickyNotesController { + + @Autowired + private StickyNotesService stickyNotesService; + + /** + * 新增便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/StickyNotesController/insertStickyNotesMation") + public void insertStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + stickyNotesService.insertStickyNotesMation(inputObject, outputObject); + } + + /** + * 查询便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStickyNotesList", value = "查询便签", method = "GET", allUse = "2") + @RequestMapping("/post/StickyNotesController/queryStickyNotesList") + public void queryStickyNotesList(InputObject inputObject, OutputObject outputObject) { + stickyNotesService.queryStickyNotesList(inputObject, outputObject); + } + + /** + * 编辑便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/StickyNotesController/editStickyNotesMation") + public void editStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + stickyNotesService.editStickyNotesMation(inputObject, outputObject); + } + + /** + * 删除便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/StickyNotesController/deleteStickyNotesMation") + public void deleteStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + stickyNotesService.deleteStickyNotesMation(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataBaseController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataBaseController.java new file mode 100644 index 0000000..76dbd35 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataBaseController.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.SysDataBaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SysDataBaseController { + + @Autowired + private SysDataBaseService sysDataBaseService; + + /** + * 获取数据库表名信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataBaseController/querySysDataBaseSelectList") + public void querySysDataBaseSelectList(InputObject inputObject, OutputObject outputObject) { + sysDataBaseService.querySysDataBaseSelectList(inputObject, outputObject); + } + + /** + * 获取数据库表备注信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataBaseController/querySysDataBaseDescSelectList") + public void querySysDataBaseDescSelectList(InputObject inputObject, OutputObject outputObject) { + sysDataBaseService.querySysDataBaseDescSelectList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataSqlController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataSqlController.java new file mode 100644 index 0000000..70ca443 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysDataSqlController.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.SysDataSqlService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SysDataSqlController { + + @Autowired + private SysDataSqlService sysDataSqlService; + + /** + * 获取历史备份列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataSqlController/querySysDataSqlBackupsList") + public void querySysDataSqlBackupsList(InputObject inputObject, OutputObject outputObject) { + sysDataSqlService.querySysDataSqlBackupsList(inputObject, outputObject); + } + + /** + * 获取所有表的列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataSqlController/queryAllTableMationList") + public void queryAllTableMationList(InputObject inputObject, OutputObject outputObject) { + sysDataSqlService.queryAllTableMationList(inputObject, outputObject); + } + + /** + * 开始备份 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataSqlController/insertTableBackUps") + public void insertTableBackUps(InputObject inputObject, OutputObject outputObject) { + sysDataSqlService.insertTableBackUps(inputObject, outputObject); + } + + /** + * 开始还原 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysDataSqlController/insertTableReduction") + public void insertTableReduction(InputObject inputObject, OutputObject outputObject) { + sysDataSqlService.insertTableReduction(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysEveUserStaffCapitalController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysEveUserStaffCapitalController.java new file mode 100644 index 0000000..bdc87c5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysEveUserStaffCapitalController.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.SysEveUserStaffCapitalService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveUserStaffCapitalController + * @Description: 员工非工资型的额外资金结算池控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/4 23:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "未结算资金池相关接口", tags = "未结算资金池相关接口", modelName = "基础模块") +public class SysEveUserStaffCapitalController { + + @Autowired + private SysEveUserStaffCapitalService sysEveUserStaffCapitalService; + + /** + * 新增员工待结算资金池信息(用于定时任务) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "addMonthMoney2StaffCapital", value = "新增员工待结算资金池信息(用于定时任务)", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "companyId", name = "companyId", value = "企业id", required = "required"), + @ApiImplicitParam(id = "departmentId", name = "departmentId", value = "部门id", required = "required"), + @ApiImplicitParam(id = "monthTime", name = "monthTime", value = "指定年月,格式为:yyyy-MM", required = "required"), + @ApiImplicitParam(id = "type", name = "type", value = "该资金来源类型", required = "required,num"), + @ApiImplicitParam(id = "money", name = "money", value = "金额", required = "required")}) + @RequestMapping("/post/SysEveUserStaffCapitalController/addMonthMoney2StaffCapital") + public void addMonthMoney2StaffCapital(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffCapitalService.addMonthMoney2StaffCapital(inputObject, outputObject); + } + + /** + * 根据月份以及部门查询未结算的额外资金 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveUserStaffCapitalController/queryStaffCapitalWaitPayMonthList") + public void queryStaffCapitalWaitPayMonthList(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffCapitalService.queryStaffCapitalWaitPayMonthList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysTAreaController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysTAreaController.java new file mode 100644 index 0000000..0b77341 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/controller/SysTAreaController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.service.SysTAreaService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysTAreaController + * @Description: 行政区划管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/18 23:47 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "行政区划", tags = "行政区划", modelName = "基础模块") +public class SysTAreaController { + + @Autowired + private SysTAreaService sysTAreaService; + + /** + * 获取行政区划列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "systarea001", value = "获取行政区划列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TableSelectInfo.class) + @RequestMapping("/post/SysTAreaController/querySysTAreaList") + public void querySysTAreaList(InputObject inputObject, OutputObject outputObject) { + sysTAreaService.queryList(inputObject, outputObject); + } + + /** + * 根据父id获取子节点信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAreaListByPId", value = "根据父id获取子节点信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "pId", name = "pId", value = "主键id", required = "required")}) + @RequestMapping("/post/SysTAreaController/queryAreaListByPId") + public void queryAreaListByPId(InputObject inputObject, OutputObject outputObject) { + sysTAreaService.queryAreaListByPId(inputObject, outputObject); + } + + /** + * 根据id批量获取节点信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAreaListByIds", value = "根据id批量获取节点信息", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个用逗号隔开", required = "required")}) + @RequestMapping("/post/SysTAreaController/queryAreaListByIds") + public void queryAreaListByIds(InputObject inputObject, OutputObject outputObject) { + sysTAreaService.selectByIds(inputObject, outputObject); + } + + /** + * 查询省市区数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPartAreaList", value = "查询省市区数据", method = "GET", allUse = "2") + @RequestMapping("/post/SysTAreaController/queryPartAreaList") + public void queryPartAreaList(InputObject inputObject, OutputObject outputObject) { + sysTAreaService.queryPartAreaList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CommonDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CommonDao.java new file mode 100644 index 0000000..2ed837c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CommonDao.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface CommonDao { + + int insertCodeModelHistory(List> inBeans); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyChatDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyChatDao.java new file mode 100644 index 0000000..994b64a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyChatDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface CompanyChatDao { + + Map queryUserMineByUserId(Map map); + + List> queryCompanyDepartmentByUserId(Map map); + + List> queryDepartmentUserByDepartId(Map depart); + + List> queryUserGroupByUserId(Map map); + + int editUserSignByUserId(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyTalkGroupDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyTalkGroupDao.java new file mode 100644 index 0000000..76c868a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/CompanyTalkGroupDao.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyTalkGroupDao + * @Description: 群组信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:52 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CompanyTalkGroupDao { + + int insertGroupMation(Map map); + + int insertGroupInviteMation(List> beans); + + int insertMakeGroupUserMation(Map map); + + List> queryGroupInvitationMation(Map map); + + Map queryGroupInvitationMationById(Map map); + + int editAgreeInGroupInvitationMation(Map map); + + int editRefuseInGroupInvitationMation(Map map); + + Map queryGroupMationByGroupId(Map bean); + + List> queryGroupMationList(Map map); + + Map queryInGroupByUserAndGroupId(Map map); + + Map queryInGroupInviteByUserAndGroupId(Map map); + + int insertInGroupInviteByUserAndGroupId(Map map); + + Map queryCreateGroupUserByGroupId(Map map); + + List> queryGroupMemberByGroupId(Map map); + + List> queryGroupMemberByGroupIdAndNotThisUser(Map map); + + int insertPersonToPersonMessage(Map map); + + int insertPersonToGroupMessage(Map map); + + List> queryChatLogByPerToPer(Map map); + + List> queryChatLogByPerToGroup(Map map); + + Map queryGroupCreateIdById(Map map); + + int deleteUserToExitGroup(Map map); + + int editCreateToExitGroup(Map map); + + Map queryGroupStateById(Map map1); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/EditUploadDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/EditUploadDao.java new file mode 100644 index 0000000..7adfb66 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/EditUploadDao.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface EditUploadDao { + + int insertFileImgMation(Map bean); + + List> queryFileImgMation(Map bean); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/ExExplainDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/ExExplainDao.java new file mode 100644 index 0000000..cba1e2e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/ExExplainDao.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.Map; + +public interface ExExplainDao { + + int insertExExplainMation(Map map); + + Map queryExExplainMation(Map map); + + int editExExplainMationById(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/StickyNotesDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/StickyNotesDao.java new file mode 100644 index 0000000..3b19050 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/StickyNotesDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface StickyNotesDao { + + int insertStickyNotesMation(Map map); + + List> selectStickyNotesMation(Map map); + + int editStickyNotesMation(Map map); + + int deleteStickyNotesMation(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataBaseDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataBaseDao.java new file mode 100644 index 0000000..d497cb6 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataBaseDao.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface SysDataBaseDao { + + List> querySysDataBaseSelectList(Map map); + + List> querySysDataBaseDescSelectList(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataSqlDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataSqlDao.java new file mode 100644 index 0000000..d512e30 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysDataSqlDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import java.util.List; +import java.util.Map; + +public interface SysDataSqlDao { + + List> querySysDataSqlBackupsList(Map map); + + List> queryAllTableMationList(Map map); + + Map queryDataSqlVersion(Map map); + + int insertTableBackUps(Map map); + + Map queryDataSqlVersionById(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysEveUserStaffCapitalDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysEveUserStaffCapitalDao.java new file mode 100644 index 0000000..871981b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysEveUserStaffCapitalDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserStaffCapitalDao + * @Description: 员工非工资型的额外资金结算池数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/2 16:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserStaffCapitalDao { + + Map queryStaffCapitalMation(@Param("staffId") String staffId, + @Param("monthTime") String monthTime); + + void insertStaffCapitalMation(Map bean); + + void editStaffCapitalMoneyMation(Map bean); + + List> queryStaffCapitalWaitPayMonthList(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysTAreaDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysTAreaDao.java new file mode 100644 index 0000000..7304586 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/SysTAreaDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.eve.entity.userauth.area.SysTArea; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysTAreaDao + * @Description: 区域管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/11 15:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysTAreaDao extends SkyeyeBaseMapper { + + List> querySysTAreaList(TableSelectInfo selectInfo); + + List> queryAreaListByParentCode(@Param("parentCode") String parentCode); + + List> queryTAreaPhoneList(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/WagesFieldTypeDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/WagesFieldTypeDao.java new file mode 100644 index 0000000..3f5146e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/dao/WagesFieldTypeDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesFieldTypeDao + * @Description: 薪资要素字段 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/8 22:23 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesFieldTypeDao { + + /** + * 获取所有的薪资要素字段,包括启用,禁用,以及删除的要素字段key;相同的key,该SQL语句会根据key进行分组 + * + * @return List> + */ + List> queryAllWagesFieldTypeList(); + + int insertWagesFieldTypeKeyToStaff(@Param("list") List> staff); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/area/SysTArea.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/area/SysTArea.java new file mode 100644 index 0000000..3decae2 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/area/SysTArea.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.userauth.area; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysTArea + * @Description: 区域管理实体类,如果这里的缓存key修改,记得修改rest中的IAreaServiceImpl + * @author: skyeye云系列--卫志强 + * @date: 2022/11/18 23:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("区域管理实体类") +@UniqueField +@RedisCacheField(name = CacheConstants.SYS_TAREA_CACHE_KEY) +@TableName(value = "t_area") +public class SysTArea extends OperatorUserInfo { + + @TableId("id") + @Property("主键id") + private String id; + + @TableField("code_id") + @ApiModelProperty(value = "区域编号", required = "required") + private String codeId; + + @TableField("`name`") + @ApiModelProperty(value = "区域名称", required = "required") + private String name; + + @TableField("parent_code_id") + @ApiModelProperty(value = "所属父区域编号", required = "required") + private String parentCodeId; + + /** + * 区划级别,从0开始 + */ + @TableField("`level`") + private Integer level; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/user/UserTreeQueryDo.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/user/UserTreeQueryDo.java new file mode 100644 index 0000000..6abdef2 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/entity/userauth/user/UserTreeQueryDo.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.userauth.user; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.TableSelectInfo; +import lombok.Data; + +/** + * @ClassName: UserTreeQueryDo + * @Description: 查询用户为树结构的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 19:03 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("查询用户为树结构的实体类") +public class UserTreeQueryDo extends TableSelectInfo { + + @ApiModelProperty(value = "人员列表中是否包含自己--1.包含;其他参数不包含", required = "required,num") + private Integer chooseOrNotMy; + + @ApiModelProperty(value = "人员列表中是否必须绑定邮箱--1.必须;其他参数没必要", required = "required,num") + private Integer chooseOrNotEmail; + + /** + * 人员列表中是否包含自己--1.包含;其他参数不包含 根据chooseOrNotMy参数计算 + */ + private String userId; + + /** + * 人员列表中是否必须绑定邮箱--1.必须;其他参数没必要 根据chooseOrNotEmail参数计算 + */ + private Integer hasEmail; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CommonService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CommonService.java new file mode 100644 index 0000000..35f4e96 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CommonService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CommonService { + + void downloadFileByJsonData(InputObject inputObject, OutputObject outputObject); + + void querySysWinMationById(InputObject inputObject, OutputObject outputObject); + + void queryFilePathByFileType(InputObject inputObject, OutputObject outputObject); + + void queryInterfaceIsTrueOrNot(InputObject inputObject, OutputObject outputObject); + + void queryInterfaceValue(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyChatService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyChatService.java new file mode 100644 index 0000000..8335e34 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyChatService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CompanyChatService { + + void getList(InputObject inputObject, OutputObject outputObject); + + void editUserSignByUserId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyTalkGroupService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyTalkGroupService.java new file mode 100644 index 0000000..11b4106 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/CompanyTalkGroupService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface CompanyTalkGroupService { + + void insertGroupMation(InputObject inputObject, OutputObject outputObject); + + void queryGroupInvitationMation(InputObject inputObject, OutputObject outputObject); + + void editAgreeInGroupInvitationMation(InputObject inputObject, OutputObject outputObject); + + void editRefuseInGroupInvitationMation(InputObject inputObject, OutputObject outputObject); + + void queryGroupMationList(InputObject inputObject, OutputObject outputObject); + + void insertGroupMationToTalk(InputObject inputObject, OutputObject outputObject); + + void queryGroupMemberByGroupId(InputObject inputObject, OutputObject outputObject); + + void queryChatLogByType(InputObject inputObject, OutputObject outputObject); + + void editUserToExitGroup(InputObject inputObject, OutputObject outputObject); + + void editCreateToExitGroup(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/ExExplainService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/ExExplainService.java new file mode 100644 index 0000000..3e64115 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/ExExplainService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface ExExplainService { + + void insertExExplainMation(InputObject inputObject, OutputObject outputObject); + + void queryExExplainMation(InputObject inputObject, OutputObject outputObject); + + void editExExplainMationById(InputObject inputObject, OutputObject outputObject); + + void queryExExplainMationToShow(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/StickyNotesService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/StickyNotesService.java new file mode 100644 index 0000000..f5d9745 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/StickyNotesService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface StickyNotesService { + + void insertStickyNotesMation(InputObject inputObject, OutputObject outputObject); + + void queryStickyNotesList(InputObject inputObject, OutputObject outputObject); + + void editStickyNotesMation(InputObject inputObject, OutputObject outputObject); + + void deleteStickyNotesMation(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataBaseService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataBaseService.java new file mode 100644 index 0000000..00ec2ab --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataBaseService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface SysDataBaseService { + + void querySysDataBaseSelectList(InputObject inputObject, OutputObject outputObject); + + void querySysDataBaseDescSelectList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataSqlService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataSqlService.java new file mode 100644 index 0000000..a3b29b5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysDataSqlService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface SysDataSqlService { + + void querySysDataSqlBackupsList(InputObject inputObject, OutputObject outputObject); + + void queryAllTableMationList(InputObject inputObject, OutputObject outputObject); + + void insertTableBackUps(InputObject inputObject, OutputObject outputObject); + + void insertTableReduction(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysEveUserStaffCapitalService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysEveUserStaffCapitalService.java new file mode 100644 index 0000000..aad2a57 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysEveUserStaffCapitalService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: SysEveUserStaffCapitalService + * @Description: 员工非工资型的额外资金结算池服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/2 16:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserStaffCapitalService { + + void addMonthMoney2StaffCapital(InputObject inputObject, OutputObject outputObject); + + /** + * 新增员工待结算资金池信息 + * + * @param staffId 员工id + * @param companyId 企业id + * @param departmentId 部门id + * @param monthTime 指定年月,格式为:yyyy-MM + * @param type 该资金来源类型 + * @param money 金额 + */ + void addMonthMoney2StaffCapital(String staffId, String companyId, String departmentId, String monthTime, int type, String money); + + void queryStaffCapitalWaitPayMonthList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysTAreaService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysTAreaService.java new file mode 100644 index 0000000..98285c4 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/SysTAreaService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.userauth.area.SysTArea; + +/** + * @ClassName: SysTAreaService + * @Description: 区域管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/11 15:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysTAreaService extends SkyeyeBusinessService { + + void queryAreaListByPId(InputObject inputObject, OutputObject outputObject); + + void queryPartAreaList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CommonServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..826e4e4 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CommonServiceImpl.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.HttpClient; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CommonDao; +import com.skyeye.eve.service.CommonService; +import com.skyeye.exception.CustomException; +import com.skyeye.win.entity.SysEveWinBgPic; +import com.skyeye.win.entity.SysEveWinLockBgPic; +import com.skyeye.win.entity.SysEveWinThemeColor; +import com.skyeye.win.service.SysEveWinBgPicService; +import com.skyeye.win.service.SysEveWinLockBgPicService; +import com.skyeye.win.service.SysEveWinThemeColorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * @ClassName: CommonServiceImpl + * @Description: 公共类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/4 17:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CommonServiceImpl implements CommonService { + + @Autowired + private CommonDao commonDao; + + @Autowired + private SysEveWinBgPicService sysEveWinBgPicService; + + @Autowired + private SysEveWinLockBgPicService sysEveWinLockBgPicService; + + @Autowired + private SysEveWinThemeColorService sysEveWinThemeColorService; + + @Value("${IMAGES_PATH}") + private String tPath; + + /** + * 代码生成器生成下载文件 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void downloadFileByJsonData(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> array = JSONUtil.toList(map.get("jsonData").toString(), null); + List> inBeans = new ArrayList<>(); + Map user = inputObject.getLogParams(); + String zipName = ToolUtil.getSurFaceId() + ".zip"; + String basePath = tPath + FileConstants.FileUploadPath.CODE_GENERATOR.getSavePath(); + FileUtil.createDirs(basePath); + String strZipPath = tPath + FileConstants.FileUploadPath.CODE_GENERATOR.getSavePath() + "/" + zipName; + ZipOutputStream out = null; + try { + out = new ZipOutputStream(new FileOutputStream(strZipPath)); + byte[] buffer = new byte[1024]; + + for (int i = 0; i < array.size(); i++) { + JSONObject object = (JSONObject) array.get(i); + String content = object.getStr("content"); + // 加入压缩包 + ByteArrayInputStream stream = new ByteArrayInputStream(content.getBytes()); + if ("javascript".equals(object.getStr("modelType").toLowerCase())) { + out.putNextEntry(new ZipEntry(object.getStr("fileName") + ".js")); + } else { + out.putNextEntry(new ZipEntry(object.getStr("fileName") + "." + object.getStr("modelType").toLowerCase())); + } + int len; + // 读入需要下载的文件的内容,打包到zip文件 + while ((len = stream.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + out.closeEntry(); + Map bean = getCodeModelHoitoryObject(user, zipName, object, content); + inBeans.add(bean); + } + } catch (Exception ex) { + throw new CustomException(ex); + } finally { + FileUtil.close(out); + } + commonDao.insertCodeModelHistory(inBeans); + } + + private Map getCodeModelHoitoryObject(Map user, String zipName, JSONObject object, String content) { + Map bean = new HashMap<>(); + bean.put("tableName", object.getStr("tableName")); + bean.put("groupId", object.getStr("groupId")); + bean.put("modelId", object.getStr("modelId")); + bean.put("content", content); + bean.put("fileName", object.getStr("fileName")); + if ("javascript".equals(object.getStr("modelType").toLowerCase())) { + bean.put("fileType", "js"); + } else { + bean.put("fileType", object.getStr("modelType").toLowerCase()); + } + bean.put("filePath", zipName); + DataCommonUtil.setCommonData(bean, user.get("id").toString()); + return bean; + } + + /** + * 获取win系统桌列表信息供展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysWinMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + + // 获取win系统桌面图片列表供展示 + List winBgPic = sysEveWinBgPicService.querySystemSysEveWinBgPicList(); + + // 获取win系统锁屏桌面图片列表供展示 + List winLockBgPic = sysEveWinLockBgPicService.querySystemSysEveWinLockBgPicList(); + + // 获取win系统主题颜色列表供展示 + List winThemeColor = sysEveWinThemeColorService.querySysEveWinThemeColorList(); + + map.put("winBgPic", winBgPic); + map.put("winLockBgPic", winLockBgPic); + map.put("winThemeColor", winThemeColor); + outputObject.setBean(map); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据文件类型获取文件的保存地址以及访问地址 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryFilePathByFileType(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Integer fileType = Integer.parseInt(map.get("fileType").toString()); + String savePath = tPath + FileConstants.FileUploadPath.getSavePath(fileType); + FileUtil.createDirs(savePath); + String visitPath = FileConstants.FileUploadPath.getVisitPath(fileType); + + Map result = new HashMap<>(); + result.put("savePath", savePath); + result.put("visitPath", visitPath); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 验证接口是否正确 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInterfaceIsTrueOrNot(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("loginPCIp", PutObject.getRequest().getParameter("loginPCIp")); + map.put("userToken", PutObject.getRequest().getParameter("userToken")); + String str = HttpClient.doPost(map.get("interfa").toString(), map); + if (!ToolUtil.isBlank(str)) { + if (ToolUtil.isJson(str)) { + Map json = JSONUtil.toBean(str, null); + if ("0".equals(json.get("returnCode").toString())) { + if (!ToolUtil.isBlank(json.get("rows").toString())) { + map.put("aData", json.get("rows").toString()); + outputObject.setBean(map); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } else { + outputObject.setreturnMessage("该接口没有拿到数据,请重新填写接口!"); + } + } else { + outputObject.setreturnMessage("该接口无效,请重新填写接口!"); + } + } else { + outputObject.setreturnMessage("接口拿到的不是json串,请重新填写接口!"); + } + } else { + outputObject.setreturnMessage("该接口无效,请重新填写接口!"); + } + } + + /** + * 获取接口中的值 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryInterfaceValue(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("loginPCIp", PutObject.getRequest().getParameter("loginPCIp")); + map.put("userToken", PutObject.getRequest().getParameter("userToken")); + String str = HttpClient.doPost(map.get("interfa").toString(), map); + Map json = JSONUtil.toBean(str, null); + map.put("aData", json.get("rows").toString()); + outputObject.setBean(map); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyChatServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyChatServiceImpl.java new file mode 100644 index 0000000..ecd3df6 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyChatServiceImpl.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CompanyChatDao; +import com.skyeye.eve.service.CompanyChatService; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.organization.service.ICompanyJobService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import com.skyeye.websocket.TalkWebSocket; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Service +public class CompanyChatServiceImpl implements CompanyChatService { + + @Autowired + private CompanyChatDao companyChatDao; + + @Autowired + private JedisClientService jedisService; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Autowired + private ICompanyJobService iCompanyJobService; + + /** + * 获取好友列表,群聊信息,个人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + map.put("userId", userId); + //获取个人信息 + Map mine = null; + if (ToolUtil.isBlank(jedisService.get(Constants.getSysTalkUserThisMainMationById(userId)))) { + mine = companyChatDao.queryUserMineByUserId(map); + iCompanyService.setNameForMap(mine, "companyId", "companyName"); + iDepmentService.setNameForMap(mine, "departmentId", "departmentName"); + jedisService.set(Constants.getSysTalkUserThisMainMationById(userId), JSONUtil.toJsonStr(mine)); + } else { + mine = JSONUtil.toBean(jedisService.get(Constants.getSysTalkUserThisMainMationById(userId)), null); + } + + //获取聊天组 + List> group = null; + if (ToolUtil.isBlank(jedisService.get(Constants.getSysTalkUserHasGroupListMationById(userId)))) { + group = companyChatDao.queryUserGroupByUserId(map); + jedisService.set(Constants.getSysTalkUserHasGroupListMationById(userId), JSONUtil.toJsonStr(group)); + } else { + group = JSONUtil.toList(jedisService.get(Constants.getSysTalkUserHasGroupListMationById(userId)), null); + } + + //获取公司单位 + List> companyDepartment = companyChatDao.queryCompanyDepartmentByUserId(map); + + //循环获取分组的人列表 + for (Map depart : companyDepartment) { + List> userList = null; + if (ToolUtil.isBlank(jedisService.get(Constants.getSysTalkGroupUserListMationById(depart.get("id").toString() + "_" + userId)))) { + depart.put("notUserId", CommonConstants.ADMIN_USER_ID); + userList = companyChatDao.queryDepartmentUserByDepartId(depart); + iCompanyService.setNameForMap(userList, "companyId", "companyName"); + iDepmentService.setNameForMap(userList, "departmentId", "departmentName"); + iCompanyJobService.setNameForMap(userList, "jobId", "jobName"); + jedisService.set(Constants.getSysTalkGroupUserListMationById(depart.get("id").toString() + "_" + userId), JSONUtil.toJsonStr(userList)); + } else { + userList = JSONUtil.toList(jedisService.get(Constants.getSysTalkGroupUserListMationById(depart.get("id").toString() + "_" + userId)), null); + } + if (CollectionUtil.isNotEmpty(userList)) { + Set uId = TalkWebSocket.getOnlineUserId(); + for (Map u : userList) { + if (uId.contains(u.get("id").toString())) { + u.put("status", "online"); + } else { + u.put("status", "offline"); + } + } + } + depart.put("list", userList); + } + map.clear(); + map.put("friend", companyDepartment); + map.put("group", group); + map.put("mine", mine); + outputObject.setBean(map); + } + + /** + * 编辑签名 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editUserSignByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + companyChatDao.editUserSignByUserId(map); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyTalkGroupServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyTalkGroupServiceImpl.java new file mode 100644 index 0000000..f46947b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/CompanyTalkGroupServiceImpl.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONUtil; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CompanyTalkGroupDao; +import com.skyeye.eve.service.CompanyTalkGroupService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyTalkGroupServiceImpl + * @Description: 群组信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class CompanyTalkGroupServiceImpl implements CompanyTalkGroupService { + + @Autowired + private CompanyTalkGroupDao companyTalkGroupDao; + + @Autowired + private JedisClientService jedisService; + + /** + * 添加群组信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertGroupMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String[] invites = map.get("userIds").toString().split(","); + if (invites.length > 0) { + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + DataCommonUtil.setCommonData(map, userId); + // 插入群组信息 + String id = map.get("id").toString();//群组id + map.put("groupUserNum", 200);//默认每个群组的人数最多200人 + map.put("state", 1);//群状态,正常 + map.put("groupNum", ToolUtil.getTalkGroupNum());//群号 + map.put("groupHistroyImg", map.get("groupImg").toString() + ",");//群历史logo + companyTalkGroupDao.insertGroupMation(map); + //插入被邀请人信息 + List> inviteBeans = new ArrayList<>(); + for (String str : invites) { + if (!ToolUtil.isBlank(str)) { + Map inviteBean = new HashMap<>(); + inviteBean.put("inviteUserId", str);//被邀请人id + inviteBean.put("groupId", id);//群组id + inviteBean.put("state", 0);//等待查看 + inviteBean.put("inGroupType", 1);//进群方式 1被邀请进群 + DataCommonUtil.setCommonData(inviteBean, userId); + inviteBeans.add(inviteBean); + } + } + companyTalkGroupDao.insertGroupInviteMation(inviteBeans); + // 插入创建人入群数据 + Map groupUser = new HashMap<>(); + groupUser.put("id", ToolUtil.getSurFaceId()); + groupUser.put("userId", userId); + groupUser.put("groupId", id); + groupUser.put("createTime", DateUtil.getTimeAndToString()); + companyTalkGroupDao.insertMakeGroupUserMation(groupUser); + // 删除该用户在redis中存储的群组列表信息 + jedisService.del(Constants.getSysTalkUserHasGroupListMationById(userId)); + outputObject.setBean(map); + } else { + outputObject.setreturnMessage("群组中最少拥有两名成员。"); + } + } + + /** + * 获取邀请信息/入群信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = companyTalkGroupDao.queryGroupInvitationMation(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 同意入群 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editAgreeInGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + Map bean = companyTalkGroupDao.queryGroupInvitationMationById(map); + if ("0".equals(bean.get("state").toString())) {//未查看等待审核 + if (user.get("id").toString().equals(bean.get("inviteUserId").toString())) {//当前审批人和设定的审批人一致 + map.put("userId", user.get("id")); + companyTalkGroupDao.editAgreeInGroupInvitationMation(map); + Map createGroupUser = companyTalkGroupDao.queryCreateGroupUserByGroupId(bean);//获取创建该群聊的用户id和人数作比较 + if (Integer.parseInt(createGroupUser.get("groupUserNum").toString()) + > Integer.parseInt(createGroupUser.get("newGroupNum").toString())) {//当前群聊人数小于总人数限制 + //插入入群数据 + Map groupUser = new HashMap<>(); + groupUser.put("id", ToolUtil.getSurFaceId()); + if ("1".equals(bean.get("inGroupType").toString())) {//被邀请进群 + groupUser.put("userId", user.get("id")); + } else if ("2".equals(bean.get("inGroupType").toString())) {//搜索账号进群 + groupUser.put("userId", bean.get("createId")); + } + jedisService.del(Constants.checkSysEveTalkGroupUserListByGroupId(bean.get("groupId").toString()));//删除群组成员缓存 + jedisService.del(Constants.getSysTalkUserHasGroupListMationById(groupUser.get("userId").toString()));//删除该用户在redis中存储的群组列表信息 + groupUser.put("groupId", bean.get("groupId")); + groupUser.put("createTime", DateUtil.getTimeAndToString()); + companyTalkGroupDao.insertMakeGroupUserMation(groupUser); + Map groupMation = companyTalkGroupDao.queryGroupMationByGroupId(bean); + groupMation.put("inGroupType", bean.get("inGroupType"));//进群方式 1.被邀请进群 2.搜索账号进群 + groupMation.put("userId", groupUser.get("userId")); + outputObject.setBean(groupMation); + } else { + outputObject.setreturnMessage("该群聊人数已满。"); + } + } else { + outputObject.setreturnMessage("该数据不在您的审批范围内。"); + } + } else { + outputObject.setreturnMessage("该数据已被操作,请刷新页面。"); + } + } + + /** + * 拒绝入群 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editRefuseInGroupInvitationMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + Map bean = companyTalkGroupDao.queryGroupInvitationMationById(map); + if ("0".equals(bean.get("state").toString())) {//未查看等待审核 + if (user.get("id").toString().equals(bean.get("inviteUserId").toString())) {//当前审批人和设定的审批人一致 + map.put("userId", user.get("id")); + companyTalkGroupDao.editRefuseInGroupInvitationMation(map); + } else { + outputObject.setreturnMessage("该数据不在您的审批范围内。"); + } + } else { + outputObject.setreturnMessage("该数据已被操作,请刷新页面。"); + } + } + + /** + * 搜索群组列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryGroupMationList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = companyTalkGroupDao.queryGroupMationList(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 申请加入群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertGroupMationToTalk(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Map inGroup = companyTalkGroupDao.queryInGroupByUserAndGroupId(map);//判断是否已在该群聊 + if (CollectionUtils.isEmpty(inGroup)) { + Map inGroupInvite = companyTalkGroupDao.queryInGroupInviteByUserAndGroupId(map);//判断是否有该用户的未审批的群聊申请信息 + if (CollectionUtils.isEmpty(inGroupInvite)) { + Map createGroupUser = companyTalkGroupDao.queryCreateGroupUserByGroupId(map);//获取创建该群聊的用户id和人数作比较 + if (Integer.parseInt(createGroupUser.get("groupUserNum").toString()) + > Integer.parseInt(createGroupUser.get("newGroupNum").toString())) {//当前群聊人数小于总人数限制 + Map inviteBean = new HashMap<>(); + inviteBean.put("inviteUserId", createGroupUser.get("createId"));//审批人id + inviteBean.put("groupId", map.get("groupId"));//群组id + inviteBean.put("state", 0);//等待查看 + inviteBean.put("inGroupType", 2);//进群方式 2搜索账号进群 + DataCommonUtil.setCommonData(inviteBean, inputObject.getLogParams().get("id").toString()); + companyTalkGroupDao.insertInGroupInviteByUserAndGroupId(inviteBean); + outputObject.setBean(inviteBean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } else { + outputObject.setreturnMessage("该群聊人数已满。"); + } + } + } else { + outputObject.setreturnMessage("您已在该群聊。"); + } + } + + /** + * 获取群成员 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryGroupMemberByGroupId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = new ArrayList<>(); + String groupId = map.get("id").toString(); + if (ToolUtil.isBlank(jedisService.get(Constants.checkSysEveTalkGroupUserListByGroupId(groupId)))) { + beans = companyTalkGroupDao.queryGroupMemberByGroupId(map);//获取群成员 + jedisService.set(Constants.checkSysEveTalkGroupUserListByGroupId(groupId), JSONUtil.toJsonStr(beans)); + } else { + beans = JSONUtil.toList(jedisService.get(Constants.checkSysEveTalkGroupUserListByGroupId(groupId)).toString(), null); + } + map.clear(); + map.put("members", beans.size()); + map.put("list", beans); + outputObject.setBean(map); + } + + /** + * 获取聊天记录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryChatLogByType(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + if ("friend".equals(map.get("chatType").toString())) {//个人对个人 + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = companyTalkGroupDao.queryChatLogByPerToPer(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } else if ("group".equals(map.get("chatType").toString())) {//个人对群组 + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = companyTalkGroupDao.queryChatLogByPerToGroup(map); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } else { + outputObject.setreturnMessage("参数错误"); + } + } + + /** + * 退出群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editUserToExitGroup(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map groupMation = companyTalkGroupDao.queryGroupCreateIdById(map); + if (!CollectionUtils.isEmpty(groupMation)) { + Map user = inputObject.getLogParams(); + if (!user.get("id").toString().equals(groupMation.get("createId").toString())) {//退群的人不是群创建人,允许退群 + map.put("userId", user.get("id")); + companyTalkGroupDao.deleteUserToExitGroup(map); + jedisService.del(Constants.checkSysEveTalkGroupUserListByGroupId(map.get("groupId").toString()));//删除群组成员缓存 + jedisService.del(Constants.getSysTalkUserHasGroupListMationById(user.get("id").toString()));//删除该用户在redis中存储的群组列表信息 + } else { + outputObject.setreturnMessage("您是该群聊的创建人,无法退群,请进行解散群聊操作。"); + } + } else { + outputObject.setreturnMessage("群信息不存在,请核实后进行操作。"); + } + } + + /** + * 解散群聊 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editCreateToExitGroup(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map groupMation = companyTalkGroupDao.queryGroupCreateIdById(map); + if (!CollectionUtils.isEmpty(groupMation)) { + Map user = inputObject.getLogParams(); + if (user.get("id").toString().equals(groupMation.get("createId").toString())) {//退群的人是群创建人,允许解散群 + List> list = companyTalkGroupDao.queryGroupMemberByGroupId(map);//获取群成员 + for (Map bean : list) { + jedisService.del(Constants.getSysTalkUserHasGroupListMationById(bean.get("id").toString()));//删除该用户在redis中存储的群组列表信息 + } + jedisService.del(Constants.checkSysEveTalkGroupUserListByGroupId(map.get("groupId").toString()));//删除群组成员缓存 + jedisService.del(Constants.getSysTalkUserHasGroupListMationById(user.get("id").toString()));//删除该用户在redis中存储的群组列表信息 + map.put("userId", user.get("id")); + companyTalkGroupDao.editCreateToExitGroup(map); + } else { + outputObject.setreturnMessage("您不是该群聊的创建人,无法解散,请进行退出群聊操作。"); + } + } else { + outputObject.setreturnMessage("群信息不存在,请核实后进行操作。"); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/ExExplainServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/ExExplainServiceImpl.java new file mode 100644 index 0000000..d1bb995 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/ExExplainServiceImpl.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.ExExplainDao; +import com.skyeye.eve.service.ExExplainService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.Map; + +@Service +public class ExExplainServiceImpl implements ExExplainService { + + @Autowired + private ExExplainDao exExplainDao; + + @Autowired + public JedisClientService jedisClient; + + /** + * 添加使用说明信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertExExplainMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = exExplainDao.queryExExplainMation(map); + if (bean == null) { + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + exExplainDao.insertExExplainMation(map); + Integer type = Integer.parseInt(map.get("type").toString()); + jedisClient.del(Constants.getSysExplainExexplainRedisKey(type)); + bean = new HashMap<>(); + bean.put("id", map.get("id").toString()); + outputObject.setBean(bean); + } else { + outputObject.setreturnMessage("该代码生成器说明已存在,不可进行二次保存"); + } + } + + /** + * 编辑使用说明信息时进行回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryExExplainMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = exExplainDao.queryExExplainMation(map); + outputObject.setBean(bean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 编辑使用说明信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editExExplainMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = exExplainDao.queryExExplainMation(map); + if (bean == null) { + outputObject.setreturnMessage("该代码生成器说明不存在,不可进行编辑"); + } else { + Integer type = Integer.parseInt(map.get("type").toString()); + jedisClient.del(Constants.getSysExplainExexplainRedisKey(type)); + exExplainDao.editExExplainMationById(map); + } + } + + /** + * 获取使用说明信息供展示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryExExplainMationToShow(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Integer type = Integer.parseInt(map.get("type").toString()); + String key = Constants.getSysExplainExexplainRedisKey(type); + if (jedisClient.exists(key)) { + map = JSONUtil.toBean(jedisClient.get(key), null); + } else { + Map bean = exExplainDao.queryExExplainMation(map); + if (bean == null) { + map.put("title", "标题"); + map.put("content", "等待发布说明。"); + } else { + jedisClient.set(key, JSONUtil.toJsonStr(bean)); + map = bean; + } + } + outputObject.setBean(map); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/StickyNotesServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/StickyNotesServiceImpl.java new file mode 100644 index 0000000..53b0e7f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/StickyNotesServiceImpl.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.eve.dao.StickyNotesDao; +import com.skyeye.eve.service.StickyNotesService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +public class StickyNotesServiceImpl implements StickyNotesService { + + @Autowired + private StickyNotesDao stickyNotesDao; + + /** + * 新增便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + stickyNotesDao.insertStickyNotesMation(map); + outputObject.setBean(map); + } + + /** + * 查询便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStickyNotesList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("createId", inputObject.getLogParams().get("id")); + List> beans = stickyNotesDao.selectStickyNotesMation(map); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 编辑便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + stickyNotesDao.editStickyNotesMation(map); + } + + /** + * 删除便签 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteStickyNotesMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + stickyNotesDao.deleteStickyNotesMation(map); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataBaseServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataBaseServiceImpl.java new file mode 100644 index 0000000..e486617 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataBaseServiceImpl.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.dao.SysDataBaseDao; +import com.skyeye.eve.service.SysDataBaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public class SysDataBaseServiceImpl implements SysDataBaseService { + + @Autowired + private SysDataBaseDao sysDataBaseDao; + + @Value("${jdbc.database.name}") + private String dbName; + + /** + * 获取数据库表名信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysDataBaseSelectList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("dbName", dbName); + List> beans = sysDataBaseDao.querySysDataBaseSelectList(map); + outputObject.setBeans(beans); + if (!beans.isEmpty()) { + outputObject.settotal(beans.size()); + } + } + + /** + * 获取数据库表备注信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysDataBaseDescSelectList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("dbName", dbName); + List> beans = sysDataBaseDao.querySysDataBaseDescSelectList(map); + outputObject.setBeans(beans); + if (!beans.isEmpty()) { + outputObject.settotal(beans.size()); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataSqlServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataSqlServiceImpl.java new file mode 100644 index 0000000..29b4b44 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysDataSqlServiceImpl.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.*; +import com.skyeye.eve.dao.SysDataSqlDao; +import com.skyeye.eve.service.SysDataSqlService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.*; +import java.util.List; +import java.util.Map; + +@Service +public class SysDataSqlServiceImpl implements SysDataSqlService { + + @Autowired + private SysDataSqlDao sysDataSqlDao; + + @Value("${jdbc.database.name}") + private String dbName; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Value("${MYSQL_DUMP}") + private String mysqlDump; + + @Value("${jdbc.database.username}") + private String userName; + + @Value("${jdbc.database.password}") + private String password; + + @Value("${jdbc.database.name}") + private String databaseName; + + @Value("${jdbc.database.address}") + private String address; + + /** + * 获取历史备份列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysDataSqlBackupsList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = sysDataSqlDao.querySysDataSqlBackupsList(map); + for (Map bean : beans) { + bean.put("fileSize", BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("fileSize").toString()))); + } + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取所有表的列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllTableMationList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + map.put("dbName", dbName); + List> beans = sysDataSqlDao.queryAllTableMationList(map); + for (Map bean : beans) { + bean.put("tableSize", BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("tableSize").toString())));//数据大小 + bean.put("indexSize", BytesUtil.sizeFormatNum2String(Long.parseLong(bean.get("indexSize").toString())));//索引大小 + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 开始备份 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertTableBackUps(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map version = sysDataSqlDao.queryDataSqlVersion(map); + String basePath = tPath + "\\upload\\datasql"; + FileUtil.createDirs(basePath); + String newFileName = String.valueOf(System.currentTimeMillis()) + ".sql"; + String path = basePath + "\\" + newFileName;//文件存储地址 + //拼接命令行的命令 + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(mysqlDump + "/mysqldump").append(" --opt").append(" -h").append(address); + stringBuilder.append(" --user=").append(userName).append(" --password=").append(password).append(" --lock-all-tables=true"); + stringBuilder.append(" --result-file=").append(path).append(" --default-character-set=utf8 ").append(databaseName); + // 调用外部执行exe文件的javaAPI + try { + Process process = Runtime.getRuntime().exec(stringBuilder.toString()); + if (process.waitFor() == 0) {// 0 表示线程正常终止。 + System.out.println("执行完毕"); + //保存到数据库 + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + map.put("mysqlVersion", version.get("version"));//数据库版本 + String filePath = "/images/upload/datasql/" + newFileName; + map.put("filePath", filePath);//文件存储地址 + IdWorker id = new IdWorker(); + String sqlVersion = String.valueOf(id.nextId()); + map.put("sqlVersion", sqlVersion);//备份版本 + map.put("sqlTitle", "数据库备份_" + sqlVersion);//备份标题 + File sqlFile = new File(path); + map.put("fileSize", sqlFile.length()); + sysDataSqlDao.insertTableBackUps(map); + } + } catch (Exception ex) { + throw new CustomException(ex); + } + } + + /** + * 开始还原 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertTableReduction(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = sysDataSqlDao.queryDataSqlVersionById(map); + if (bean != null && !bean.isEmpty()) { + String basePath = tPath.replace("images", ""); + String filePath = bean.get("filePath").toString(); + File file = new File(basePath + filePath); + // 数据库备份文件存在 + if (file.exists()) { + OutputStream outputStream = null; + BufferedReader br = null; + OutputStreamWriter writer = null; + try { + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(mysqlDump + "mysql.exe -h" + address + " -u" + userName + " -p" + password + " --default-character-set=utf8 " + databaseName); + outputStream = process.getOutputStream(); + br = new BufferedReader(new InputStreamReader(new FileInputStream(basePath + filePath), "utf-8")); + String str = null; + StringBuffer sb = new StringBuffer(); + while ((str = br.readLine()) != null) { + sb.append(str + "\r\n"); + } + str = sb.toString(); + writer = new OutputStreamWriter(outputStream, "utf-8"); + writer.write(str); + writer.flush(); + } catch (IOException ex) { + throw new CustomException(ex); + } finally { + FileUtil.close(outputStream); + FileUtil.close(br); + FileUtil.close(writer); + } + } else { + outputObject.setreturnMessage("该备份文件已不存在。"); + } + } else { + outputObject.setreturnMessage("该备份信息已不存在。"); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysEveUserStaffCapitalServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysEveUserStaffCapitalServiceImpl.java new file mode 100644 index 0000000..6431194 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysEveUserStaffCapitalServiceImpl.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.SysEveUserStaffCapitalDao; +import com.skyeye.eve.service.SysEveUserStaffCapitalService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserStaffCapitalServiceImpl + * @Description: 员工非工资型的额外资金结算池服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/2 16:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SysEveUserStaffCapitalServiceImpl implements SysEveUserStaffCapitalService { + + @Autowired + private SysEveUserStaffCapitalDao sysEveUserStaffCapitalDao; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + /** + * 新增员工待结算资金池信息(用于定时任务) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void addMonthMoney2StaffCapital(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String companyId = map.get("companyId").toString(); + String departmentId = map.get("departmentId").toString(); + String monthTime = map.get("monthTime").toString(); + Integer type = Integer.parseInt(map.get("type").toString()); + String money = map.get("money").toString(); + this.addMonthMoney2StaffCapital(staffId, companyId, departmentId, monthTime, type, money); + } + + /** + * 新增员工待结算资金池信息 + * + * @param staffId 员工id + * @param companyId 企业id + * @param departmentId 部门id + * @param monthTime 指定年月,格式为:yyyy-MM + * @param type 该资金来源类型 + * @param money 金额 + */ + @Override + public void addMonthMoney2StaffCapital(String staffId, String companyId, String departmentId, String monthTime, int type, String money) { + synchronized (staffId) { + Map staffCapital = sysEveUserStaffCapitalDao.queryStaffCapitalMation(staffId, monthTime); + if (staffCapital == null || staffCapital.isEmpty()) { + staffCapital = setStaffCapitalMation(staffId, companyId, departmentId, monthTime, type, money); + sysEveUserStaffCapitalDao.insertStaffCapitalMation(staffCapital); + } else { + String oldMoney = staffCapital.get("money").toString(); + String newMoney = CalculationUtil.add(oldMoney, money, 2); + staffCapital.put("money", newMoney); + sysEveUserStaffCapitalDao.editStaffCapitalMoneyMation(staffCapital); + } + } + } + + private Map setStaffCapitalMation(String staffId, String companyId, String departmentId, String monthTime, int type, String money) { + Map staffCapital = new HashMap<>(); + staffCapital.put("id", ToolUtil.getSurFaceId()); + staffCapital.put("staffId", staffId); + staffCapital.put("companyId", companyId); + staffCapital.put("departmentId", departmentId); + staffCapital.put("monthTime", monthTime); + staffCapital.put("money", money); + staffCapital.put("type", type); + // 状态 1.待结算 2.批准在某月工资发放日结算 3.已结算 + staffCapital.put("state", 1); + staffCapital.put("createTime", DateUtil.getTimeAndToString()); + return staffCapital; + } + + /** + * 根据月份以及部门查询未结算的额外资金 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStaffCapitalWaitPayMonthList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Page pages = PageHelper.startPage(Integer.parseInt(map.get("page").toString()), Integer.parseInt(map.get("limit").toString())); + List> beans = sysEveUserStaffCapitalDao.queryStaffCapitalWaitPayMonthList(map); + iCompanyService.setNameForMap(beans, "companyId", "companyName"); + iDepmentService.setNameForMap(beans, "departmentId", "departmentName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysTAreaServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysTAreaServiceImpl.java new file mode 100644 index 0000000..5e7e536 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/eve/service/impl/SysTAreaServiceImpl.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.service.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.SysTAreaDao; +import com.skyeye.eve.entity.userauth.area.SysTArea; +import com.skyeye.eve.service.SysTAreaService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysTAreaServiceImpl + * @Description: 区域管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/18 23:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class SysTAreaServiceImpl extends SkyeyeBusinessServiceImpl implements SysTAreaService { + + public static String SYS_ALL_T_AREA_LIST = "sys_all_t_area_list"; + + @Override + public List> queryDataList(InputObject inputObject) { + TableSelectInfo selectInfo = inputObject.getParams(TableSelectInfo.class); + return skyeyeBaseMapper.querySysTAreaList(selectInfo); + } + + /** + * 根据父id获取子节点信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAreaListByPId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String pId = map.get("pId").toString(); + String parentCode = "0"; + if (!StringUtils.equals("0", pId)) { + // 如果父ID不是0,则查询的不是一级节点,则需要先获取编码code + SysTArea sysTArea = selectById(pId); + parentCode = sysTArea.getCodeId(); + } + List> beans = skyeyeBaseMapper.queryAreaListByParentCode(parentCode); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 查询省市区数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPartAreaList(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans; + if (ToolUtil.isBlank(jedisClientService.get(SYS_ALL_T_AREA_LIST))) { + beans = skyeyeBaseMapper.queryTAreaPhoneList(map); + beans = ToolUtil.listToTree(beans, "codeId", "parentCodeId", "children"); + jedisClientService.set(SYS_ALL_T_AREA_LIST, JSONUtil.toJsonStr(beans)); + } else { + beans = JSONUtil.toList(jedisClientService.get(SYS_ALL_T_AREA_LIST), null); + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/controller/SysEveIconController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/controller/SysEveIconController.java new file mode 100644 index 0000000..5bd5147 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/controller/SysEveIconController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.icon.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.icon.entity.SysEveIcon; +import com.skyeye.icon.service.SysEveIconService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveIconController + * @Description: 系统icon库控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 21:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "系统icon库", tags = "系统icon库", modelName = "系统icon库") +public class SysEveIconController { + + @Autowired + private SysEveIconService sysEveIconService; + + /** + * 获取ICON列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysIconList", value = "获取ICON列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveIconController/querySysIconList") + public void querySysIconList(InputObject inputObject, OutputObject outputObject) { + sysEveIconService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑ICON信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysIcon", value = "新增/编辑ICON信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysEveIcon.class) + @RequestMapping("/post/SysEveIconController/writeSysIcon") + public void writeSysIcon(InputObject inputObject, OutputObject outputObject) { + sysEveIconService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询icon信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysIconById", value = "根据id查询icon信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveIconController/querySysIconById") + public void querySysIconById(InputObject inputObject, OutputObject outputObject) { + sysEveIconService.selectById(inputObject, outputObject); + } + + /** + * 删除ICON信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSysIconById", value = "删除ICON信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveIconController/deleteSysIconById") + public void deleteSysIconById(InputObject inputObject, OutputObject outputObject) { + sysEveIconService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/dao/SysEveIconDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/dao/SysEveIconDao.java new file mode 100644 index 0000000..1f0c5d1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/dao/SysEveIconDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.icon.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.icon.entity.SysEveIcon; + +/** + * @ClassName: SysEveIconDao + * @Description: 系统icon库数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 21:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveIconDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/entity/SysEveIcon.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/entity/SysEveIcon.java new file mode 100644 index 0000000..3cff5ff --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/entity/SysEveIcon.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.icon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveIcon + * @Description: 系统icon库 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 21:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"iconClass"}) +@RedisCacheField(name = "sys:icon") +@TableName(value = "sys_eve_icon") +@ApiModel("系统icon库") +public class SysEveIcon extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("icon_class") + @ApiModelProperty(value = "icon属性", required = "required", fuzzyLike = true) + private String iconClass; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/SysEveIconService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/SysEveIconService.java new file mode 100644 index 0000000..63506ed --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/SysEveIconService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.icon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.icon.entity.SysEveIcon; + +/** + * @ClassName: SysEveIconService + * @Description: 系统icon库服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 21:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveIconService extends SkyeyeBusinessService { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/impl/SysEveIconServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/impl/SysEveIconServiceImpl.java new file mode 100644 index 0000000..0f6272f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/icon/service/impl/SysEveIconServiceImpl.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.icon.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.icon.dao.SysEveIconDao; +import com.skyeye.icon.entity.SysEveIcon; +import com.skyeye.icon.service.SysEveIconService; +import org.springframework.stereotype.Service; + +/** + * @ClassName: SysEveIconServiceImpl + * @Description: 系统icon库服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 21:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "系统icon库", groupName = "系统icon库") +public class SysEveIconServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveIconService { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuPointType.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuPointType.java new file mode 100644 index 0000000..ac2730b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuPointType.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MenuPointType + * @Description: 菜单权限点类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/29 21:27 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MenuPointType implements SkyeyeEnumClass { + + AUTH_POINT(1, "权限点", true, true), + DATA_GROUP(2, "数据分组", true, false), + DATA_POINT(3, "数据权限", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getTypeName(Integer type) { + for (MenuPointType bean : MenuPointType.values()) { + if (bean.getKey() == type) { + return bean.getValue(); + } + } + return StrUtil.EMPTY; + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuType.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuType.java new file mode 100644 index 0000000..cb7ca3d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/MenuType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: MenuType + * @Description: APP菜单类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/12/16 9:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum MenuType implements SkyeyeEnumClass { + + FOLDER(1, "目录", true, false), + PAGE(2, "页面", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/UrlType.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/UrlType.java new file mode 100644 index 0000000..443fd4e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/classenum/UrlType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UrlType + * @Description: APP菜单URL类型 + * @author: skyeye云系列--卫志强 + * @date: 2023/12/16 9:21 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UrlType implements SkyeyeEnumClass { + + EXTERNAL_SYSTEM_MENU(1, "外部系统菜单", true, false), + SELF_SYSTEM_MENU(2, "自身系统菜单", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AppWorkPageController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AppWorkPageController.java new file mode 100644 index 0000000..224b860 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AppWorkPageController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.entity.AppWorkPage; +import com.skyeye.menu.service.AppWorkPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AppWorkPageServiceImpl + * @Description: 手机端菜单以及目录功能控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/10 23:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "手机端菜单管理", tags = "手机端菜单管理", modelName = "菜单管理") +public class AppWorkPageController { + + @Autowired + private AppWorkPageService appWorkPageService; + + /** + * 获取菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAppWorkPageList", value = "获取菜单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AppWorkPageController/queryAppWorkPageList") + public void queryAppWorkPageList(InputObject inputObject, OutputObject outputObject) { + appWorkPageService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑手机端菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAppWorkPageMation", value = "新增/编辑手机端菜单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AppWorkPage.class) + @RequestMapping("/post/AppWorkPageController/writeAppWorkPageMation") + public void writeAppWorkPageMation(InputObject inputObject, OutputObject outputObject) { + appWorkPageService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAppWorkPageById", value = "根据id查询菜单", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AppWorkPageController/queryAppWorkPageById") + public void queryAppWorkPageById(InputObject inputObject, OutputObject outputObject) { + appWorkPageService.selectById(inputObject, outputObject); + } + + /** + * 删除菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAppWorkPageById", value = "删除菜单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AppWorkPageController/deleteAppWorkPageById") + public void deleteAppWorkPageById(InputObject inputObject, OutputObject outputObject) { + appWorkPageService.deleteById(inputObject, outputObject); + } + + /** + * 根据桌面id获取目录集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAppWorkPageListByDesktopId", value = "根据桌面id获取目录集合", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "desktopId", name = "desktopId", value = "桌面id")}) + @RequestMapping("/post/AppWorkPageController/queryAppWorkPageListByDesktopId") + public void queryAppWorkPageListByDesktopId(InputObject inputObject, OutputObject outputObject) { + appWorkPageService.queryAppWorkPageListByDesktopId(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AuthPointController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AuthPointController.java new file mode 100644 index 0000000..79d8f4f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/AuthPointController.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.entity.AuthPoint; +import com.skyeye.menu.service.AuthPointService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * + * @ClassName: AuthPointController + * @Description: 菜单权限点管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/23 19:24 + * + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "菜单权限点管理", tags = "菜单权限点管理", modelName = "菜单管理") +public class AuthPointController { + + @Autowired + private AuthPointService authPointService; + + /** + * 根据菜单id获取菜单权限点列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAuthPointList", value = "根据菜单id获取菜单权限点列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TableSelectInfo.class) + @RequestMapping("/post/AuthPointController/queryAuthPointList") + public void queryAuthPointList(InputObject inputObject, OutputObject outputObject) { + authPointService.queryList(inputObject, outputObject); + } + + /** + * 新增/编辑菜单权限点 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAuthPoint", value = "新增/编辑菜单权限点", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = AuthPoint.class) + @RequestMapping("/post/AuthPointController/writeAuthPoint") + public void writeAuthPoint(InputObject inputObject, OutputObject outputObject) { + authPointService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询菜单权限点 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAuthPointById", value = "根据id查询菜单权限点", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AuthPointController/queryAuthPointById") + public void queryAuthPointById(InputObject inputObject, OutputObject outputObject) { + authPointService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除菜单权限点 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAuthPointById", value = "根据id删除菜单权限点", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AuthPointController/deleteAuthPointById") + public void deleteAuthPointById(InputObject inputObject, OutputObject outputObject) { + authPointService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/SysEveMenuController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/SysEveMenuController.java new file mode 100644 index 0000000..6770399 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/controller/SysEveMenuController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.entity.SysMenu; +import com.skyeye.menu.entity.SysMenuQueryDo; +import com.skyeye.menu.service.SysEveMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveMenuController + * @Description: 菜单管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/15 20:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "菜单管理", tags = "菜单管理", modelName = "菜单管理") +public class SysEveMenuController { + + @Autowired + private SysEveMenuService sysEveMenuService; + + /** + * 获取菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys006", value = "获取菜单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysMenuQueryDo.class) + @RequestMapping("/post/SysEveMenuController/querySysMenuList") + public void querySysMenuList(InputObject inputObject, OutputObject outputObject) { + sysEveMenuService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeMenu", value = "添加/编辑菜单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysMenu.class) + @RequestMapping("/post/SysEveMenuController/writeMenu") + public void writeMenu(InputObject inputObject, OutputObject outputObject) { + sysEveMenuService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 系统菜单详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys040", value = "系统菜单详情", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "菜单ID", required = "required")}) + @RequestMapping("/post/SysEveMenuController/querySysEveMenuBySysId") + public void querySysEveMenuBySysId(InputObject inputObject, OutputObject outputObject) { + sysEveMenuService.selectById(inputObject, outputObject); + } + + /** + * 根据父菜单ID查看子菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys009", value = "根据父菜单ID查看子菜单", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "parentId", name = "parentId", value = "父菜单ID", required = "required")}) + @RequestMapping("/post/SysEveMenuController/querySysMenuMationBySimpleLevel") + public void querySysMenuMationBySimpleLevel(InputObject inputObject, OutputObject outputObject) { + sysEveMenuService.querySysMenuMationBySimpleLevel(inputObject, outputObject); + } + + /** + * 删除菜单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMenuById", value = "删除菜单信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "菜单ID", required = "required")}) + @RequestMapping("/post/SysEveMenuController/deleteMenuById") + public void deleteMenuById(InputObject inputObject, OutputObject outputObject) { + sysEveMenuService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AppWorkPageDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AppWorkPageDao.java new file mode 100644 index 0000000..0eaf66c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AppWorkPageDao.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.menu.entity.AppWorkPage; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AppWorkPageDao + * @Description: 手机端菜单以及目录功能接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/10 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface AppWorkPageDao extends SkyeyeBaseMapper { + + List> queryAppWorkPageList(CommonPageInfo commonPageInfo); + + List queryAllChildIdsByParentId(@Param("ids") List ids); + + List> queryAllAppMenuList(); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AuthPointDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AuthPointDao.java new file mode 100644 index 0000000..76d2843 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/AuthPointDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.dao; + +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.menu.entity.AuthPoint; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AuthPointDao + * @Description: 菜单权限点管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/29 21:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface AuthPointDao extends SkyeyeBaseMapper { + + List> queryMenuAuthPointList(TableSelectInfo selectInfo); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/SysEveMenuDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/SysEveMenuDao.java new file mode 100644 index 0000000..9281a24 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/dao/SysEveMenuDao.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.menu.entity.SysMenu; +import com.skyeye.menu.entity.SysMenuQueryDo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveMenuDao + * @Description: 菜单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/5 21:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveMenuDao extends SkyeyeBaseMapper { + + List> querySysMenuList(SysMenuQueryDo sysMenuQuery); + + List> querySysMenuMationBySimpleLevel(Map map); + + Map queryUseThisMenuRoleById(@Param("id") String id); + + /** + * 根据父id查询所有的子节点信息(包含父id),如果是多个 + * + * @param ids 父id + * @return + */ + List queryAllChildIdsByParentId(@Param("ids") List ids); + + List> queryAllMenuList(); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AppWorkPage.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AppWorkPage.java new file mode 100644 index 0000000..ee13d33 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AppWorkPage.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.win.entity.SysDesktop; +import lombok.Data; + +/** + * @ClassName: AppWorkPage + * @Description: APP菜单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/24 21:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "app_workbench_page") +@ApiModel("APP菜单实体类") +public class AppWorkPage extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "菜单/目录名称", required = "required") + private String name; + + @TableField("logo") + @ApiModelProperty(value = "菜单logo") + private String logo; + + @TableField("url") + @ApiModelProperty(value = "菜单路径") + private String url; + + @TableField("url_type") + @ApiModelProperty(value = "APP菜单URL类型,参考#UrlType", required = "num") + private Integer urlType; + + @TableField("order_by") + @ApiModelProperty(value = "排序,值越大越往后", required = "required,num") + private Integer orderBy; + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @Property(value = "菜单类型,参考#MenuType") + private Integer type; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "所属目录id", defaultValue = "0") + private String parentId; + + @TableField(exist = false) + @Property(value = "所属目录信息") + private AppWorkPage parentMation; + + @TableField(value = "desktop_id") + @ApiModelProperty(value = "所属桌面id", required = "required") + private String desktopId; + + @TableField(exist = false) + @Property(value = "菜单所属桌面") + private SysDesktop desktopMation; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AuthPoint.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AuthPoint.java new file mode 100644 index 0000000..2ef12ca --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/AuthPoint.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysMenuAuthPointMation + * @Description: 菜单权限点实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/23 19:14 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_eve_menu_auth_point") +@ApiModel("菜单权限点实体类") +public class AuthPoint extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属菜单id【不可修改】", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属菜单的类型(pc端或者手机端)【不可修改】", required = "required") + private String objectKey; + + @TableField("`name`") + @ApiModelProperty(value = "权限点名称/分组名称/数据权限名称", required = "required") + private String name; + + @TableField("auth_menu") + @ApiModelProperty(value = "接口id/分组标识/数据权限表达式", required = "required") + private String authMenu; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "num") + private Integer orderBy; + + @TableField("menu_num") + @Property(value = "菜单数字码(权限点)") + private String menuNum; + + @TableField(value = "parent_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属父id,层级结构参考type字段【不可修改】", required = "required") + private String parentId; + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "类型 1.权限点 2.数据分组(父级为1) 3.数据分组下的数据类型(父级为2)【不可修改】,参考#MenuPointType", required = "required,num") + private String type; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenu.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenu.java new file mode 100644 index 0000000..1d1923a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenu.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.IconOrImgInfo; +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.win.entity.SysDesktop; +import com.skyeye.win.entity.SysWin; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: SysMenu + * @Description: 菜单管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/5/15 21:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sys:menu") +@TableName(value = "sys_eve_menu") +@ApiModel("菜单管理实体类") +public class SysMenu extends IconOrImgInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "菜单名称", required = "required") + private String name; + + @TableField("page_type") + @ApiModelProperty(value = "页面类型,参考#MenuPageType", required = "required") + private Integer pageType; + + @TableField(exist = false) + @Property(value = "当 pageType 为表单布局时,存储的表单布局信息") + private DsFormPage dsFormPage; + + @TableField(exist = false) + @Property(value = "当 type 为视图页面时,存储的视图页面信息") + private Map reportPage; + + @TableField("page_url") + @ApiModelProperty(value = "菜单链接", required = "required") + private String pageUrl; + + @TableField("path") + @ApiModelProperty(value = "VUE前端路由路径") + private String path; + + @TableField("type") + @ApiModelProperty(value = "菜单类型", required = "required") + private String type; + + @TableField("sys_type") + @ApiModelProperty(value = "是否为系统菜单", required = "required,num") + private Integer sysType; + + @TableField("parent_id") + @ApiModelProperty(value = "父菜单ID", required = "required") + private String parentId; + + @TableField(exist = false) + @Property(value = "父菜单") + private SysMenu parentMenu; + + @TableField("level") + @ApiModelProperty(value = "菜单级别 0:父菜单 1:子菜单", required = "required,num") + private Integer level; + + /** + * 菜单链接打开类型,父菜单默认为1.1:打开iframe,2:打开html。 + */ + @TableField("open_type") + private Integer openType; + + @TableField("order_num") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderNum; + + @TableField("sys_win_id") + @ApiModelProperty(value = "菜单所属系统id", required = "required") + private String sysWinId; + + @TableField(exist = false) + @Property(value = "菜单所属系统") + private SysWin sysWinMation; + + @TableField("is_share") + @ApiModelProperty(value = "是否同步共享", required = "required,num") + private Integer isShare; + + @TableField("desktop_id") + @ApiModelProperty(value = "菜单所属桌面id", required = "required") + private String desktopId; + + @TableField(exist = false) + @Property(value = "菜单所属桌面") + private SysDesktop desktopMation; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenuQueryDo.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenuQueryDo.java new file mode 100644 index 0000000..36ae351 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/entity/SysMenuQueryDo.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: SysMenuQueryDo + * @Description: 菜单列表查询条件实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/30 22:41 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("菜单列表查询条件实体类") +public class SysMenuQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "服务id") + private String sysWinId; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AppWorkPageService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AppWorkPageService.java new file mode 100644 index 0000000..da66b24 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AppWorkPageService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.entity.AppWorkPage; + +/** + * @ClassName: AppWorkPageServiceImpl + * @Description: 手机端菜单以及目录功能服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/10 23:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface AppWorkPageService extends SkyeyeBusinessService { + + void queryAppWorkPageListByDesktopId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AuthPointService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AuthPointService.java new file mode 100644 index 0000000..fce318c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/AuthPointService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.menu.entity.AuthPoint; + +/** + * @ClassName: AuthPointService + * @Description: 菜单权限点管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/29 21:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface AuthPointService extends SkyeyeBusinessService { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/SysEveMenuService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/SysEveMenuService.java new file mode 100644 index 0000000..da27181 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/SysEveMenuService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.entity.SysMenu; + +public interface SysEveMenuService extends SkyeyeBusinessService { + + void querySysMenuMationBySimpleLevel(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AppWorkPageServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AppWorkPageServiceImpl.java new file mode 100644 index 0000000..0f6b55b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AppWorkPageServiceImpl.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.menu.classenum.MenuType; +import com.skyeye.menu.dao.AppWorkPageDao; +import com.skyeye.menu.entity.AppWorkPage; +import com.skyeye.menu.service.AppWorkPageService; +import com.skyeye.win.service.SysEveDesktopService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AppWorkPageServiceImpl + * @Description: 手机端菜单以及目录功能服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/10 23:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "手机端菜单管理", groupName = "菜单管理") +public class AppWorkPageServiceImpl extends SkyeyeBusinessServiceImpl implements AppWorkPageService { + + @Autowired + private SysEveDesktopService sysEveDesktopService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryAppWorkPageList(commonPageInfo); + List ids = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return beans; + } + // 查询子节点信息(包含当前节点) + List childIds = skyeyeBaseMapper.queryAllChildIdsByParentId(ids); + beans = selectMapByIds(childIds).values().stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + beans = beans.stream() + .sorted(Comparator.comparing(bean -> Integer.parseInt(bean.get("orderBy").toString()))).collect(Collectors.toList()); + beans.forEach(bean -> { + bean.put("lay_is_open", true); + }); + return beans; + } + + @Override + protected void createPrepose(AppWorkPage entity) { + if (StrUtil.isNotEmpty(entity.getUrl())) { + entity.setType(MenuType.PAGE.getKey()); + } else { + entity.setType(MenuType.FOLDER.getKey()); + } + } + + @Override + public AppWorkPage selectById(String id) { + AppWorkPage appWorkPage = super.selectById(id); + sysEveDesktopService.setDataMation(appWorkPage, AppWorkPage::getDesktopId); + if (!appWorkPage.getParentId().equals("0")) { + appWorkPage.setParentMation(selectById(appWorkPage.getParentId())); + } + return appWorkPage; + } + + @Override + public List selectByIds(String... ids) { + List appWorkPages = super.selectByIds(ids); + // 桌面信息 + sysEveDesktopService.setDataMation(appWorkPages, AppWorkPage::getDesktopId); + return appWorkPages; + } + + @Override + public void deletePostpose(String id) { + // 删除子菜单 + deleteByParentId(id); + } + + private void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(AppWorkPage::getParentId), parentId); + remove(queryWrapper); + } + + /** + * 根据父目录id获取子目录集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAppWorkPageListByDesktopId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String desktopId = map.get("desktopId").toString(); + if (StringUtils.isEmpty(desktopId)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AppWorkPage::getDesktopId), desktopId); + queryWrapper.eq(MybatisPlusUtil.toColumns(AppWorkPage::getType), MenuType.FOLDER.getKey()); + List appWorkPageMationList = list(queryWrapper); + outputObject.setBeans(appWorkPageMationList); + outputObject.settotal(appWorkPageMationList.size()); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AuthPointServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AuthPointServiceImpl.java new file mode 100644 index 0000000..953c530 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/AuthPointServiceImpl.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.TableSelectInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.menu.classenum.MenuPointType; +import com.skyeye.menu.dao.AuthPointDao; +import com.skyeye.menu.entity.AuthPoint; +import com.skyeye.menu.service.AuthPointService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AuthPointServiceImpl + * @Description: 菜单权限点管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/23 19:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "权限点管理", groupName = "菜单管理", teamAuth = true) +public class AuthPointServiceImpl extends SkyeyeBusinessServiceImpl implements AuthPointService { + + @Override + public List> queryDataList(InputObject inputObject) { + TableSelectInfo selectInfo = inputObject.getParams(TableSelectInfo.class); + List> beans = skyeyeBaseMapper.queryMenuAuthPointList(selectInfo); + beans.forEach(bean -> { + bean.put("typeName", MenuPointType.getTypeName(Integer.parseInt(bean.get("type").toString()))); + }); + return beans; + } + + @Override + protected void createPrepose(AuthPoint entity) { + entity.setMenuNum(String.valueOf(DateUtil.getTimeStampAndToString())); + } + + @Override + protected void validatorEntity(AuthPoint entity) { + super.validatorEntity(entity); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(AuthPoint::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(AuthPoint::getAuthMenu), entity.getAuthMenu())); + queryWrapper.eq(MybatisPlusUtil.toColumns(AuthPoint::getObjectId), entity.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(AuthPoint::getParentId), entity.getParentId()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + AuthPoint checkSysMenuAuthPoint = getOne(queryWrapper); + + if (!ObjectUtils.isEmpty(checkSysMenuAuthPoint)) { + throw new CustomException("该菜单下已存在相同的名称/接口URL,请进行更改。"); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/SysEveMenuServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/SysEveMenuServiceImpl.java new file mode 100644 index 0000000..e280558 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/menu/service/impl/SysEveMenuServiceImpl.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.menu.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dsform.entity.DsFormPage; +import com.skyeye.dsform.service.DsFormPageService; +import com.skyeye.exception.CustomException; +import com.skyeye.menu.dao.SysEveMenuDao; +import com.skyeye.menu.entity.SysMenu; +import com.skyeye.menu.entity.SysMenuQueryDo; +import com.skyeye.menu.service.SysEveMenuService; +import com.skyeye.operate.classenum.MenuPageType; +import com.skyeye.rest.report.service.IReportPageService; +import com.skyeye.server.entity.ServiceBeanCustom; +import com.skyeye.server.service.ServiceBeanCustomService; +import com.skyeye.win.service.SysEveDesktopService; +import com.skyeye.win.service.SysEveWinService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SysEveMenuServiceImpl + * @Description: 菜单管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/3 11:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "菜单管理", groupName = "菜单管理") +public class SysEveMenuServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveMenuService { + + @Autowired + private SysEveMenuDao sysEveMenuDao; + + @Autowired + private SysEveDesktopService sysEveDesktopService; + + @Autowired + private SysEveWinService sysEveWinService; + + @Autowired + private DsFormPageService dsFormPageService; + + @Autowired + private ServiceBeanCustomService serviceBeanCustomService; + + /** + * 菜单链接打开类型,父菜单默认为1.1:打开iframe,2:打开html。 + */ + public static final Integer SYS_MENU_OPEN_TYPE_IS_IFRAME = 1; + public static final Integer SYS_MENU_OPEN_TYPE_IS_HTML = 2; + + /** + * 菜单类型 + */ + public static final String SYS_MENU_TYPE_IS_IFRAME = "win"; + public static final String SYS_MENU_TYPE_IS_HTML = "html"; + + @Autowired + private IReportPageService iReportPageService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + SysMenuQueryDo sysMenuQuery = inputObject.getParams(SysMenuQueryDo.class); + List> beans = sysEveMenuDao.querySysMenuList(sysMenuQuery); + List ids = beans.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return beans; + } + // 查询子节点信息(包含当前节点) + List childIds = sysEveMenuDao.queryAllChildIdsByParentId(ids); + beans = selectMapByIds(childIds).values().stream().map(bean -> BeanUtil.beanToMap(bean)).collect(Collectors.toList()); + beans = beans.stream() + .sorted(Comparator.comparing(bean -> Integer.parseInt(bean.get("orderNum").toString()))).collect(Collectors.toList()); + beans.forEach(bean -> { + bean.put("lay_is_open", true); + }); + return beans; + } + + @Override + public void validatorEntity(SysMenu entity) { + super.validatorEntity(entity); + if (StrUtil.equals(entity.getId(), entity.getParentId())) { + throw new CustomException("父菜单不能为自己!"); + } + } + + @Override + public void createPrepose(SysMenu entity) { + // 设置菜单链接打开类型 + setOpenType(entity); + // 设置菜单级别 + setMenuLevel(entity); + } + + @Override + public void updatePrepose(SysMenu entity) { + // 设置菜单链接打开类型 + setOpenType(entity); + // 设置菜单级别 + setMenuLevel(entity); + } + + private void setMenuLevel(SysMenu sysMenu) { + if ("0".equals(sysMenu.getParentId())) { + sysMenu.setLevel(0); + } else { + sysMenu.setLevel(CommonNumConstants.NUM_ONE); + } + } + + private void setOpenType(SysMenu sysMenu) { + if (SYS_MENU_TYPE_IS_IFRAME.equals(sysMenu.getType())) { + // iframe + sysMenu.setOpenType(SYS_MENU_OPEN_TYPE_IS_IFRAME); + } else if (SYS_MENU_TYPE_IS_HTML.equals(sysMenu.getType())) { + // html + sysMenu.setOpenType(SYS_MENU_OPEN_TYPE_IS_HTML); + } + } + + @Override + public void deletePreExecution(String id) { + // 判断菜单有没有角色使用,没有则可以删除 + Map useMenuBean = sysEveMenuDao.queryUseThisMenuRoleById(id); + if (CollectionUtil.isNotEmpty(useMenuBean)) { + if (Integer.parseInt(useMenuBean.get("roleNum").toString()) > 0) { + throw new CustomException("该菜单正在被一个或多个角色使用,无法删除。"); + } + } + } + + @Override + public void deletePostpose(String id) { + // 删除子菜单 + deleteByParentId(id); + } + + private void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(SysMenu::getParentId), parentId); + remove(queryWrapper); + } + + /** + * 根据父菜单ID查看子菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysMenuMationBySimpleLevel(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + List> beans = sysEveMenuDao.querySysMenuMationBySimpleLevel(map); + // 桌面信息 + sysEveDesktopService.setMationForMap(beans, "desktopId", "desktopMation"); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public SysMenu selectById(String id) { + SysMenu sysMenu = super.selectById(id); + + sysEveDesktopService.setDataMation(sysMenu, SysMenu::getDesktopId); + sysEveWinService.setDataMation(sysMenu, SysMenu::getSysWinId); + + if (sysMenu.getPageType() == MenuPageType.LAYOUT.getKey()) { + // 表单布局 + DsFormPage dsFormPage = dsFormPageService.getDataFromDb(sysMenu.getPageUrl()); + ServiceBeanCustom serviceBeanCustom = serviceBeanCustomService.selectServiceBeanCustom(dsFormPage.getAppId(), dsFormPage.getClassName()); + dsFormPage.setServiceBeanCustom(serviceBeanCustom); + sysMenu.setDsFormPage(dsFormPage); + } else if (sysMenu.getPageType() == MenuPageType.REPORT.getKey()) { + // 报表页面 + sysMenu.setReportPage(iReportPageService.queryDataMationById(sysMenu.getPageUrl())); + } + if (!sysMenu.getParentId().equals("0")) { + sysMenu.setParentMenu(selectById(sysMenu.getParentId())); + } + return sysMenu; + } + + @Override + public List selectByIds(String... ids) { + List sysMenuList = super.selectByIds(ids); + // 桌面信息 + sysEveDesktopService.setDataMation(sysMenuList, SysMenu::getDesktopId); + // 服务信息 + sysEveWinService.setDataMation(sysMenuList, SysMenu::getSysWinId); + return sysMenuList; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/StaffWagesStateEnum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/StaffWagesStateEnum.java new file mode 100644 index 0000000..eb42d8c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/StaffWagesStateEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: StaffWagesStateEnum + * @Description: 员工薪资设定状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum StaffWagesStateEnum implements SkyeyeEnumClass { + + WAIT_DESIGN_WAGES(1, "待设定", true, true), + TOO_DESIGN_WAGES(2, "已设定", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallMenuSize.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallMenuSize.java new file mode 100644 index 0000000..8996ecc --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallMenuSize.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserInstallMenuSize + * @Description: 开始菜单尺寸枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:51 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserInstallMenuSize implements SkyeyeEnumClass { + + MINI("xs", "迷你", true, true), + MIDDLE("sm", "中等", true, false), + WIDE("lg", "宽敞", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallTaskPosition.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallTaskPosition.java new file mode 100644 index 0000000..e7a4071 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserInstallTaskPosition.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserInstallTaskPosition + * @Description: 任务栏在屏幕的位置枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:51 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserInstallTaskPosition implements SkyeyeEnumClass { + + TOP("top", "顶部", true, true), + BOTTOM("bottom", "底部", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserIsTermOfValidity.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserIsTermOfValidity.java new file mode 100644 index 0000000..defdddc --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserIsTermOfValidity.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserIsTermOfValidity + * @Description: 用户是否长期有效枚举 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/20 21:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserIsTermOfValidity implements SkyeyeEnumClass { + + LONG_TERM(1, "长期有效", true, true), + EFFECTIVE_TIME_PERIOD(2, "时间段有效", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserLockState.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserLockState.java new file mode 100644 index 0000000..06b5f4b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserLockState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserLockState + * @Description: 用户锁定状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/20 21:33 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserLockState implements SkyeyeEnumClass { + + SYS_USER_LOCK_STATE_ISUNLOCK(0, "未锁定", true, true), + SYS_USER_LOCK_STATE_ISLOCK(1, "锁定", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserStaffType.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserStaffType.java new file mode 100644 index 0000000..58d8417 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/classenum/UserStaffType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserStaffType + * @Description: 员工类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:51 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserStaffType implements SkyeyeEnumClass { + + SIMPLE_STAFF(1, "普通员工", true, true), + TEACHER(2, "教师", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/AppAuthController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/AppAuthController.java new file mode 100644 index 0000000..aaf6b1f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/AppAuthController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.service.AppAuthService; +import com.skyeye.personnel.service.SysEveUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AppAuthController + * @Description: 登录管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 17:04 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "登录管理", tags = "登录管理", modelName = "登录管理") +public class AppAuthController { + + @Autowired + public SysEveUserService sysEveUserService; + + @Autowired + private AppAuthService appAuthService; + + @ApiOperation(id = "login001", value = "登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userCode", name = "userCode", value = "账号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required")}) + @RequestMapping("/post/AppAuthController/queryUserToLogin") + public void queryUserToLogin(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryUserToLogin(inputObject, outputObject); + } + + @ApiOperation(id = "userphone001", value = "手机端用户登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userCode", name = "userCode", value = "账号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required"), + @ApiImplicitParam(id = "cId", name = "cId", value = "cId,用于手机端消息通知")}) + @RequestMapping("/post/AppAuthController/queryPhoneToLogin") + public void queryPhoneToLogin(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryPhoneToLogin(inputObject, outputObject); + } + + @ApiOperation(id = "login003", value = "退出", method = "POST", allUse = "2") + @RequestMapping("/post/AppAuthController/deleteUserMationBySession") + public void deleteUserMationBySession(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.deleteUserMationBySession(inputObject, outputObject); + } + + @ApiOperation(id = "login007", value = "修改密码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "newPassword", name = "newPassword", value = "新密码", required = "required"), + @ApiImplicitParam(id = "oldPassword", name = "oldPassword", value = "旧密码", required = "required")}) + @RequestMapping("/post/AppAuthController/editUserPassword") + public void editUserPassword(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editUserPassword(inputObject, outputObject); + } + + @ApiOperation(id = "sendSmsCode", value = "发送手机验证码", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mobile", name = "mobile", value = "手机号"), + @ApiImplicitParam(id = "scene", name = "scene", value = "发送场景,参考#SmsSceneEnum", required = "required")}) + @RequestMapping("/post/AppAuthController/sendSmsCode") + public void sendSmsCode(InputObject inputObject, OutputObject outputObject) { + appAuthService.sendSmsCode(inputObject, outputObject); + } + + @ApiOperation(id = "smsLogin", value = "短信验证码登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mobile", name = "mobile", value = "手机号", required = "required"), + @ApiImplicitParam(id = "smsCode", name = "smsCode", value = "短信验证码", required = "required")}) + @RequestMapping("/post/AppAuthController/smsLogin") + public void smsLogin(InputObject inputObject, OutputObject outputObject) { + appAuthService.smsLogin(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserController.java new file mode 100644 index 0000000..b9ed24b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserController.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.userauth.user.UserTreeQueryDo; +import com.skyeye.personnel.entity.SysEveUser; +import com.skyeye.personnel.service.SysEveUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveUserController + * @Description: 用户管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/13 9:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用户管理", tags = "用户管理", modelName = "用户管理") +public class SysEveUserController { + + @Autowired + public SysEveUserService sysEveUserService; + + /** + * 获取管理员用户列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys001", value = "获取用户列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveUserController/querySysUserList") + public void querySysUserList(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.querySysUserList(inputObject, outputObject); + } + + /** + * 锁定账号 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys002", value = "锁定账号", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "账号ID", required = "required")}) + @RequestMapping("/post/SysEveUserController/editSysUserLockStateToLockById") + public void editSysUserLockStateToLockById(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editSysUserLockStateToLockById(inputObject, outputObject); + } + + /** + * 解锁账号 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys003", value = "解锁账号", method = "PUT", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "账号ID", required = "required")}) + @RequestMapping("/post/SysEveUserController/editSysUserLockStateToUnLockById") + public void editSysUserLockStateToUnLockById(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editSysUserLockStateToUnLockById(inputObject, outputObject); + } + + /** + * 创建账号 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysAdd005", value = "创建账号", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysEveUser.class) + @RequestMapping("/post/SysEveUserController/insertSysUserMationById") + public void insertSysUserMationById(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.insertSysUserMationById(inputObject, outputObject); + } + + /** + * 重置密码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys005", value = "重置密码", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "账号ID", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required")}) + @RequestMapping("/post/SysEveUserController/editSysUserPasswordMationById") + public void editSysUserPasswordMationById(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editSysUserPasswordMationById(inputObject, outputObject); + } + + /** + * 从session中获取用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "login002", value = "从session中获取用户信息", method = "POST", allUse = "2") + @RequestMapping("/post/SysEveUserController/queryUserMationBySession") + public void queryUserMationBySession(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryUserMationBySession(inputObject, outputObject); + } + + /** + * 获取角色和当前已经绑定的角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveUserController/queryRoleAndBindRoleByUserId") + public void queryRoleAndBindRoleByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryRoleAndBindRoleByUserId(inputObject, outputObject); + } + + /** + * 编辑用户绑定的角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys020", value = "编辑用户绑定的角色", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "rowId", name = "id", value = "账号ID", required = "required"), + @ApiImplicitParam(id = "roleIds", name = "roleIds", value = "角色ID串,逗号隔开", required = "required")}) + @RequestMapping("/post/SysEveUserController/editRoleIdsByUserId") + public void editRoleIdsByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editRoleIdsByUserId(inputObject, outputObject); + } + + /** + * 获取当前登录用户的桌面菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "login004", value = "获取当前登录用户的桌面菜单列表", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveUserController/queryDeskTopMenuBySession") + public void queryDeskTopMenuBySession(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryDeskTopMenuBySession(inputObject, outputObject); + } + + /** + * 获取当前登录用户的所有菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "login005", value = "获取当前登录用户的所有菜单列表", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveUserController/queryAllMenuBySession") + public void queryAllMenuBySession(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryAllMenuBySession(inputObject, outputObject); + } + + /** + * 锁屏密码解锁 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "login008", value = "锁屏密码解锁", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required")}) + @RequestMapping("/post/SysEveUserController/queryUserLockByLockPwd") + public void queryUserLockByLockPwd(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryUserLockByLockPwd(inputObject, outputObject); + } + + /** + * 修改个人信息时获取数据回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys032", value = "修改个人信息时获取数据回显", method = "POST", allUse = "2") + @RequestMapping("/post/SysEveUserController/queryUserDetailsMationByUserId") + public void queryUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryUserDetailsMationByUserId(inputObject, outputObject); + } + + /** + * 修改个人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveUserController/editUserDetailsMationByUserId") + public void editUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.editUserDetailsMationByUserId(inputObject, outputObject); + } + + /** + * 获取该用户拥有的桌面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "login009", value = "获取该用户拥有的桌面", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveUserController/querySysDeskTopByUserId") + public void querySysDeskTopByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.querySysDeskTopByUserId(inputObject, outputObject); + } + + /** + * 根据用户id获取桌面菜单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDeskTopsMenuByUserId", value = "根据用户id获取桌面菜单信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userId", name = "userId", value = "用户id(账号ID)", required = "required")}) + @RequestMapping("/post/SysEveUserController/queryDeskTopsMenuByUserId") + public void queryDeskTopsMenuByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryDeskTopsMenuByUserId(inputObject, outputObject); + } + + /** + * 人员选择获取所有公司和人 + * --公司为空的不显示 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople001", value = "人员选择获取所有公司和人", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/queryAllPeopleToTree") + public void queryAllPeopleToTree(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryAllPeopleToTree(inputObject, outputObject); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople002", value = "人员选择根据当前用户所属公司获取这个公司的人", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/queryCompanyPeopleToTreeByUserBelongCompany") + public void queryCompanyPeopleToTreeByUserBelongCompany(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryCompanyPeopleToTreeByUserBelongCompany(inputObject, outputObject); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司部门展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople003", value = "人员选择根据当前用户所属公司获取这个公司部门展示的人", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/queryDepartmentPeopleToTreeByUserBelongDepartment") + public void queryDepartmentPeopleToTreeByUserBelongDepartment(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryDepartmentPeopleToTreeByUserBelongDepartment(inputObject, outputObject); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司岗位展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople004", value = "人员选择根据当前用户所属公司获取这个公司岗位展示的人", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/queryJobPeopleToTreeByUserBelongJob") + public void queryJobPeopleToTreeByUserBelongJob(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryJobPeopleToTreeByUserBelongJob(inputObject, outputObject); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司同级部门展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople005", value = "人员选择根据当前用户所属公司获取这个公司同级部门展示的人", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/querySimpleDepPeopleToTreeByUserBelongSimpleDep") + public void querySimpleDepPeopleToTreeByUserBelongSimpleDep(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.querySimpleDepPeopleToTreeByUserBelongSimpleDep(inputObject, outputObject); + } + + /** + * 根据聊天组展示用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople006", value = "根据聊天组展示用户", method = "GET", allUse = "2") + @ApiImplicitParams(classBean = UserTreeQueryDo.class) + @RequestMapping("/post/SysEveUserController/queryTalkGroupUserListByUserId") + public void queryTalkGroupUserListByUserId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryTalkGroupUserListByUserId(inputObject, outputObject); + } + + /** + * 根据openId获取用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "userphone004", value = "根据openId获取用户信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "openId", name = "openId", value = "用户openId", required = "required")}) + @RequestMapping("/post/SysEveUserController/queryUserMationByOpenId") + public void queryUserMationByOpenId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.queryUserMationByOpenId(inputObject, outputObject); + } + + /** + * openId绑定用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "userphone005", value = "openId绑定用户信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userCode", name = "userCode", value = "账号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required"), + @ApiImplicitParam(id = "openId", name = "openId", value = "用户openId", required = "required")}) + @RequestMapping("/post/SysEveUserController/insertUserMationByOpenId") + public void insertUserMationByOpenId(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.insertUserMationByOpenId(inputObject, outputObject); + } + + /** + * 根据id查询用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveUserById", value = "根据id查询用户信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "用户ID", required = "required")}) + @RequestMapping("/post/SysEveUserController/querySysEveUserById") + public void querySysEveUserById(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.selectById(inputObject, outputObject); + } + + /** + * 重置用户有效期 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "resetUserEffectiveDate", value = "重置用户有效期", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "用户ID", required = "required"), + @ApiImplicitParam(id = "isTermOfValidity", name = "isTermOfValidity", value = "是否长期有效,参考#UserIsTermOfValidity", required = "required,num"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "有效期开始时间"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "有效期结束时间")}) + @RequestMapping("/post/SysEveUserController/resetUserEffectiveDate") + public void resetUserEffectiveDate(InputObject inputObject, OutputObject outputObject) { + sysEveUserService.resetUserEffectiveDate(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserInstallController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserInstallController.java new file mode 100644 index 0000000..e700efb --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserInstallController.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.service.SysEveUserInstallService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveUserInstallController + * @Description: 用户个人配置信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 12:11 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用户个人配置信息", tags = "用户个人配置信息", modelName = "用户个人配置信息") +public class SysEveUserInstallController { + + @Autowired + private SysEveUserInstallService sysEveUserInstallService; + + /** + * 自定义设置win背景图片 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys025", value = "自定义设置win背景图片", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winBgPicUrl", name = "winBgPicUrl", value = "图片url链接", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallWinBgPic") + public void editUserInstallWinBgPic(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallWinBgPic(inputObject, outputObject); + } + + /** + * 自定义设置win锁屏背景图片 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys026", value = "自定义设置win锁屏背景图片", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winLockBgPicUrl", name = "winLockBgPicUrl", value = "图片url链接", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallWinLockBgPic") + public void editUserInstallWinLockBgPic(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallWinLockBgPic(inputObject, outputObject); + } + + /** + * 自定义设置主题颜色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys024", value = "自定义设置主题颜色", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winThemeColor", name = "winThemeColor", value = "颜色的color数字", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallThemeColor") + public void editUserInstallThemeColor(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallThemeColor(inputObject, outputObject); + } + + /** + * 自定义设置win开始菜单尺寸 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys027", value = "自定义设置win开始菜单尺寸", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winStartMenuSize", name = "winStartMenuSize", value = "尺寸size", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallWinStartMenuSize") + public void editUserInstallWinStartMenuSize(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallWinStartMenuSize(inputObject, outputObject); + } + + /** + * 自定义设置win任务栏在屏幕的位置 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys028", value = "自定义设置win开始菜单尺寸", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winTaskPosition", name = "winTaskPosition", value = "位置属性", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallWinTaskPosition") + public void editUserInstallWinTaskPosition(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallWinTaskPosition(inputObject, outputObject); + } + + /** + * 自定义设置win雾化 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys029", value = "自定义设置win雾化", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winBgPicVague", name = "winBgPicVague", value = "背景图片是否雾化", required = "required"), + @ApiImplicitParam(id = "winBgPicVagueValue", name = "winBgPicVagueValue", value = "雾化值", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallVagueBgSrc") + public void editUserInstallVagueBgSrc(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallVagueBgSrc(inputObject, outputObject); + } + + /** + * 自定义设置窗口下面展示的是图标还是图标+文字 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys030", value = "自定义设置窗口下面展示的是图标还是图标+文字", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "winBottomMenuIcon", name = "winBottomMenuIcon", value = "是否只展示图标", required = "required")}) + @RequestMapping("/post/SysEveUserInstallController/editUserInstallLoadMenuIconById") + public void editUserInstallLoadMenuIconById(InputObject inputObject, OutputObject outputObject) { + sysEveUserInstallService.editUserInstallLoadMenuIconById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffController.java new file mode 100644 index 0000000..65ed861 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffController.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.entity.SysEveUserStaffQuery; +import com.skyeye.personnel.service.SysEveUserStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveUserStaffController + * @Description: 员工管理开始 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/12 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工管理", tags = "员工管理", modelName = "员工管理") +public class SysEveUserStaffController { + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + /** + * 获取员工列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysUserStaffList", value = "查看所有员工列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SysEveUserStaffQuery.class) + @RequestMapping("/post/SysEveUserStaffController/querySysUserStaffList") + public void querySysUserStaffList(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysUserStaff", value = "新增/编辑员工信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SysEveUserStaff.class) + @RequestMapping("/post/SysEveUserStaffController/writeSysUserStaff") + public void writeSysUserStaff(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysUserStaffById", value = "根据id查询员工信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "员工id", required = "required")}) + @RequestMapping("/post/SysEveUserStaffController/querySysUserStaffById") + public void querySysUserStaffById(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.selectById(inputObject, outputObject); + } + + /** + * 员工离职 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "staff006", value = "员工离职", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "员工id", required = "required"), + @ApiImplicitParam(id = "quitTime", name = "quitTime", value = "离职时间"), + @ApiImplicitParam(id = "quitReason", name = "quitReason", value = "离职原因")}) + @RequestMapping("/post/SysEveUserStaffController/editSysUserStaffState") + public void editSysUserStaffState(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.editSysUserStaffState(inputObject, outputObject); + } + + /** + * 获取当前登录员工的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "staff010", value = "获取当前登录员工的信息", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveUserStaffController/querySysUserStaffLogin") + public void querySysUserStaffLogin(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.querySysUserStaffLogin(inputObject, outputObject); + } + + /** + * 根据用户ids/员工ids获取员工信息集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserMationList", value = "根据用户ids/员工ids获取员工信息集合", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "userIds", name = "userIds", value = "用户id,多个逗号隔离(两个参数传一个即可,默认优先以userIds查询为主)"), + @ApiImplicitParam(id = "staffIds", name = "staffIds", value = "员工id,多个逗号隔开(两个参数传一个即可,默认优先以userIds查询为主)")}) + @RequestMapping("/post/SysEveUserStaffController/queryUserMationList") + public void queryUserMationList(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.queryUserMationList(inputObject, outputObject); + } + + /** + * 修改员工剩余年假信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editSysUserStaffAnnualLeaveById", value = "修改员工剩余年假信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "quarterYearHour", name = "quarterYearHour", value = "年假,精确到6位", required = "required"), + @ApiImplicitParam(id = "annualLeaveStatisTime", name = "annualLeaveStatisTime", value = "员工剩余年假数据刷新日期", required = "required")}) + @RequestMapping("/post/SysEveUserStaffController/editSysUserStaffAnnualLeaveById") + public void editSysUserStaffAnnualLeaveById(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.editSysUserStaffAnnualLeaveById(inputObject, outputObject); + } + + /** + * 修改员工的补休池剩余补休信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateSysUserStaffHolidayNumberById", value = "修改员工的补休池剩余补休信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "holidayNumber", name = "holidayNumber", value = "当前员工剩余补休天数", required = "required"), + @ApiImplicitParam(id = "holidayStatisTime", name = "holidayStatisTime", value = "员工剩余补休数据刷新日期", required = "required")}) + @RequestMapping("/post/SysEveUserStaffController/updateSysUserStaffHolidayNumberById") + public void updateSysUserStaffHolidayNumberById(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.updateSysUserStaffHolidayNumberById(inputObject, outputObject); + } + + /** + * 修改员工的补休池已休补休信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateSysUserStaffRetiredHolidayNumberById", value = "修改员工的补休池已休补休信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "retiredHolidayNumber", name = "retiredHolidayNumber", value = "当前员工已休补休天数", required = "required"), + @ApiImplicitParam(id = "retiredHolidayStatisTime", name = "retiredHolidayStatisTime", value = "员工已休补休数据刷新日期", required = "required")}) + @RequestMapping("/post/SysEveUserStaffController/updateSysUserStaffRetiredHolidayNumberById") + public void updateSysUserStaffRetiredHolidayNumberById(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.updateSysUserStaffRetiredHolidayNumberById(inputObject, outputObject); + } + + /** + * 根据员工id获取该员工的考勤时间段 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStaffCheckWorkTimeRelationNameByStaffId", value = "根据员工id获取该员工的考勤时间段", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required")}) + @RequestMapping("/post/SysEveUserStaffController/queryStaffCheckWorkTimeRelationNameByStaffId") + public void queryStaffCheckWorkTimeRelationNameByStaffId(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.queryStaffCheckWorkTimeRelationNameByStaffId(inputObject, outputObject); + } + + /** + * 获取所有在职的,拥有账号的员工 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "commonselpeople007", value = "获取所有在职的,拥有账号的员工", method = "POST", allUse = "2") + @RequestMapping("/post/SysEveUserStaffController/queryAllSysUserIsIncumbency") + public void queryAllSysUserIsIncumbency(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.queryAllSysUserIsIncumbency(inputObject, outputObject); + } + + /** + * 修改员工薪资设定信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editSysUserStaffActMoneyById", value = "修改员工薪资设定信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "actMoney", name = "actMoney", value = "员工月标准工资", required = "required,double")}) + @RequestMapping("/post/SysEveUserStaffController/editSysUserStaffActMoneyById") + public void editSysUserStaffActMoneyById(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffService.editSysUserStaffActMoneyById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffTeacherController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffTeacherController.java new file mode 100644 index 0000000..4a77b14 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/controller/SysEveUserStaffTeacherController.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.entity.SysEveUserStaffTeacher; +import com.skyeye.personnel.service.SysEveUserStaffTeacherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveUserStaffController + * @Description: 员工所属学校关系控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/12 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "员工所属学校关系管理", tags = "员工所属学校关系管理", modelName = "员工管理") +public class SysEveUserStaffTeacherController { + + @Autowired + private SysEveUserStaffTeacherService sysEveUserStaffTeacherService; + + /** + * 普通员工转教职工 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "staff007", value = "普通员工转教职工", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysEveUserStaffTeacher.class) + @RequestMapping("/post/SysEveUserStaffTeacherController/createStaffTeacherLink") + public void createStaffTeacherLink(InputObject inputObject, OutputObject outputObject) { + sysEveUserStaffTeacherService.createEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserDao.java new file mode 100644 index 0000000..ce7b585 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserDao.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.entity.userauth.user.UserTreeQueryDo; +import com.skyeye.personnel.entity.SysEveUser; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserDao + * @Description: 用户管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 15:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserDao extends SkyeyeBaseMapper { + + List> querySysUserList(CommonPageInfo pageInfo); + + Map queryMationByUserCode(@Param("userCode") String userCode); + + Map queryBindRoleMationByUserId(Map map); + + int editRoleIdsByUserId(Map map); + + List> queryDeskTopsMenuByUserId(@Param("userId") String userId); + + Map queryUserDetailsMationByUserId(@Param("userId") String userId); + + int editUserDetailsMationByUserId(Map map); + + List> querySysDeskTopByUserId(Map user); + + Map queryUserSchoolMationByUserId(@Param("userId") String userId); + + List> queryUserStaffToTree(UserTreeQueryDo queryDo); + + List> queryUserStaffDepToTree(UserTreeQueryDo queryDo); + + List> queryTalkGroupUserListByUserId(UserTreeQueryDo queryDo); + + Map queryWxUserMationByOpenId(@Param("openId") String openId); + + Map queryUserMationByOpenId(@Param("openId") String openId); + + Map queryUserBindMationByUserId(@Param("userId") String userId); + + int updateBindUserMation(Map map); + + int insertWxUserMation(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserInstallDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserInstallDao.java new file mode 100644 index 0000000..15ad736 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserInstallDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.personnel.entity.SysEveUserInstall; + +/** + * @ClassName: SysEveUserInstallDao + * @Description: 用户个人配置信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 12:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserInstallDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffDao.java new file mode 100644 index 0000000..b4d4ab1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffDao.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.personnel.entity.SysEveUserStaff; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserStaffDao + * @Description: 员工管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserStaffDao extends SkyeyeBaseMapper { + + List> queryUserMationList(@Param("userIds") String userIds, @Param("staffIds") String staffIds); + + int insertStaffCheckWorkTimeRelation(List> staffTimeMation); + + int deleteStaffCheckWorkTimeRelationByStaffId(@Param("staffId") String staffId); + + List> queryStaffCheckWorkTimeRelationNameByStaffId(@Param("staffId") String staffId); + + List> queryCheckTimeMationByTimeIds(@Param("list") List timeIds); + + List> queryCheckTimeDaysMationByTimeIds(@Param("list") List timeIds); + + /** + * 根据状态获取对应状态的员工 + * + * @param state 状态 1在职 2离职 3.见习 4.试用 5.退休 + * @return + */ + List> queryAllSysUserStaffListByState(@Param("list") List state); + + /** + * 修改员工的年假信息 + * + * @param staffId 员工id + * @param quarterYearHour 年假,精确到6位 + * @param annualLeaveStatisTime 员工剩余年假数据刷新日期 + */ + void editSysUserStaffAnnualLeaveById(@Param("staffId") String staffId, + @Param("quarterYearHour") String quarterYearHour, @Param("annualLeaveStatisTime") String annualLeaveStatisTime); + + /** + * 修改员工的补休池剩余补休信息 + * + * @param staffId 员工id + * @param holidayNumber 当前员工剩余补休天数 + * @param holidayStatisTime 刷新时间 + */ + void updateSysUserStaffHolidayNumberById(@Param("staffId") String staffId, + @Param("holidayNumber") String holidayNumber, @Param("holidayStatisTime") String holidayStatisTime); + + /** + * 修改员工的补休池已休补休信息 + * + * @param staffId 员工id + * @param retiredHolidayNumber 当前员工已休补休天数 + * @param retiredHolidayStatisTime 刷新时间 + */ + void updateSysUserStaffRetiredHolidayNumberById(@Param("staffId") String staffId, + @Param("retiredHolidayNumber") String retiredHolidayNumber, @Param("retiredHolidayStatisTime") String retiredHolidayStatisTime); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffTeacherDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffTeacherDao.java new file mode 100644 index 0000000..a2f7727 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/dao/SysEveUserStaffTeacherDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.personnel.entity.SysEveUserStaffTeacher; +import org.apache.ibatis.annotations.Mapper; + +/** + * @ClassName: SysEveUserStaffTeacherDao + * @Description: 员工所属学校关系数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/23 21:38 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ + +public interface SysEveUserStaffTeacherDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUser.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUser.java new file mode 100644 index 0000000..5aa937a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUser.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveUser + * @Description: 用户管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/16 15:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_eve_user") +@ApiModel("用户管理实体类") +public class SysEveUser extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @ApiModelProperty(value = "员工id", required = "required") + private String staffId; + + @TableField("user_code") + @ApiModelProperty(value = "用户名账号", required = "required") + private String userCode; + + @TableField("pwd_num_enc") + @Property(value = "用户密码加密次数") + private Integer pwdNumEnc; + + @TableField("password") + @ApiModelProperty(value = "密码", required = "required") + private String password; + + @TableField("role_id") + @ApiModelProperty(value = "角色ID") + private String roleId; + + @TableField("user_lock") + @Property(value = "用户账号是否锁定,参考#UserLockState") + private Integer userLock; + + @TableField("is_term_of_validity") + @ApiModelProperty(value = "是否长期有效,参考#UserIsTermOfValidity", required = "required,num") + private Integer isTermOfValidity; + + @TableField("start_time") + @ApiModelProperty(value = "有效期开始时间") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "有效期结束时间") + private String endTime; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserInstall.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserInstall.java new file mode 100644 index 0000000..ee0b21c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserInstall.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveUserInstall + * @Description: 用户个人配置信息 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 11:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_eve_user_install") +@ApiModel("用户个人配置信息") +public class SysEveUserInstall extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("user_id") + @Property(value = "用户id") + private String userId; + + @TableField("win_bg_pic_url") + @Property(value = "win系统背景图片") + private String winBgPicUrl; + + @TableField("win_bg_pic_vague") + @Property(value = "背景图片是否雾化 1正常0模糊") + private String winBgPicVague; + + @TableField("win_bg_pic_vague_value") + @Property(value = "雾化值 1~9") + private Integer winBgPicVagueValue; + + @TableField("win_lock_bg_pic_url") + @Property(value = "win系统锁屏时的背景图片") + private String winLockBgPicUrl; + + @TableField("win_theme_color") + @Property(value = "win系统的主题颜色") + private String winThemeColor; + + @TableField("win_bottom_menu_icon") + @Property(value = "是否只展示图标,参考#WhetherEnum") + private String winBottomMenuIcon; + + @TableField("win_start_menu_size") + @Property(value = "开始菜单尺寸,参考#UserInstallMenuSize") + private String winStartMenuSize; + + @TableField("win_task_position") + @Property(value = "任务栏在屏幕的位置,参考#UserInstallTaskPosition") + private String winTaskPosition; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaff.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaff.java new file mode 100644 index 0000000..27f962a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaff.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.organization.entity.Company; +import com.skyeye.organization.entity.CompanyJob; +import com.skyeye.organization.entity.Department; +import com.skyeye.organization.entity.JobScore; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserStaff + * @Description: 员工管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +//@RedisCacheField(name = CacheConstants.SYS_USER_STAFF_CACHE_KEY, cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "sys_eve_user_staff") +@ApiModel("员工管理实体类") +public class SysEveUserStaff extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "job_number", updateStrategy = FieldStrategy.NEVER) + @Property(value = "员工工号", fuzzyLike = true) + private String jobNumber; + + @TableField("user_name") + @ApiModelProperty(value = "员工姓名", required = "required", fuzzyLike = true) + private String userName; + + @TableField(exist = false) + @Property("员工工号+姓名") + private String name; + + @TableField("user_photo") + @ApiModelProperty(value = "员工头像", required = "required") + private String userPhoto; + + @TableField("user_idcard") + @ApiModelProperty(value = "员工身份证", required = "idcard") + private String userIdCard; + + @TableField("user_sex") + @ApiModelProperty(value = "员工性别,参考#SexEnum", required = "required,num") + private Integer userSex; + + @TableField("email") + @ApiModelProperty(value = "邮箱", required = "email") + private String email; + + @TableField("phone") + @ApiModelProperty(value = "手机号", required = "phone") + private String phone; + + @TableField("home_phone") + @ApiModelProperty(value = "家庭电话") + private String homePhone; + + @TableField("qq") + @ApiModelProperty(value = "QQ") + private String qq; + + @TableField("user_sign") + @ApiModelProperty(value = "个性签名") + private String userSign; + + @TableField("state") + @ApiModelProperty(value = "员工在职状态,参考#UserStaffState", required = "required,num") + private Integer state; + + @TableField(exist = false) + @Property(value = "员工在职状态名称") + private String stateName; + + @TableField("user_id") + @ApiModelProperty(value = "用户id") + private String userId; + + @TableField("company_id") + @ApiModelProperty(value = "所属公司id", required = "required") + private String companyId; + + @TableField(exist = false) + @Property(value = "所属公司信息") + private Company companyMation; + + @TableField(exist = false) + @Property(value = "所属公司名称") + private String companyName; + + @TableField("department_id") + @ApiModelProperty(value = "所属部门id", required = "required") + private String departmentId; + + @TableField(exist = false) + @Property(value = "所属部门信息") + private Department departmentMation; + + @TableField(exist = false) + @Property(value = "所属部门名称") + private String departmentName; + + @TableField("job_id") + @ApiModelProperty(value = "所属职位id", required = "required") + private String jobId; + + @TableField(exist = false) + @Property(value = "所属职位信息") + private CompanyJob jobMation; + + @TableField(exist = false) + @Property(value = "所属职位名称") + private String jobName; + + @TableField("job_score_id") + @ApiModelProperty(value = "职位定级id") + private String jobScoreId; + + @TableField(exist = false) + @Property(value = "职位定级信息") + private JobScore jobScoreMation; + + @TableField(exist = false) + @Property(value = "职位定级名称") + private String jobScoreName; + + @TableField("quit_time") + @ApiModelProperty(value = "离职时间") + private String quitTime; + + @TableField("quit_reason") + @ApiModelProperty(value = "离职原因 最多50字") + private String quitReason; + + @TableField("work_time") + @ApiModelProperty(value = "参加工作时间") + private String workTime; + + @TableField("entry_time") + @ApiModelProperty(value = "入职时间,也是到岗时间") + private String entryTime; + + @TableField("trial_time") + @ApiModelProperty(value = "如果有试用期,则为试用期到期时间。当state=4时,该字段必填") + private String trialTime; + + @TableField("become_worker_time") + @ApiModelProperty(value = "如果有试用期,则为转正日期") + private String becomeWorkerTime; + + @TableField("type") + @ApiModelProperty(value = "员工类型,参考#UserStaffType", required = "required,num", defaultValue = "1") + private Integer type; + + @TableField("native_place") + @ApiModelProperty(value = "籍贯") + private String nativePlace; + + @TableField("marital_status") + @ApiModelProperty(value = "婚姻状况 1.已婚 2.未婚") + private Integer maritalStatus; + + @TableField("politic_id") + @ApiModelProperty(value = "政治面貌id") + private String politicId; + + @TableField("highest_education") + @ApiModelProperty(value = "最高学历id") + private String highestEducation; + + @TableField("design_wages") + @ApiModelProperty(value = "薪资设定情况,参考#StaffWagesStateEnum", required = "num", defaultValue = "1") + private Integer designWages; + + @TableField("act_wages") + @ApiModelProperty(value = "员工的月标准薪资") + private String actWages; + + @TableField("annual_leave") + @ApiModelProperty(value = "员工剩余年假") + private String annualLeave; + + @TableField("annual_leave_statis_time") + @ApiModelProperty(value = "员工剩余年假最近的刷新日期") + private String annualLeaveStatisTime; + + @TableField("holiday_number") + @ApiModelProperty(value = "当前员工剩余补休天数") + private String holidayNumber; + + @TableField("holiday_statis_time") + @ApiModelProperty(value = "补休池剩余补休天数数据刷新时间") + private String holidayStatisTime; + + @TableField("retired_holiday_number") + @ApiModelProperty(value = "当前员工已休补休天数") + private String retiredHolidayNumber; + + @TableField("retired_holiday_statis_time") + @ApiModelProperty(value = "补休池已休补休天数数据刷新时间") + private String retiredHolidayStatisTime; + + @TableField("interview_arrangement_id") + @ApiModelProperty(value = "关联的面试安排信息id") + private String interviewArrangementId; + + @TableField(exist = false) + @ApiModelProperty(value = "员工考勤时间段", required = "json") + private List timeIdList; + + @TableField(exist = false) + @Property(value = "员工考勤时间段信息") + private List> timeList; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffQuery.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffQuery.java new file mode 100644 index 0000000..248efa7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffQuery.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +/** + * @ClassName: SysEveUserStaffQuery + * @Description: 员工查询实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/23 10:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("员工查询实体类") +public class SysEveUserStaffQuery extends CommonPageInfo { + + @ApiModelProperty(value = "薪资设定情况,参考#StaffWagesStateEnum") + private Integer designWages; + + @ApiModelProperty(value = "是否绑定账号,参考#WhetherEnum") + private Integer bindAccount; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffTeacher.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffTeacher.java new file mode 100644 index 0000000..4083cc1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/entity/SysEveUserStaffTeacher.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: SysEveUserStaffTeacher + * @Description: 员工所属学校关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:24 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "sys_eve_user_staff_teacher") +@ApiModel("员工所属学校关系实体类") +public class SysEveUserStaffTeacher extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("staff_id") + @ApiModelProperty(value = "员工id", required = "required") + private String staffId; + + @TableField("school_id") + @ApiModelProperty(value = "学校id", required = "required") + private String schoolId; + + @TableField("faculty_id") + @ApiModelProperty(value = "院系id") + private String facultyId; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/AppAuthService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/AppAuthService.java new file mode 100644 index 0000000..2c72205 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/AppAuthService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AppAuthService + * @Description: 登录管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 17:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AppAuthService { + + void sendSmsCode(InputObject inputObject, OutputObject outputObject); + + void smsLogin(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserInstallService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserInstallService.java new file mode 100644 index 0000000..5beb143 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserInstallService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.entity.SysEveUserInstall; + +/** + * @ClassName: SysEveUserInstallService + * @Description: 用户个人配置信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 12:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserInstallService extends SkyeyeBusinessService { + + void editUserInstallWinBgPic(InputObject inputObject, OutputObject outputObject); + + void editUserInstallWinLockBgPic(InputObject inputObject, OutputObject outputObject); + + void editUserInstallThemeColor(InputObject inputObject, OutputObject outputObject); + + void editUserInstallWinStartMenuSize(InputObject inputObject, OutputObject outputObject); + + void editUserInstallWinTaskPosition(InputObject inputObject, OutputObject outputObject); + + void editUserInstallVagueBgSrc(InputObject inputObject, OutputObject outputObject); + + void editUserInstallLoadMenuIconById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserService.java new file mode 100644 index 0000000..4f44500 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserService.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.entity.SysEveUser; + +import java.util.Map; + +/** + * @ClassName: SysEveUserService + * @Description: 用户管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 16:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserService extends SkyeyeBusinessService { + + void querySysUserList(InputObject inputObject, OutputObject outputObject); + + void editSysUserLockStateToLockById(InputObject inputObject, OutputObject outputObject); + + void editSysUserLockStateToUnLockById(InputObject inputObject, OutputObject outputObject); + + void editSysUserPasswordMationById(InputObject inputObject, OutputObject outputObject); + + void queryUserToLogin(InputObject inputObject, OutputObject outputObject); + + void queryUserMationBySession(InputObject inputObject, OutputObject outputObject); + + void deleteUserMationBySession(InputObject inputObject, OutputObject outputObject); + + /** + * 退出登录 + * + * @param userId 用户id + */ + void removeLogin(String userId); + + void queryRoleAndBindRoleByUserId(InputObject inputObject, OutputObject outputObject); + + void editRoleIdsByUserId(InputObject inputObject, OutputObject outputObject); + + void queryDeskTopMenuBySession(InputObject inputObject, OutputObject outputObject); + + void queryAllMenuBySession(InputObject inputObject, OutputObject outputObject); + + void setUserLoginRedisMation(String userId, Map userMation); + + void insertSysUserMationById(InputObject inputObject, OutputObject outputObject); + + void editUserPassword(InputObject inputObject, OutputObject outputObject); + + void queryUserLockByLockPwd(InputObject inputObject, OutputObject outputObject); + + void queryUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject); + + void editUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject); + + void querySysDeskTopByUserId(InputObject inputObject, OutputObject outputObject); + + void queryDeskTopsMenuByUserId(InputObject inputObject, OutputObject outputObject); + + void queryAllPeopleToTree(InputObject inputObject, OutputObject outputObject); + + void queryCompanyPeopleToTreeByUserBelongCompany(InputObject inputObject, OutputObject outputObject); + + void queryDepartmentPeopleToTreeByUserBelongDepartment(InputObject inputObject, OutputObject outputObject); + + void queryJobPeopleToTreeByUserBelongJob(InputObject inputObject, OutputObject outputObject); + + void querySimpleDepPeopleToTreeByUserBelongSimpleDep(InputObject inputObject, OutputObject outputObject); + + void queryTalkGroupUserListByUserId(InputObject inputObject, OutputObject outputObject); + + void queryPhoneToLogin(InputObject inputObject, OutputObject outputObject); + + void queryUserMationByOpenId(InputObject inputObject, OutputObject outputObject); + + void insertUserMationByOpenId(InputObject inputObject, OutputObject outputObject); + + void editUserLockState(String id, Integer userLock); + + void resetUserEffectiveDate(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffService.java new file mode 100644 index 0000000..e8c4dc7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffService.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.personnel.entity.SysEveUserStaff; + +/** + * @ClassName: SysEveUserStaffService + * @Description: 员工管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/18 11:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserStaffService extends SkyeyeBusinessService { + + void editSysUserStaffState(InputObject inputObject, OutputObject outputObject); + + void updateStaffType(String id, Integer type); + + void querySysUserStaffLogin(InputObject inputObject, OutputObject outputObject); + + void queryUserMationList(InputObject inputObject, OutputObject outputObject); + + void editSysUserStaffAnnualLeaveById(InputObject inputObject, OutputObject outputObject); + + void updateSysUserStaffHolidayNumberById(InputObject inputObject, OutputObject outputObject); + + void updateSysUserStaffRetiredHolidayNumberById(InputObject inputObject, OutputObject outputObject); + + void queryStaffCheckWorkTimeRelationNameByStaffId(InputObject inputObject, OutputObject outputObject); + + void editSysUserStaffBindUserId(String staffId, String userId); + + void queryAllSysUserIsIncumbency(InputObject inputObject, OutputObject outputObject); + + void editSysUserStaffActMoneyById(InputObject inputObject, OutputObject outputObject); + + /** + * 检查手机号是否存在 + * + * @param phone 手机号 + * @return boolean 是否存在, true:存在, false:不存在 + */ + boolean checkPhoneExists(String phone); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffTeacherService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffTeacherService.java new file mode 100644 index 0000000..55bdbb1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/SysEveUserStaffTeacherService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.personnel.entity.SysEveUserStaffTeacher; + +/** + * @ClassName: SysEveUserStaffTeacherService + * @Description: 员工所属学校关系服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/23 21:39 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SysEveUserStaffTeacherService extends SkyeyeBusinessService { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/AppAuthServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/AppAuthServiceImpl.java new file mode 100644 index 0000000..cc47ae5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/AppAuthServiceImpl.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.enumeration.SmsSceneEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.service.AppAuthService; +import com.skyeye.personnel.service.SysEveUserStaffService; +import com.skyeye.sms.entity.SmsCodeSendReq; +import com.skyeye.sms.entity.SmsCodeValidateReq; +import com.skyeye.sms.service.SmsCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @ClassName: AppAuthServiceImpl + * @Description: 登录管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 17:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class AppAuthServiceImpl implements AppAuthService { + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Autowired + private SmsCodeService smsCodeService; + + @Override + public void sendSmsCode(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mobile = params.get("mobile").toString(); + Integer scene = Integer.parseInt(params.get("scene").toString()); + // 情况 1:如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了 + if (scene == SmsSceneEnum.UPDATE_MOBILE.getKey()) { + if (sysEveUserStaffService.checkPhoneExists(mobile)) { + throw new CustomException("手机号已经被使用"); + } + } + // 情况 2:如果是重置密码场景,需要校验手机号是存在的 + if (scene == SmsSceneEnum.RESET_PASSWORD.getKey()) { + if (!sysEveUserStaffService.checkPhoneExists(mobile)) { + throw new CustomException("手机号不存在"); + } + } + // 情况 3:如果是修改密码场景,需要查询手机号,无需前端传递 + if (scene == SmsSceneEnum.UPDATE_PASSWORD.getKey()) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + SysEveUserStaff sysEveUserStaff = sysEveUserStaffService.selectById(staffId); + if (StrUtil.isEmpty(sysEveUserStaff.getPhone())) { + throw new CustomException("您还没有绑定手机号,请先绑定手机号"); + } + mobile = sysEveUserStaff.getPhone(); + } + if (StrUtil.isEmpty(mobile)) { + throw new CustomException("手机号不能为空"); + } + // 发送短信验证码 + SmsCodeSendReq smsCodeSendReq = new SmsCodeSendReq().setMobile(mobile).setScene(scene); + smsCodeService.sendSmsCodeReq(smsCodeSendReq); + + } + + @Override + public void smsLogin(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mobile = params.get("mobile").toString(); + String smsCode = params.get("smsCode").toString(); + // 校验验证码 + SmsCodeValidateReq smsCodeValidateReq = new SmsCodeValidateReq(); + smsCodeValidateReq.setMobile(mobile); + smsCodeValidateReq.setSmsCode(smsCode); + smsCodeValidateReq.setScene(SmsSceneEnum.LOGIN.getKey()); + smsCodeService.validateSmsCode(smsCodeValidateReq); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserInstallServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserInstallServiceImpl.java new file mode 100644 index 0000000..341dd45 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserInstallServiceImpl.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.personnel.classenum.UserInstallMenuSize; +import com.skyeye.personnel.classenum.UserInstallTaskPosition; +import com.skyeye.personnel.dao.SysEveUserInstallDao; +import com.skyeye.personnel.entity.SysEveUserInstall; +import com.skyeye.personnel.service.SysEveUserInstallService; +import com.skyeye.personnel.service.SysEveUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +/** + * @ClassName: SysEveUserInstallServiceImpl + * @Description: 用户个人配置信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 12:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户个人配置信息", groupName = "用户个人配置信息") +public class SysEveUserInstallServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveUserInstallService { + + @Autowired + private SysEveUserService sysEveUserService; + + @Override + public void createPrepose(SysEveUserInstall entity) { + entity.setWinBgPicUrl("/images/upload/winbgpic/default.jpg"); + entity.setWinLockBgPicUrl("/images/upload/winlockbgpic/default.jpg"); + entity.setWinThemeColor("31"); + entity.setWinStartMenuSize(UserInstallMenuSize.MIDDLE.getKey()); + entity.setWinTaskPosition(UserInstallTaskPosition.BOTTOM.getKey()); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallWinBgPic(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winBgPicUrl"); + } + + private void editUserInstallItem(InputObject inputObject, String column) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + String val = map.get(column).toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(SysEveUserInstall::getUserId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(clazz, column), val); + update(updateWrapper); + + // 修改reids中的用户信息 + user.put(column, val); + sysEveUserService.setUserLoginRedisMation(userId, user); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallWinLockBgPic(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winLockBgPicUrl"); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallThemeColor(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winThemeColor"); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallWinStartMenuSize(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winStartMenuSize"); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallWinTaskPosition(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winTaskPosition"); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallVagueBgSrc(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String userId = user.get("id").toString(); + String winBgPicVague = map.get("winBgPicVague").toString(); + String winBgPicVagueValue = map.get("winBgPicVagueValue").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(SysEveUserInstall::getUserId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserInstall::getWinBgPicVague), winBgPicVague); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserInstall::getWinBgPicVagueValue), winBgPicVagueValue); + update(updateWrapper); + + // 修改reids中的用户信息 + user.put("winBgPicVague", winBgPicVague); + user.put("winBgPicVagueValue", winBgPicVagueValue); + sysEveUserService.setUserLoginRedisMation(userId, user); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editUserInstallLoadMenuIconById(InputObject inputObject, OutputObject outputObject) { + editUserInstallItem(inputObject, "winBottomMenuIcon"); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserServiceImpl.java new file mode 100644 index 0000000..7ded8f3 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserServiceImpl.java @@ -0,0 +1,912 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.*; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.*; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.authority.service.SysAuthorityService; +import com.skyeye.eve.entity.userauth.user.UserTreeQueryDo; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.CompanyDepartmentService; +import com.skyeye.organization.service.CompanyJobScoreService; +import com.skyeye.organization.service.CompanyJobService; +import com.skyeye.organization.service.CompanyMationService; +import com.skyeye.personnel.classenum.UserIsTermOfValidity; +import com.skyeye.personnel.classenum.UserLockState; +import com.skyeye.personnel.dao.SysEveUserDao; +import com.skyeye.personnel.entity.SysEveUser; +import com.skyeye.personnel.entity.SysEveUserInstall; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.service.SysEveUserInstallService; +import com.skyeye.personnel.service.SysEveUserService; +import com.skyeye.personnel.service.SysEveUserStaffService; +import com.skyeye.role.service.SysEveRoleService; +import org.apache.commons.lang3.StringUtils; +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 java.util.*; + +/** + * @ClassName: SysEveUserServiceImpl + * @Description: 用户管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/13 9:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户管理", groupName = "用户管理") +public class SysEveUserServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveUserService { + + private static final Logger LOGGER = LoggerFactory.getLogger(SysEveUserServiceImpl.class); + + @Autowired + private SysEveUserDao sysEveUserDao; + + @Autowired + private SysEveRoleService sysEveRoleService; + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Autowired + private SysAuthorityService sysAuthorityService; + + @Autowired + private CompanyMationService companyMationService; + + @Autowired + private CompanyDepartmentService companyDepartmentService; + + @Autowired + private CompanyJobService companyJobService; + + @Autowired + private CompanyJobScoreService companyJobScoreService; + + @Autowired + private SysEveUserInstallService sysEveUserInstallService; + + /** + * 获取管理员用户列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysUserList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = sysEveUserDao.querySysUserList(pageInfo); + companyMationService.setNameMationForMap(beans, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(beans, "jobId", "jobName", StrUtil.EMPTY); + beans.forEach(bean -> { + bean.put("staffServiceClassName", sysEveUserStaffService.getServiceClassName()); + }); + iAuthUserService.setNameForMap(beans, "createId", "createName"); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysUserLockStateToLockById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SysEveUser sysEveUser = selectById(id); + if (UserLockState.SYS_USER_LOCK_STATE_ISUNLOCK.getKey() == sysEveUser.getUserLock()) { + // 未锁定,设置为锁定 + editUserLockState(id, UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey()); + } else { + outputObject.setreturnMessage("该账号已被锁定,请刷新页面."); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysUserLockStateToUnLockById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + SysEveUser sysEveUser = selectById(id); + if (UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey() == sysEveUser.getUserLock()) { + // 锁定,设置为解锁 + editUserLockState(id, UserLockState.SYS_USER_LOCK_STATE_ISUNLOCK.getKey()); + } else { + outputObject.setreturnMessage("该账号已解锁,请刷新页面."); + } + } + + /** + * 创建账号 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertSysUserMationById(InputObject inputObject, OutputObject outputObject) { + SysEveUser sysEveUser = inputObject.getParams(SysEveUser.class); + // 判断账号是否存在 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(SysEveUser::getUserCode), sysEveUser.getUserCode()); + long count = count(wrapper); + if (count == 0) { + String currentUserId = inputObject.getLogParams().get("id").toString(); + int pwdNum = (int) (Math.random() * 100); + sysEveUser.setPwdNumEnc(pwdNum); + sysEveUser.setPassword(getCalcPaswword(sysEveUser.getPassword(), pwdNum)); + sysEveUser.setUserLock(UserLockState.SYS_USER_LOCK_STATE_ISUNLOCK.getKey()); + + // 根据员工id获取员工所属部门 + SysEveUserStaff staff = sysEveUserStaffService.selectById(sysEveUser.getStaffId()); + if (ObjectUtil.isNotEmpty(staff) && StrUtil.isNotEmpty(staff.getId())) { + // 删除redis中缓存的单位下的用户 + jedisClientService.delKeys(Constants.getSysTalkGroupUserListMationById(staff.getDepartmentId()) + "*"); + } else { + outputObject.setreturnMessage("员工信息不存在."); + return; + } + // 1.新增用户信息 + String id = createEntity(sysEveUser, currentUserId); + // 2.新增用户设置信息 + SysEveUserInstall sysEveUserInstall = new SysEveUserInstall(); + sysEveUserInstall.setUserId(id); + sysEveUserInstallService.createEntity(sysEveUserInstall, id); + // 3.修改员工与账号的关系 + sysEveUserStaffService.editSysUserStaffBindUserId(sysEveUser.getStaffId(), id); + } else { + outputObject.setreturnMessage("该账号已存在,请更换!"); + } + } + + private String getCalcPaswword(String password, int pwdNum) { + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + return password; + } + + @Override + public SysEveUser selectById(String id) { + SysEveUser sysEveUser = super.selectById(id); + sysEveUser.setPassword(null); + sysEveUser.setPwdNumEnc(null); + return sysEveUser; + } + + /** + * 重置密码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysUserPasswordMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + int pwdNum = (int) (Math.random() * 100); + String password = map.get("password").toString(); + // 更新数据库中的密码 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getPassword), getCalcPaswword(password, pwdNum)); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getPwdNumEnc), pwdNum); + update(updateWrapper); + } + + /** + * 登录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserToLogin(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userCode = map.get("userCode").toString(); + Map userMation = sysEveUserDao.queryMationByUserCode(userCode); + if (userMation == null) { + outputObject.setreturnMessage("请确保用户名输入无误!"); + } else { + int pwdNum = Integer.parseInt(userMation.get("pwdNum").toString()); + String password = map.get("password").toString(); + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + String userDBPassword = userMation.get("password").toString(); + if (password.equals(userDBPassword)) { + int userLock = Integer.parseInt(userMation.get("userLock").toString()); + if (UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey() == userLock) { + outputObject.setreturnMessage("您的账号已被锁定,请联系管理员解除!"); + } else { + // 校验用户有效期 + chectUserEffectiveDate(userMation); + + String userId = userMation.get("id").toString(); + setUserOtherMation(userMation); + List> authPoints = getMenuAndAuthToRedis(userMation, userId); + judgeAndGetSchoolMation(userMation, userId); + LOGGER.info("set userMation to redis cache start."); + setUserLoginRedisMation(userId, userMation); + LOGGER.info("set userMation to redis cache end."); + String userToken = GetUserToken.createNewToken(userId, userDBPassword); + userMation.put("userToken", userToken); + outputObject.setBean(userMation); + outputObject.setBeans(authPoints); + } + } else { + outputObject.setreturnMessage("密码输入错误!"); + } + } + } + + private void chectUserEffectiveDate(Map userMation) { + Integer isTermOfValidity = Integer.parseInt(userMation.get("isTermOfValidity").toString()); + if (isTermOfValidity == UserIsTermOfValidity.EFFECTIVE_TIME_PERIOD.getKey()) { + // 时间段有效期 + String startTime = userMation.get("startTime").toString(); + String endTime = userMation.get("endTime").toString(); + String currentTime = DateUtil.getYmdTimeAndToString(); + if (DateUtil.getDistanceDay(startTime, currentTime) >= 0 && DateUtil.getDistanceDay(currentTime, endTime) >= 0) { + // startTime <= 当前时间 <= endTime + } else { + throw new CustomException("用户有效期已过,请联系管理员续期!"); + } + } + } + + @Override + public void setUserLoginRedisMation(String userId, Map userMation) { + SysUserAuthConstants.setUserLoginRedisCache(userId, userMation); + } + + private void setUserOtherMation(Map userMation) { + companyMationService.setNameMationForMap(userMation, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(userMation, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(userMation, "jobId", "jobName", StrUtil.EMPTY); + } + + /** + * 获取用户菜单权限信息并存入redis缓存 + * + * @param userMation + * @param userId + * @return + */ + private List> getMenuAndAuthToRedis(Map userMation, String userId) { + LOGGER.info("get menu and auth mation."); + String roleIds = userMation.get("roleId").toString(); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + List> authPoints = sysAuthorityService.getRoleHasMenuPointListByRoleIds(roleIds, userId); + + LOGGER.info("set menu and auth mation to redis cache start."); + jedisClientService.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + jedisClientService.set(ObjectConstant.getAllMenuCacheKey(userId), roleIds); + jedisClientService.set("authPointsMation:" + userId, roleIds); + LOGGER.info("set menu and auth mation to redis cache end."); + userMation.remove("roleId"); + return authPoints; + } + + /** + * 处理该用户的学校权限信息 + * + * @param userMation + * @param userId + */ + private void judgeAndGetSchoolMation(Map userMation, String userId) { + // 处理学校权限信息 + // 当前登录帐号包含某所学校的id + Map schoolMation = sysEveUserDao.queryUserSchoolMationByUserId(userId); + if (schoolMation != null && !schoolMation.isEmpty()) { + if (schoolMation.containsKey("schoolId") && !ToolUtil.isBlank(schoolMation.get("schoolId").toString())) { + // 判断该用户的学校的数据权限-----数据权限 1.查看所有 2.查看本校 + int power = schoolMation.containsKey("schoolPower") ? Integer.parseInt(schoolMation.get("schoolPower").toString()) : 2; + if (power == 2) { + // 将用户有权查看的学校id放入登录信息中 + userMation.put("schoolPowerId", schoolMation.get("schoolId").toString()); + } else { + userMation.put("schoolPowerId", "all"); + } + } + } + } + + /** + * 从session中获取用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserMationBySession(InputObject inputObject, OutputObject outputObject) { + Map userMation = inputObject.getLogParams(); + if (userMation == null) { + outputObject.setreturnMessage("登录超时,请重新登录。"); + } else { + outputObject.setBean(userMation); + } + } + + /** + * 退出 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteUserMationBySession(InputObject inputObject, OutputObject outputObject) { + String userId = GetUserToken.getUserTokenUserId(PutObject.getRequest()); + this.removeLogin(userId); + inputObject.removeSession(); + } + + /** + * 退出登录 + * + * @param userId 用户id + */ + @Override + public void removeLogin(String userId) { + SysUserAuthConstants.delUserLoginRedisCache(userId); + jedisClientService.del(ObjectConstant.getDeskTopsCacheKey(userId)); + jedisClientService.del(ObjectConstant.getAllMenuCacheKey(userId)); + jedisClientService.del("authPointsMation:" + userId); + if (userId.lastIndexOf(SysUserAuthConstants.APP_IDENTIFYING) < 0) { + // PC端用户登录信息 + } else { + // 手机端用户登录信息 + } + } + + /** + * 获取角色和当前已经绑定的角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryRoleAndBindRoleByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 获取角色列表 + List> roles = sysEveRoleService.queryAllDataForMap(); + // 获取用户绑定的角色ID串 + Map userRole = sysEveUserDao.queryBindRoleMationByUserId(map); + String[] roleIds = userRole.get("roleIds").toString().split(","); + for (Map bean : roles) { + if (Arrays.asList(roleIds).contains(bean.get("id").toString())) { + bean.put("isCheck", "checked"); + } + } + outputObject.setBeans(roles); + outputObject.settotal(roles.size()); + } + + /** + * 编辑用户绑定的角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editRoleIdsByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + sysEveUserDao.editRoleIdsByUserId(map); + } + + /** + * 获取当前登录用户的桌面菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDeskTopMenuBySession(InputObject inputObject, OutputObject outputObject) { + List> deskTops = inputObject.getLogDeskTopMenuParams(); + outputObject.setBeans(deskTops); + } + + /** + * 获取当前登录用户的所有菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllMenuBySession(InputObject inputObject, OutputObject outputObject) { + List> deskTops = inputObject.getLogAllMenuParams(); + outputObject.setBeans(deskTops); + } + + /** + * 修改密码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editUserPassword(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + // 根据redis中的用户信息userCode获取用户信息 + Map userMation = sysEveUserDao.queryMationByUserCode(user.get("userCode").toString()); + int pwdNum = Integer.parseInt(userMation.get("pwdNum").toString()); + String password = map.get("oldPassword").toString(); + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + if (password.equals(userMation.get("password").toString())) { + // 输入的旧密码数据库中的旧密码一致,转化新密码 + String newPassword = map.get("newPassword").toString(); + for (int i = 0; i < pwdNum; i++) { + newPassword = ToolUtil.MD5(newPassword); + } + // 更新数据库中的密码 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, user.get("id").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getPassword), newPassword); + update(updateWrapper); + } else { + outputObject.setreturnMessage("旧密码输入错误."); + } + } + + /** + * 锁屏密码解锁 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserLockByLockPwd(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + int pwdNum = Integer.parseInt(user.get("pwdNum").toString()); + String password = map.get("password").toString(); + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + if (!password.equals(user.get("password").toString())) { + outputObject.setreturnMessage("密码输入错误。"); + } + } + + /** + * 修改个人信息时获取数据回显 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject) { + Map user = inputObject.getLogParams(); + Map bean = sysEveUserDao.queryUserDetailsMationByUserId(user.get("id").toString()); + companyMationService.setNameMationForMap(bean, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(bean, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(bean, "jobId", "jobName", StrUtil.EMPTY); + companyJobScoreService.setNameMationForMap(bean, "jobScoreId", "jobScoreName", StrUtil.EMPTY); + outputObject.setBean(bean); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 修改个人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editUserDetailsMationByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + sysEveUserDao.editUserDetailsMationByUserId(map); + // 删除用户在redis中存储的信息 + jedisClientService.del(Constants.getSysTalkUserThisMainMationById(user.get("id").toString())); + } + + /** + * 获取该用户拥有的桌面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysDeskTopByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("id", user.get("id")); + List> beans = sysEveUserDao.querySysDeskTopByUserId(map); + outputObject.setBeans(beans); + } + + /** + * 根据用户id获取桌面菜单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDeskTopsMenuByUserId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = map.get("userId").toString(); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + outputObject.setBeans(deskTops); + outputObject.settotal(deskTops.size()); + } + + /** + * 人员选择获取所有公司和人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllPeopleToTree(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + List> result = new ArrayList<>(); + setOrganization(result, StringUtils.EMPTY); + List> beans = sysEveUserDao.queryUserStaffToTree(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + result.addAll(beans); + outputObject.setBeans(result); + } + + /** + * 设置组织信息 + * + * @param beans + * @param companyId + */ + private void setOrganization(List> beans, String companyId) { + beans.addAll(companyMationService.queryCompanyList(companyId)); + beans.addAll(companyDepartmentService.queryDepartmentList(Arrays.asList(companyId), new ArrayList<>())); + beans.addAll(companyJobService.queryJobList(Arrays.asList(companyId), new ArrayList<>())); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCompanyPeopleToTreeByUserBelongCompany(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + String companyId = inputObject.getLogParams().get("companyId").toString(); + queryDo.setCompanyId(companyId); + + List> result = new ArrayList<>(); + setOrganization(result, companyId); + List> beans = sysEveUserDao.queryUserStaffToTree(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + result.addAll(beans); + outputObject.setBeans(result); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司部门展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDepartmentPeopleToTreeByUserBelongDepartment(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + String companyId = inputObject.getLogParams().get("companyId").toString(); + queryDo.setCompanyId(companyId); + List> result = new ArrayList<>(); + result.addAll(companyMationService.queryCompanyList(companyId)); + result.addAll(companyDepartmentService.queryDepartmentList(Arrays.asList(companyId), new ArrayList<>())); + List> beans = sysEveUserDao.queryUserStaffDepToTree(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + result.addAll(beans); + outputObject.setBeans(result); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司岗位展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryJobPeopleToTreeByUserBelongJob(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + String companyId = inputObject.getLogParams().get("companyId").toString(); + queryDo.setCompanyId(companyId); + List> result = new ArrayList<>(); + setOrganization(result, companyId); + List> beans = sysEveUserDao.queryUserStaffToTree(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + result.addAll(beans); + outputObject.setBeans(result); + } + + /** + * 人员选择根据当前用户所属公司获取这个公司同级部门展示的人 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySimpleDepPeopleToTreeByUserBelongSimpleDep(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + String departmentId = inputObject.getLogParams().get("departmentId").toString(); + queryDo.setDepartmentId(departmentId); + List> beans = sysEveUserDao.queryUserStaffDepToTree(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + beans.addAll(companyDepartmentService.queryDepartmentList(new ArrayList<>(), Arrays.asList(inputObject.getLogParams().get("departmentId").toString()))); + outputObject.setBeans(beans); + } + + /** + * 根据聊天组展示用户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryTalkGroupUserListByUserId(InputObject inputObject, OutputObject outputObject) { + UserTreeQueryDo queryDo = inputObject.getParams(UserTreeQueryDo.class); + compareSelUserListByParams(queryDo, inputObject); + Map user = inputObject.getLogParams(); + queryDo.setUserId(user.get("id").toString()); + List> beans = sysEveUserDao.queryTalkGroupUserListByUserId(queryDo); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + outputObject.setBeans(beans); + } + + /** + * 获取人员列表时的参数转换 + * + * @param queryDo + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + public void compareSelUserListByParams(UserTreeQueryDo queryDo, InputObject inputObject) { + // 人员列表中是否包含自己--1.包含;其他参数不包含 + if (queryDo.getChooseOrNotMy() != 1) { + Map user = inputObject.getLogParams(); + queryDo.setUserId(user.get("id").toString()); + } + // 人员列表中是否必须绑定邮箱--1.必须;其他参数没必要 + if (queryDo.getChooseOrNotEmail() == 1) { + queryDo.setHasEmail(1); + } + } + + /** + * 手机端用户登录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPhoneToLogin(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userCode = map.get("userCode").toString(); + Map userMation = sysEveUserDao.queryMationByUserCode(userCode); + if (userMation == null) { + outputObject.setreturnMessage("请确保用户名输入无误!"); + } else { + int pwdNum = Integer.parseInt(userMation.get("pwdNum").toString()); + String password = map.get("password").toString(); + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + if (password.equals(userMation.get("password").toString())) { + int userLock = Integer.parseInt(userMation.get("userLock").toString()); + if (UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey() == userLock) { + outputObject.setreturnMessage("您的账号已被锁定,请联系管理员解除!"); + } else { + String userId = userMation.get("id").toString(); + String roleIds = userMation.get("roleId").toString(); + userMation.remove("roleId"); + + // 获取动态token + String userToken = GetUserToken.createNewToken(userId, password); + userMation.put("userToken", userToken); + + String appUserId = userId + SysUserAuthConstants.APP_IDENTIFYING; + companyDepartmentService.setNameMationForMap(userMation, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(userMation, "jobId", "jobName", StrUtil.EMPTY); + SysUserAuthConstants.setUserLoginRedisCache(appUserId, userMation); + jedisClientService.set(ObjectConstant.getAllMenuCacheKey(userId), roleIds); + jedisClientService.set("authPointsMation:" + appUserId, roleIds); + // 获取用户权限点返回给前台 + List> authPoints = sysAuthorityService.getRoleHasMenuPointListByRoleIds(roleIds, appUserId); + outputObject.setBean(userMation); + outputObject.setBeans(authPoints); + } + } else { + outputObject.setreturnMessage("密码输入错误!"); + } + } + } + + /** + * 根据openId获取用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserMationByOpenId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String openId = map.get("openId").toString(); + //判断该微信用户在redis中是否存在数据 + String key = WxchatUtil.getWechatUserOpenIdMation(openId); + if (ToolUtil.isBlank(jedisClientService.get(key))) { + //该用户没有绑定账号 + Map bean = sysEveUserDao.queryWxUserMationByOpenId(openId); + //判断该用户的openId是否存在于数据库 + if (bean != null && !bean.isEmpty()) { + //存在数据库 + map.putAll(bean); + //1.将微信和账号的绑定信息存入redis + jedisClientService.set(key, JSONUtil.toJsonStr(bean)); + //如果已经绑定用户,则获取用户信息 + if (bean.containsKey("userId") && !ToolUtil.isBlank(bean.get("userId").toString())) { + Map userMation = sysEveUserDao.queryUserMationByOpenId(openId); + companyMationService.setNameMationForMap(userMation, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(userMation, "departmentId", "departmentName", StrUtil.EMPTY); + // 2.将账号的信息存入redis + SysUserAuthConstants.setUserLoginRedisCache(bean.get("userId").toString() + SysUserAuthConstants.APP_IDENTIFYING, userMation); + //3.将权限的信息存入redis + jedisClientService.set("authPointsMation:" + bean.get("userId").toString() + SysUserAuthConstants.APP_IDENTIFYING, ""); + } + } else { + //不存在 + map.put("id", ToolUtil.getSurFaceId()); + map.put("joinTime", DateUtil.getTimeAndToString()); + map.put("openId", openId); + map.put("userId", ""); + sysEveUserDao.insertWxUserMation(map); + //1.将微信和账号的绑定信息存入redis + jedisClientService.set(key, JSONUtil.toJsonStr(map)); + } + } else { + map = JSONUtil.toBean(jedisClientService.get(key), null); + //如果已经绑定用户,则获取用户信息 + if (map.containsKey("userId") && !ToolUtil.isBlank(map.get("userId").toString())) { + Map userMation = sysEveUserDao.queryUserMationByOpenId(openId); + companyMationService.setNameMationForMap(userMation, "companyId", "companyName", StrUtil.EMPTY); + //2.将账号的信息存入redis + SysUserAuthConstants.setUserLoginRedisCache(map.get("userId").toString() + SysUserAuthConstants.APP_IDENTIFYING, userMation); + //3.将权限的信息存入redis + jedisClientService.set("authPointsMation:" + map.get("userId").toString() + SysUserAuthConstants.APP_IDENTIFYING, ""); + } else { + outputObject.setreturnMessage("您还未绑定用户,请前往绑定.", "-9000"); + } + } + outputObject.setBean(map); + } + + @Override + public void editUserLockState(String id, Integer userLock) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getUserLock), userLock); + update(updateWrapper); + } + + /** + * openId绑定用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void insertUserMationByOpenId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userCode = map.get("userCode").toString(); + String password = map.get("password").toString(); + String openId = map.get("openId").toString(); + // 根据账号获取用户信息 + Map userMation = sysEveUserDao.queryMationByUserCode(userCode); + // 判断该账号是否存在 + if (userMation != null && !userMation.isEmpty()) { + int pwdNum = Integer.parseInt(userMation.get("pwdNum").toString()); + for (int i = 0; i < pwdNum; i++) { + password = ToolUtil.MD5(password); + } + //判断密码是否正确 + if (password.equals(userMation.get("password").toString())) { + //判断账号是否锁定 + int userLock = Integer.parseInt(userMation.get("userLock").toString()); + if (UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey() == userLock) { + outputObject.setreturnMessage("您的账号已被锁定,请联系管理员解除."); + } else { + Map wxUserMation = sysEveUserDao.queryWxUserMationByOpenId(openId); + //判断该用户的openId是否存在于数据库 + if (wxUserMation != null && !wxUserMation.isEmpty()) { + //判断当前openId是否已经绑定账号 + if (wxUserMation.containsKey("userId") && !ToolUtil.isBlank(wxUserMation.get("userId").toString())) { + outputObject.setreturnMessage("该微信用户已绑定账号."); + } else { + //判断该账号是否被别人绑定 + Map isBindInWx = sysEveUserDao.queryUserBindMationByUserId(userMation.get("id").toString()); + if (isBindInWx != null && !isBindInWx.isEmpty()) { + outputObject.setreturnMessage("该账号已被绑定."); + } else { + companyJobService.setNameMationForMap(userMation, "jobId", "jobName", StrUtil.EMPTY); + //构建绑定信息对象 + map = new HashMap<>(); + String userId = userMation.get("id").toString(); + map.put("userId", userId); + map.put("bindTime", DateUtil.getTimeAndToString()); + map.put("openId", openId); + sysEveUserDao.updateBindUserMation(map); + //重新获取绑定信息,存入redis,返回前端 + map = sysEveUserDao.queryWxUserMationByOpenId(openId); + //1.将微信和账号的绑定信息存入redis + String key = WxchatUtil.getWechatUserOpenIdMation(openId); + jedisClientService.set(key, JSONUtil.toJsonStr(map)); + //2.将账号的信息存入redis + SysUserAuthConstants.setUserLoginRedisCache(userId + SysUserAuthConstants.APP_IDENTIFYING, userMation); + //3.将权限的信息存入redis + jedisClientService.set("authPointsMation:" + userId + SysUserAuthConstants.APP_IDENTIFYING, ""); + outputObject.setBean(map); + } + } + } else { + outputObject.setreturnMessage("该微信用户不存在."); + } + } + } else { + outputObject.setreturnMessage("密码输入错误."); + } + } else { + outputObject.setreturnMessage("该账号不存在,请核实后进行登录."); + } + } + + @Override + public void resetUserEffectiveDate(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + Integer isTermOfValidity = Integer.parseInt(map.get("isTermOfValidity").toString()); + String startTime = map.get("startTime").toString(); + String endTime = map.get("endTime").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getIsTermOfValidity), isTermOfValidity); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getStartTime), startTime); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUser::getEndTime), endTime); + update(updateWrapper); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffServiceImpl.java new file mode 100644 index 0000000..cd8e006 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffServiceImpl.java @@ -0,0 +1,507 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.UserStaffState; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.dao.WagesFieldTypeDao; +import com.skyeye.exception.CustomException; +import com.skyeye.organization.service.CompanyDepartmentService; +import com.skyeye.organization.service.CompanyJobScoreService; +import com.skyeye.organization.service.CompanyJobService; +import com.skyeye.organization.service.CompanyMationService; +import com.skyeye.personnel.classenum.StaffWagesStateEnum; +import com.skyeye.personnel.classenum.UserLockState; +import com.skyeye.personnel.dao.SysEveUserStaffDao; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.entity.SysEveUserStaffQuery; +import com.skyeye.personnel.service.SysEveUserService; +import com.skyeye.personnel.service.SysEveUserStaffService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: SysEveUserStaffServiceImpl + * @Description: 员工管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 12:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工管理", groupName = "员工管理") +public class SysEveUserStaffServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveUserStaffService { + + @Autowired + private SysEveUserStaffDao sysEveUserStaffDao; + + @Autowired + private SysEveUserService sysEveUserService; + + @Autowired + private WagesFieldTypeDao wagesFieldTypeDao; + + @Value("${skyeye.jobNumberPrefix}") + private String jobNumberPrefix; + + @Autowired + private CompanyMationService companyMationService; + + @Autowired + private CompanyDepartmentService companyDepartmentService; + + @Autowired + private CompanyJobService companyJobService; + + @Autowired + private CompanyJobScoreService companyJobScoreService; + + @Override + public void getQueryWrapper(InputObject inputObject, QueryWrapper wrapper) { + SysEveUserStaffQuery sysEveUserStaffQuery = inputObject.getParams(SysEveUserStaffQuery.class); + if (sysEveUserStaffQuery.getDesignWages() != null) { + wrapper.eq(MybatisPlusUtil.toColumns(SysEveUserStaff::getDesignWages), sysEveUserStaffQuery.getDesignWages()); + } + if (sysEveUserStaffQuery.getBindAccount() == WhetherEnum.DISABLE_USING.getKey()) { + // 未绑定账号 + String userIdKey = MybatisPlusUtil.toColumns(SysEveUserStaff::getUserId); + wrapper.and(wra -> { + wra.isNull(userIdKey).or().eq(userIdKey, StrUtil.EMPTY); + }); + } + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getType())) { + // 员工类型,参考#UserStaffType + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveUserStaff::getType), commonPageInfo.getType()); + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + beans.forEach(bean -> { + bean.put(CommonConstants.NAME, bean.get("jobNumber").toString() + "_" + bean.get("userName").toString()); + }); + // 设置组织信息 + companyMationService.setNameMationForMap(beans, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(beans, "jobId", "jobName", StrUtil.EMPTY); + companyJobScoreService.setNameMationForMap(beans, "jobScoreId", "jobScoreName", StrUtil.EMPTY); + return beans; + } + + @Override + public void validatorEntity(SysEveUserStaff entity) { + super.validatorEntity(entity); + if (StrUtil.isNotEmpty(entity.getPhone())) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveUserStaff::getPhone), entity.getPhone()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SysEveUserStaff checkUserStaff = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(checkUserStaff)) { + throw new CustomException("该手机号已存在,请更换."); + } + } + } + + @Override + public void createPrepose(SysEveUserStaff entity) { + // 设置新的工号 + QueryWrapper queryWrapper = new QueryWrapper<>(); + String jobNumberKey = MybatisPlusUtil.toColumns(SysEveUserStaff::getJobNumber); + queryWrapper.select("max(0 + RIGHT(" + jobNumberKey + ", 6)) AS " + jobNumberKey); + SysEveUserStaff sysEveUserStaff = getOne(queryWrapper, false); + entity.setJobNumber(jobNumberPrefix + CalculationUtil.add(sysEveUserStaff.getJobNumber(), CommonNumConstants.NUM_ONE.toString(), CommonNumConstants.NUM_ZERO)); + entity.setActWages(CommonNumConstants.NUM_ZERO.toString()); + entity.setAnnualLeave(CommonNumConstants.NUM_ZERO.toString()); + entity.setHolidayNumber(CommonNumConstants.NUM_ZERO.toString()); + entity.setRetiredHolidayNumber(CommonNumConstants.NUM_ZERO.toString()); + entity.setDesignWages(StaffWagesStateEnum.WAIT_DESIGN_WAGES.getKey()); + } + + @Override + public void createPostpose(SysEveUserStaff entity, String userId) { + // 新增员工薪资字段信息 + createUserStaffWagesFieldType(entity.getId()); + } + + @Override + public void updatePrepose(SysEveUserStaff entity) { + SysEveUserStaff oldData = selectById(entity.getId()); + entity.setUserId(oldData.getUserId()); + entity.setQuitTime(oldData.getQuitTime()); + entity.setQuitReason(oldData.getQuitReason()); + entity.setBecomeWorkerTime(oldData.getBecomeWorkerTime()); + entity.setType(oldData.getType()); + entity.setDesignWages(oldData.getDesignWages()); + entity.setActWages(oldData.getActWages()); + entity.setAnnualLeave(oldData.getAnnualLeave()); + entity.setAnnualLeaveStatisTime(oldData.getAnnualLeaveStatisTime()); + entity.setHolidayNumber(oldData.getHolidayNumber()); + entity.setHolidayStatisTime(oldData.getHolidayStatisTime()); + entity.setRetiredHolidayNumber(oldData.getRetiredHolidayNumber()); + entity.setRetiredHolidayStatisTime(oldData.getRetiredHolidayStatisTime()); + entity.setInterviewArrangementId(oldData.getInterviewArrangementId()); + } + + @Override + public void updatePostpose(SysEveUserStaff entity, String userId) { + SysEveUserStaff oldData = selectById(entity.getId()); + if (!StrUtil.equals(oldData.getDepartmentId(), entity.getDepartmentId())) { + // 新旧部门不一致,删除用户在redis中存储的好友组信息(旧的部门) + jedisClientService.delKeys(Constants.getSysTalkGroupUserListMationById(oldData.getDepartmentId()) + "*"); + // 删除用户在redis中存储的好友组信息(新的部门) + jedisClientService.delKeys(Constants.getSysTalkGroupUserListMationById(entity.getDepartmentId()) + "*"); + } + } + + @Override + public void writePostpose(SysEveUserStaff entity, String userId) { + super.writePostpose(entity, userId); + // 员工考勤时间段 + saveUserStaffCheckWorkTime(entity.getTimeIdList(), entity.getId()); + } + + /** + * 新增员工薪资字段信息 + * + * @param staffId + */ + private void createUserStaffWagesFieldType(String staffId) { + List> fieldType = wagesFieldTypeDao.queryAllWagesFieldTypeList(); + if (fieldType != null && !fieldType.isEmpty()) { + fieldType.stream().forEach(bean -> { + bean.put("id", staffId); + }); + wagesFieldTypeDao.insertWagesFieldTypeKeyToStaff(fieldType); + } + } + + /** + * 新增员工考勤时间段 + * + * @param timeIdList 班次id + * @param staffId 员工id + */ + private void saveUserStaffCheckWorkTime(List timeIdList, String staffId) { + // 删除员工考勤时间段信息再重新添加 + sysEveUserStaffDao.deleteStaffCheckWorkTimeRelationByStaffId(staffId); + // 逗号隔开的多班次考勤 + if (CollectionUtil.isNotEmpty(timeIdList)) { + // 校验多班次考勤是否有重复时间段 + boolean repeat = judgeRepeatShift(timeIdList); + if (repeat) { + // 存在冲突的工作时间段 + throw new CustomException("Conflicting working hours."); + } + List> staffTimeMation = new ArrayList<>(); + timeIdList.stream().forEach(timeId -> { + if (!ToolUtil.isBlank(timeId)) { + Map bean = new HashMap<>(); + bean.put("staffId", staffId); + bean.put("timeId", timeId); + staffTimeMation.add(bean); + } + }); + if (!staffTimeMation.isEmpty()) { + sysEveUserStaffDao.insertStaffCheckWorkTimeRelation(staffTimeMation); + } + } + } + + private boolean judgeRepeatShift(List timeIds) { + // 1.获取班次的上下班打卡时间 + List> timeMation = sysEveUserStaffDao.queryCheckTimeMationByTimeIds(timeIds); + // 2.获取班次的工作日 + List> timeDayMation = sysEveUserStaffDao.queryCheckTimeDaysMationByTimeIds(timeIds); + timeMation.forEach(bean -> { + List> thisDayMation = timeDayMation.stream() + .filter(item -> item.get("timeId").toString().equals(bean.get("timeId").toString())) + .collect(Collectors.toList()); + bean.put("days", thisDayMation); + }); + // 3.校验工作日是否冲突 + return judgeRepeatWorking(timeMation); + } + + private boolean judgeRepeatWorking(List> timeMation) { + if (timeMation.size() > 1) { + for (int i = 0; i < timeMation.size(); i++) { + for (int j = (i + 1); j < timeMation.size(); j++) { + List times = new ArrayList<>(); + times.add(timeMation.get(i).get("startTime").toString() + "-" + + timeMation.get(i).get("endTime").toString()); + times.add(timeMation.get(j).get("startTime").toString() + "-" + + timeMation.get(j).get("endTime").toString()); + // 1.首先判断每天的工作日的开始时间和结束时间是否有重复 + boolean flag = DateUtil.checkOverlap(times); + if (flag) { + // 开始时间和结束时间是否有重复 + List> iDayMation = (List>) timeMation.get(i) + .get("days"); + List> jDayMation = (List>) timeMation.get(j) + .get("days"); + // 求这两个班次的工作日冲突的天数,根据类型和工作日(周几)判断 + int size = iDayMation.stream() + .map(t -> jDayMation.stream() + .filter(s -> (Objects.equals(t.get("type").toString(), s.get("type").toString()) + || Objects.equals(t.get("type").toString(), "1") + || Objects.equals(s.get("type").toString(), "1")) + && Objects.equals(t.get("day").toString(), s.get("day").toString())) + .findAny().orElse(null)).filter(Objects::nonNull).collect(Collectors.toList()).size(); + if (size > 0) { + return true; + } + } + } + } + return false; + } else { + return false; + } + } + + @Override + public SysEveUserStaff selectById(String id) { + SysEveUserStaff sysEveUserStaff = super.selectById(id); + sysEveUserStaff.setStateName(UserStaffState.getNameByState(sysEveUserStaff.getState())); + // 员工考勤时间段信息 + List> staffTimeMation = sysEveUserStaffDao.queryStaffCheckWorkTimeRelationNameByStaffId(id); + sysEveUserStaff.setTimeList(staffTimeMation); + // 设置组织信息 + companyMationService.setNameDataMation(sysEveUserStaff, SysEveUserStaff::getCompanyId, StrUtil.EMPTY); + companyDepartmentService.setNameDataMation(sysEveUserStaff, SysEveUserStaff::getDepartmentId, StrUtil.EMPTY); + companyJobService.setNameDataMation(sysEveUserStaff, SysEveUserStaff::getJobId, StrUtil.EMPTY); + companyJobScoreService.setNameDataMation(sysEveUserStaff, SysEveUserStaff::getJobScoreId, StrUtil.EMPTY); + return sysEveUserStaff; + } + + /** + * 员工离职 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysUserStaffState(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("id").toString(); + // 设置离职信息 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, staffId); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getState), UserStaffState.QUIT.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getQuitTime), map.get("quitTime").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getQuitReason), map.get("quitReason").toString()); + update(updateWrapper); + + SysEveUserStaff staffMation = selectById(staffId); + if (!ToolUtil.isBlank(staffMation.getUserId())) { + // 删除redis中缓存的单位下的用户 + jedisClientService.delKeys(Constants.getSysTalkGroupUserListMationById(staffMation.getDepartmentId()) + "*"); + // 锁定帐号 + sysEveUserService.editUserLockState(staffMation.getUserId(), UserLockState.SYS_USER_LOCK_STATE_ISLOCK.getKey()); + // 退出登录 + sysEveUserService.removeLogin(staffMation.getUserId()); + } + } + + /** + * 修改员工类型 + * + * @param id 员工id + * @param type 参考#UserStaffType + */ + @Override + public void updateStaffType(String id, Integer type) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getType), type); + update(updateWrapper); + } + + /** + * 获取当前登录员工的信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysUserStaffLogin(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + SysEveUserStaff sysEveUserStaff = selectById(staffId); + outputObject.setBean(sysEveUserStaff); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + /** + * 根据用户ids/员工ids获取员工信息集合 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryUserMationList(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String userIds = params.get("userIds").toString(); + String staffIds = params.get("staffIds").toString(); + List> beans = new ArrayList<>(); + // 用户id和员工id只要有一个不为空就进行查询 + if (!ToolUtil.isBlank(userIds) || !ToolUtil.isBlank(staffIds)) { + beans = sysEveUserStaffDao.queryUserMationList(userIds, staffIds); + // 设置组织信息 + companyMationService.setNameMationForMap(beans, "companyId", "companyName", StrUtil.EMPTY); + companyDepartmentService.setNameMationForMap(beans, "departmentId", "departmentName", StrUtil.EMPTY); + companyJobService.setNameMationForMap(beans, "jobId", "jobName", StrUtil.EMPTY); + companyJobScoreService.setNameMationForMap(beans, "jobScoreId", "jobScoreName", StrUtil.EMPTY); + } + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 修改员工剩余年假信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editSysUserStaffAnnualLeaveById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String quarterYearHour = map.get("quarterYearHour").toString(); + String annualLeaveStatisTime = map.get("annualLeaveStatisTime").toString(); + sysEveUserStaffDao.editSysUserStaffAnnualLeaveById(staffId, quarterYearHour, annualLeaveStatisTime); + } + + /** + * 修改员工的补休池剩余补休信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void updateSysUserStaffHolidayNumberById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String holidayNumber = map.get("holidayNumber").toString(); + String holidayStatisTime = map.get("holidayStatisTime").toString(); + sysEveUserStaffDao.updateSysUserStaffHolidayNumberById(staffId, holidayNumber, holidayStatisTime); + } + + /** + * 修改员工的补休池已休补休信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void updateSysUserStaffRetiredHolidayNumberById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String retiredHolidayNumber = map.get("retiredHolidayNumber").toString(); + String retiredHolidayStatisTime = map.get("retiredHolidayStatisTime").toString(); + sysEveUserStaffDao.updateSysUserStaffRetiredHolidayNumberById(staffId, retiredHolidayNumber, retiredHolidayStatisTime); + } + + /** + * 根据员工id获取该员工的考勤时间段 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStaffCheckWorkTimeRelationNameByStaffId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + // 员工考勤时间段信息 + List> staffTimeMation = sysEveUserStaffDao.queryStaffCheckWorkTimeRelationNameByStaffId(staffId); + outputObject.setBeans(staffTimeMation); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void editSysUserStaffBindUserId(String staffId, String userId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, staffId); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getUserId), userId); + update(updateWrapper); + } + + @Override + public void queryAllSysUserIsIncumbency(InputObject inputObject, OutputObject outputObject) { + List list = new ArrayList<>(); + list.add(UserStaffState.ON_THE_JOB.getKey()); + list.add(UserStaffState.PROBATION.getKey()); + list.add(UserStaffState.PROBATION_PERIOD.getKey()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(SysEveUserStaff::getState), list); + String userIdKey = MybatisPlusUtil.toColumns(SysEveUserStaff::getUserId); + queryWrapper.isNotNull(userIdKey).ne(userIdKey, StrUtil.EMPTY); + List userStaffList = list(queryWrapper); + List> mapList = userStaffList.stream() + .map(userStaff -> { + Map map = new HashMap<>(); + map.put("id", userStaff.getUserId()); + map.put("name", userStaff.getUserName()); + map.put("email", userStaff.getEmail()); + return map; + }).collect(Collectors.toList()); + outputObject.setBeans(mapList); + outputObject.settotal(mapList.size()); + } + + @Override + public void editSysUserStaffActMoneyById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String actMoney = map.get("actMoney").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, staffId); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getDesignWages), StaffWagesStateEnum.TOO_DESIGN_WAGES.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(SysEveUserStaff::getActWages), actMoney); + update(updateWrapper); + } + + @Override + public boolean checkPhoneExists(String phone) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveUserStaff::getPhone), phone); + long count = count(queryWrapper); + return count == 0 ? false : true; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffTeacherServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffTeacherServiceImpl.java new file mode 100644 index 0000000..6b27614 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/personnel/service/impl/SysEveUserStaffTeacherServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.personnel.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.exception.CustomException; +import com.skyeye.personnel.classenum.UserStaffType; +import com.skyeye.personnel.dao.SysEveUserStaffTeacherDao; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.entity.SysEveUserStaffTeacher; +import com.skyeye.personnel.service.SysEveUserStaffService; +import com.skyeye.personnel.service.SysEveUserStaffTeacherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: SysEveUserStaffTeacherServiceImpl + * @Description: 员工所属学校关系服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/23 21:39 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "员工所属学校关系管理", groupName = "员工管理", manageShow = false) +public class SysEveUserStaffTeacherServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveUserStaffTeacherService { + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Override + public void createPrepose(SysEveUserStaffTeacher entity) { + SysEveUserStaff sysEveUserStaff = sysEveUserStaffService.selectById(entity.getStaffId()); + if (ObjectUtil.isNotEmpty(sysEveUserStaff)) { + // 如果是普通员工,则允许转教职工 + if (sysEveUserStaff.getType() == UserStaffType.SIMPLE_STAFF.getKey()) { + // 修改员工类型 + sysEveUserStaffService.updateStaffType(entity.getStaffId(), UserStaffType.TEACHER.getKey()); + } else { + throw new CustomException("该员工无法转教职工。"); + } + } else { + throw new CustomException("The data does not exist"); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/phone/websocket/PhoneSocket.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/phone/websocket/PhoneSocket.java new file mode 100644 index 0000000..76f7d56 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/phone/websocket/PhoneSocket.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.phone.websocket; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CompanyTalkGroupDao; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author 卫志强 + * @ClassName: PhoneSocket + * @Description: 手机端消息 + * @date 2020年3月19日 + */ +@Component +@ServerEndpoint("/phonetalkwebsocket/{userId}") +public class PhoneSocket { + + /** + * 在线人数 + */ + public static int onlineNumber = 0; + /** + * 以用户的姓名为key,WebSocket为对象保存起来 + */ + private static Map clients = new ConcurrentHashMap(); + /** + * 会话 + */ + private Session session; + /** + * 用户id + */ + private String userId; + + /** + * 建立连接 + * + * @param session + */ + @OnOpen + public void onOpen(@PathParam("userId") String userId, Session session) { + //判断该用户是否已经注册 + if (!clients.containsKey(userId)) { + onlineNumber++; + System.out.println("手机端:现在来连接的客户id:" + session.getId() + "用户名:" + userId); + this.userId = userId; + this.session = session; + System.out.println("手机端:有新连接加入! 当前在线人数" + onlineNumber); + try { + // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息 5系统消息 6全体消息 7群组邀请消息 8隐身消息 9隐身上线消息 10搜索账号入群审核同意后通知用户加载群信息 11群聊消息 + //12 退出群聊 13解散群聊 + // 先给所有人发送通知,说我上线了 + Map map1 = new HashMap<>(); + map1.put("messageType", 1); + map1.put("userId", userId); + sendMessageAll(JSONUtil.toJsonStr(map1), userId); + + // 把自己的信息加入到map当中去 + clients.put(userId, this); + // 给自己发一条消息:告诉自己现在都有谁在线 + Map map2 = new HashMap<>(); + map2.put("messageType", 3); + // 移除掉自己 + Set set = clients.keySet(); + map2.put("onlineUsers", set); + sendMessageTo(JSONUtil.toJsonStr(map2), userId); + } catch (IOException e) { + System.out.println(userId + "上线的时候通知所有人发生了错误"); + } + } + + } + + @OnError + public void onError(Session session, Throwable error) { + System.out.println("手机端:服务端发生了错误" + error.getMessage()); + } + + /** + * 连接关闭 + */ + @OnClose + public void onClose() { + if (!ToolUtil.isBlank(userId)) { + onlineNumber--; + clients.remove(userId); + try { + // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息 5系统消息 6全体消息 7群组邀请消息 8隐身消息 9隐身上线消息 10搜索账号入群审核同意后通知用户加载群信息 11群聊消息 + //12 退出群聊 13解散群聊 + Map map1 = new HashMap<>(); + map1.put("messageType", 2); + map1.put("onlineUsers", clients.keySet()); + map1.put("userId", userId); + sendMessageAll(JSONUtil.toJsonStr(map1), userId); + } catch (IOException e) { + System.out.println(userId + "下线的时候通知所有人发生了错误"); + } + System.out.println("手机端:有连接关闭! 当前在线人数" + onlineNumber); + } + } + + /** + * 收到客户端的消息 + * + * @param message 消息 + * @param session 会话 + */ + @OnMessage + public void onMessage(String message, Session session) { + try { + System.out.println("来自客户端消息:" + message + "客户端的id是:" + session.getId()); + JSONObject jsonObject = JSONUtil.toBean(message, null); + String type = jsonObject.getStr("type"); + // messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息 5系统消息 6全体消息 7群组邀请消息 8隐身消息 9隐身上线消息 10搜索账号入群审核同意后通知用户加载群信息 11群聊消息 + //12 退出群聊 13解散群聊 + Map map1 = new HashMap<>(); + if ("4".equals(type)) {//普通消息 + map1.put("messageType", type); + map1.put("avatar", jsonObject.getStr("avatar"));//头像 + map1.put("textMessage", jsonObject.getStr("message"));//消息 + map1.put("username", jsonObject.getStr("username"));//收件人名称 + map1.put("fromId", jsonObject.getStr("userId"));//发件人id + map1.put("toId", jsonObject.getStr("to"));//收件人id + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + map1.put("createTime", DateUtil.getTimeAndToString()); + map1.put("dataId", ToolUtil.getSurFaceId()); + companyTalkGroupDao.insertPersonToPersonMessage(map1); + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if ("5".equals(type)) {//系统消息 + + } else if ("6".equals(type)) {//全体消息 + map1.put("messageType", type); + map1.put("avatar", jsonObject.getStr("avatar"));//头像 + map1.put("textMessage", jsonObject.getStr("message"));//消息 + map1.put("username", jsonObject.getStr("username"));//收件人名称 + map1.put("fromId", jsonObject.getStr("userId"));//发件人id + map1.put("tousername", "所有人"); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if ("7".equals(type)) {//群组邀请消息 + map1.put("messageType", type); + map1.put("toId", jsonObject.getStr("to"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if ("8".equals(type)) {//隐身消息 + map1.put("messageType", type); + map1.put("userId", jsonObject.getStr("userId")); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if ("9".equals(type)) {//隐身上线消息 + map1.put("messageType", type); + map1.put("userId", jsonObject.getStr("userId")); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if ("10".equals(type)) {//搜索账号入群审核同意后通知用户加载群信息 + map1.put("messageType", type); + map1.put("avatar", jsonObject.getStr("avatar"));//头像 + map1.put("groupname", jsonObject.getStr("groupname"));//群聊名称 + map1.put("id", jsonObject.getStr("id"));//群聊id + map1.put("toId", jsonObject.getStr("to"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if ("11".equals(type)) {//群聊 + map1.put("messageType", type); + map1.put("avatar", jsonObject.getStr("avatar"));//头像 + map1.put("textMessage", jsonObject.getStr("message"));//消息 + map1.put("username", jsonObject.getStr("username"));//发消息人名称 + map1.put("id", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map1.put("userId", jsonObject.getStr("userId"));//群聊消息不发送给自己 + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + Map groupState = companyTalkGroupDao.queryGroupStateById(map1); + if ("1".equals(groupState.get("state").toString())) {//正常 + //插入消息记录 + map1.put("createTime", DateUtil.getTimeAndToString()); + map1.put("dataId", ToolUtil.getSurFaceId()); + companyTalkGroupDao.insertPersonToGroupMessage(map1); + List> members = companyTalkGroupDao.queryGroupMemberByGroupIdAndNotThisUser(map1); + if (members.size() > 0) { + for (Map member : members) { + map1.put("toId", member.get("id"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), member.get("id").toString()); + } + } + } else { + map1.clear(); + map1.put("messageType", "1301"); + map1.put("groupId", jsonObject.getStr("to"));//收件人id,在此处为群聊id + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } + } else if ("12".equals(type)) {//退出群聊--创建人接收消息 + map1.put("messageType", type); + map1.put("groupId", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map1.put("userName", jsonObject.getStr("userName"));//退群人名称 + map1.put("userId", jsonObject.getStr("userId"));//群聊消息不发送给自己 + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + Map groupMation = companyTalkGroupDao.queryGroupCreateIdById(map1); + map1.put("toId", groupMation.get("createId"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), groupMation.get("createId").toString()); + } else if ("13".equals(type)) {//解散群聊--所有人接收消息 + map1.put("messageType", type); + map1.put("id", jsonObject.getStr("to"));//收件人id,在此处为群聊id + map1.put("userName", jsonObject.getStr("userName"));//群主 + map1.put("userId", jsonObject.getStr("userId"));//群主id + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + List> members = companyTalkGroupDao.queryGroupMemberByGroupIdAndNotThisUser(map1); + if (members.size() > 0) { + for (Map member : members) { + map1.put("toId", member.get("id"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), member.get("id").toString()); + } + } + } + } catch (Exception e) { + System.out.println("发生了错误了"); + } + } + + /** + * 发送给指定用户消息 + * + * @param message + * @param ToUserName + * @throws IOException + */ + public void sendMessageTo(String message, String ToUserName) throws IOException { + for (PhoneSocket item : clients.values()) { + if (item.userId.equals(ToUserName)) { + item.session.getAsyncRemote().sendText(message); + break; + } + } + } + + /** + * 发送给全部用户消息 + * + * @param message + * @param FromUserName + * @throws IOException + */ + public void sendMessageAll(String message, String FromUserName) throws IOException { + for (PhoneSocket item : clients.values()) { + item.session.getAsyncRemote().sendText(message); + } + } + + /** + * 获取当前在线的用户id + * + * @return + */ + public static Set getOnlineUserId() { + return clients.keySet(); + } + + public static synchronized int getOnlineCount() { + return onlineNumber; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/controller/SysEveRoleController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/controller/SysEveRoleController.java new file mode 100644 index 0000000..0bf45a0 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/controller/SysEveRoleController.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.role.entity.Role; +import com.skyeye.role.service.SysEveRoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveRoleController + * @Description: 角色管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/12 21:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "角色管理", tags = "角色管理", modelName = "基础模块") +public class SysEveRoleController { + + @Autowired + private SysEveRoleService sysEveRoleService; + + /** + * 获取角色列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys013", value = "获取角色列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveRoleController/querySysRoleList") + public void querySysRoleList(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysRole", value = "新增/编辑角色", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Role.class) + @RequestMapping("/post/SysEveRoleController/writeSysRole") + public void writeSysRole(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询角色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysRoleById", value = "根据id查询角色信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "角色ID", required = "required")}) + @RequestMapping("/post/SysEveRoleController/querySysRoleById") + public void querySysRoleById(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.selectById(inputObject, outputObject); + } + + /** + * 删除角色 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteRoleById", value = "删除角色", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "角色ID", required = "required")}) + @RequestMapping("/post/SysEveRoleController/deleteRoleById") + public void deleteRoleById(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有模块(桌面)/菜单/权限点/分组/数据权限列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys014", value = "获取所有模块(桌面)/菜单/权限点/分组/数据权限列表", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveRoleController/querySysRoleBandMenuList") + public void querySysRoleBandMenuList(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.querySysRoleBandMenuList(inputObject, outputObject); + } + + /** + * 编辑角色PC端权限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editSysRolePCAuth", value = "编辑角色PC端权限", method = "PUT", allUse = "1") + @ApiImplicitParams(classBean = Role.class, value = { + @ApiImplicitParam(id = "rowId", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveRoleController/editSysRolePCAuth") + public void editSysRolePCAuth(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.editSysRolePCAuth(inputObject, outputObject); + } + + /** + * 获取角色需要绑定的手机端菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys037", value = "获取角色需要绑定的手机端菜单列表", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveRoleController/querySysRoleBandAppMenuList") + public void querySysRoleBandAppMenuList(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.querySysRoleBandAppMenuList(inputObject, outputObject); + } + + /** + * 手机端菜单授权 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sys039", value = "手机端菜单授权", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "menuIds", name = "menuIds", value = "菜单权限", required = "required"), + @ApiImplicitParam(id = "pointIds", name = "pointIds", value = "权限点"), + @ApiImplicitParam(id = "id", name = "id", value = "角色ID", required = "required")}) + @RequestMapping("/post/SysEveRoleController/editSysRoleAppMenuById") + public void editSysRoleAppMenuById(InputObject inputObject, OutputObject outputObject) { + sysEveRoleService.editSysRoleAppMenuById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/dao/SysEveRoleDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/dao/SysEveRoleDao.java new file mode 100644 index 0000000..47f383a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/dao/SysEveRoleDao.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.role.entity.Role; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveRoleDao + * @Description: 角色管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveRoleDao extends SkyeyeBaseMapper { + + int insertSysRoleMenuMation(List> beans); + + List querySysRoleMenuIdByRoleId(@Param("roleId") String roleId); + + int deleteRoleMenuByRoleId(@Param("roleId") String roleId); + + Integer queryUserRoleByRoleId(@Param("roleId") String roleId); + + List querySysRoleAppMenuIdByRoleId(@Param("roleId") String roleId); + + int deleteRoleAppMenuByRoleId(Map map); + + int insertSysRoleAppMenuMation(List> beans); + + int deleteRoleAppPointByRoleId(Map map); + + int insertSysRoleAppPointMation(List> beans); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/entity/Role.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/entity/Role.java new file mode 100644 index 0000000..833da32 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/entity/Role.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Role + * @Description: 角色管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/12 21:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "sys:role", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "sys_eve_role") +@ApiModel("角色管理实体类") +public class Role extends BaseGeneralInfo { + + @TableField("parent_id") + @ApiModelProperty(value = "所属父节点id") + private String parentId; + + @TableField(exist = false) + @ApiModelProperty(value = "PC端菜单权限") + private List menuIds; + + @TableField(exist = false) + @Property(value = "手机端菜单权限") + private List appMenuIds; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/SysEveRoleService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/SysEveRoleService.java new file mode 100644 index 0000000..21c1c6e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/SysEveRoleService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.role.entity.Role; + +public interface SysEveRoleService extends SkyeyeBusinessService { + + void querySysRoleBandMenuList(InputObject inputObject, OutputObject outputObject); + + void querySysRoleBandAppMenuList(InputObject inputObject, OutputObject outputObject); + + void editSysRoleAppMenuById(InputObject inputObject, OutputObject outputObject); + + void editSysRolePCAuth(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/impl/SysEveRoleServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/impl/SysEveRoleServiceImpl.java new file mode 100644 index 0000000..b1a5134 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/role/service/impl/SysEveRoleServiceImpl.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.role.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.menu.dao.AppWorkPageDao; +import com.skyeye.menu.dao.SysEveMenuDao; +import com.skyeye.role.dao.SysEveRoleDao; +import com.skyeye.role.entity.Role; +import com.skyeye.role.service.SysEveRoleService; +import com.skyeye.win.service.SysEveDesktopService; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveRoleServiceImpl + * @Description: 角色管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 11:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "角色管理", groupName = "系统设置") +public class SysEveRoleServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveRoleService { + + private static Logger LOGGER = LoggerFactory.getLogger(SysEveRoleServiceImpl.class); + + @Autowired + private SysEveRoleDao sysEveRoleDao; + + @Autowired + private SysEveMenuDao sysEveMenuDao; + + @Autowired + private AppWorkPageDao appWorkPageDao; + + @Autowired + private SysEveDesktopService sysEveDesktopService; + + @Override + public Role getDataFromDb(String id) { + Role role = super.getDataFromDb(id); + List menuIds = sysEveRoleDao.querySysRoleMenuIdByRoleId(id); + List appMenuIds = sysEveRoleDao.querySysRoleAppMenuIdByRoleId(id); + role.setMenuIds(menuIds); + role.setAppMenuIds(appMenuIds); + return role; + } + + @Override + public List getDataFromDb(List idList) { + List roles = super.getDataFromDb(idList); + for (Role role : roles) { + List menuIds = sysEveRoleDao.querySysRoleMenuIdByRoleId(role.getId()); + List appMenuIds = sysEveRoleDao.querySysRoleAppMenuIdByRoleId(role.getId()); + role.setMenuIds(menuIds); + role.setAppMenuIds(appMenuIds); + } + return roles; + } + + @Override + public void updatePostpose(Role entity, String userId) { + // 删除缓存 + deleteRoleCache(entity.getId(), "delete"); + } + + /** + * 获取所有模块(桌面)/菜单/权限点/分组/数据权限列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysRoleBandMenuList(InputObject inputObject, OutputObject outputObject) { + List> beans = sysEveMenuDao.queryAllMenuList(); + // 获取桌面信息 + List> desktopList = sysEveDesktopService.queryAllDataForMap(); + beans.addAll(desktopList); + + String[] str; + for (Map bean : beans) { + str = bean.get("pId").toString().split(","); + bean.put("pId", str[str.length - 1]); + } + outputObject.setBeans(beans); + } + + /** + * 编辑角色PC端权限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysRolePCAuth(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + String roleId = map.get("id").toString(); + saveRoleMenuMation(map, roleId, user.get("id").toString(), DateUtil.getTimeAndToString()); + // 删除缓存 + deleteRoleCache(roleId, "delete"); + refreshCache(roleId); + } + + private void saveRoleMenuMation(Map map, String roleId, String createId, String createTime) { + List menuIds = (List) map.get("menuIds"); + // 删除角色菜单关联表信息 + sysEveRoleDao.deleteRoleMenuByRoleId(roleId); + if (menuIds.size() > 0) { + List> beans = new ArrayList<>(); + menuIds.stream().forEach(str -> { + Map item = new HashMap<>(); + item.put("id", ToolUtil.getSurFaceId()); + item.put("roleId", roleId); + item.put("menuId", str); + item.put("createId", createId); + item.put("createTime", createTime); + beans.add(item); + }); + sysEveRoleDao.insertSysRoleMenuMation(beans); + } + } + + @Override + public void deletePreExecution(String id) { + // 判断当前是否有用户在使用该角色 + Integer useNum = sysEveRoleDao.queryUserRoleByRoleId(id); + if (useNum > 0) { + throw new CustomException("该角色下有用户正在使用,只能对角色进行维护."); + } + } + + @Override + public void deletePostpose(String id) { + // 删除角色菜单关联表信息 + sysEveRoleDao.deleteRoleMenuByRoleId(id); + // 删除缓存 + deleteRoleCache(id, "delete"); + } + + /** + * 获取角色需要绑定的手机端菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysRoleBandAppMenuList(InputObject inputObject, OutputObject outputObject) { + List> beans = appWorkPageDao.queryAllAppMenuList(); + // 获取桌面信息 + List> desktopList = sysEveDesktopService.queryAllDataForMap(); + beans.addAll(desktopList); + outputObject.setBeans(beans); + } + + /** + * 手机端菜单授权 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSysRoleAppMenuById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String[] menuIds = map.get("menuIds").toString().split(","); + if (menuIds.length > 0) { + String roleId = map.get("id").toString(); + // 桌面模块信息以及菜单页面信息 + List> menuList = new ArrayList<>(); + for (String str : menuIds) { + Map item = new HashMap<>(); + item.put("id", ToolUtil.getSurFaceId()); + item.put("roleId", roleId); + item.put("menuId", str); + menuList.add(item); + } + sysEveRoleDao.deleteRoleAppMenuByRoleId(map); + sysEveRoleDao.insertSysRoleAppMenuMation(menuList); + + // 权限点信息以及数据权限信息 + List> authPointList = new ArrayList<>(); + String[] pointIds = map.get("pointIds").toString().split(","); + if (pointIds.length > 0) { + for (String str : pointIds) { + Map item = new HashMap<>(); + item.put("id", ToolUtil.getSurFaceId()); + item.put("roleId", roleId); + item.put("pointId", str); + authPointList.add(item); + } + } + sysEveRoleDao.deleteRoleAppPointByRoleId(map); + if (!authPointList.isEmpty()) { + sysEveRoleDao.insertSysRoleAppPointMation(authPointList); + } + // 删除角色关联的APP菜单信息 + deleteAPPRoleCache(roleId); + refreshCache(roleId); + } else { + outputObject.setreturnMessage("请选择该角色即将拥有的权限!"); + } + } + + private void deleteRoleCache(String roleId, String type) { + LOGGER.info("delete Role Cache, roleId is {}", roleId); + jedisClientService.del(String.format("roleHasMenu:%s", roleId)); + jedisClientService.del(String.format("roleHasMenuPoint:%s", roleId)); + if ("delete".equals(type)) { + deleteAPPRoleCache(roleId); + } + } + + private void deleteAPPRoleCache(String roleId) { + LOGGER.info("delete Role app Cache"); + jedisClientService.del(String.format("roleHasAppMenu:%s", roleId)); + jedisClientService.del(String.format("roleHasAppMenuPoint:%s", roleId)); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsChannelEnum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsChannelEnum.java new file mode 100644 index 0000000..1064777 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsChannelEnum.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.classenum; + +import cn.hutool.core.util.ArrayUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: SmsChannelEnum + * @Description: 短信渠道枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SmsChannelEnum implements SkyeyeEnumClass { + + DEBUG_DING_TALK("debug_ding_talk", "调试(钉钉)", true, false), + ALIYUN("aliyun", "阿里云", true, true), + TENCENT("tencent", "腾讯云", true, false), + HUAWEI("huawei", "华为云", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static SmsChannelEnum getByCode(String code) { + return ArrayUtil.firstMatch(o -> o.getKey().equals(code), values()); + } + + public static Map getMation(String code) { + SmsChannelEnum type = getByCode(code); + Map result = new HashMap<>(); + result.put("id", type.getKey()); + result.put("name", type.getValue()); + return result; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateAuditStatusEnum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateAuditStatusEnum.java new file mode 100644 index 0000000..a332f05 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateAuditStatusEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SmsTemplateAuditStatusEnum + * @Description: 短信模板的审核状态枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SmsTemplateAuditStatusEnum implements SkyeyeEnumClass { + + CHECKING(1, "审核中", true, false), + SUCCESS(2, "通过", true, false), + FAIL(3, "失败", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateTypeEnum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateTypeEnum.java new file mode 100644 index 0000000..33436b1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/classenum/SmsTemplateTypeEnum.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SmsTemplateTypeEnum + * @Description: 短信的模板类型枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 21:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SmsTemplateTypeEnum implements SkyeyeEnumClass { + + VERIFICATION_CODE(1, "验证码", true, false), + NOTICE(2, "通知", true, true), + PROMOTION(3, "营销", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsChannelController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsChannelController.java new file mode 100644 index 0000000..3f54ed9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsChannelController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.sms.entity.SmsChannel; +import com.skyeye.sms.service.SmsChannelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SmsChannelController + * @Description: 短信渠道控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "短信渠道", tags = "短信渠道", modelName = "短信渠道") +public class SmsChannelController { + + @Autowired + private SmsChannelService smsChannelService; + + @ApiOperation(id = "querySmsChannelList", value = "获取短信渠道列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SmsChannelController/querySmsChannelList") + public void querySmsChannelList(InputObject inputObject, OutputObject outputObject) { + smsChannelService.queryPageList(inputObject, outputObject); + } + + /** + * 获取全部已启用的短信渠道信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEnabledList", value = "获取全部已启用的短信渠道信息", method = "POST", allUse = "2") + @RequestMapping("/post/SmsChannelController/SmsChannelController") + public void queryAllEnabledList(InputObject inputObject, OutputObject outputObject) { + smsChannelService.queryList(inputObject, outputObject); + } + + @ApiOperation(id = "writeSmsChannel", value = "新增/编辑短信渠道", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SmsChannel.class) + @RequestMapping("/post/SmsChannelController/writeSmsChannel") + public void writeSmsChannel(InputObject inputObject, OutputObject outputObject) { + smsChannelService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "deleteSmsChannelById", value = "删除短信渠道", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SmsChannelController/deleteSmsChannelById") + public void deleteSmsChannelById(InputObject inputObject, OutputObject outputObject) { + smsChannelService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "queryEnabledSmsChannelList", value = "获取所有启动的短信渠道列表", method = "GET", allUse = "2") + @RequestMapping("/post/SmsChannelController/queryEnabledSmsChannelList") + public void queryEnabledSmsChannelList(InputObject inputObject, OutputObject outputObject) { + smsChannelService.queryEnabledSmsChannelList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsCodeController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsCodeController.java new file mode 100644 index 0000000..28a90af --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsCodeController.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.sms.entity.SmsCodeSendReq; +import com.skyeye.sms.entity.SmsCodeUseReq; +import com.skyeye.sms.entity.SmsCodeValidateReq; +import com.skyeye.sms.service.SmsCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SmsCodeController + * @Description: 短信验证码控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/30 12:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "短信验证码", tags = "短信验证码", modelName = "短信验证码") +public class SmsCodeController { + + @Autowired + private SmsCodeService smsCodeService; + + @ApiOperation(id = "sendSmsCodeReq", value = "创建短信验证码,并进行发送", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = SmsCodeSendReq.class) + @RequestMapping("/post/SmsCodeController/sendSmsCodeReq") + public void sendSmsCodeReq(InputObject inputObject, OutputObject outputObject) { + smsCodeService.sendSmsCodeReq(inputObject, outputObject); + } + + @ApiOperation(id = "useSmsCodeReq", value = "验证短信验证码,并进行使用", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = SmsCodeUseReq.class) + @RequestMapping("/post/SmsCodeController/useSmsCodeReq") + public void useSmsCodeReq(InputObject inputObject, OutputObject outputObject) { + smsCodeService.useSmsCodeReq(inputObject, outputObject); + } + + @ApiOperation(id = "validateSmsCode", value = "检查验证码是否有效", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = SmsCodeValidateReq.class) + @RequestMapping("/post/SmsCodeController/validateSmsCode") + public void validateSmsCode(InputObject inputObject, OutputObject outputObject) { + smsCodeService.validateSmsCode(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsTemplateController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsTemplateController.java new file mode 100644 index 0000000..4cb83d5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/controller/SmsTemplateController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.sms.entity.SmsTemplate; +import com.skyeye.sms.service.SmsTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SmsTemplateController + * @Description: 短信模板控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/31 0:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "短信模板", tags = "短信模板", modelName = "短信模板") +public class SmsTemplateController { + + @Autowired + private SmsTemplateService smsTemplateService; + + /** + * 获取短信模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySmsTemplatelList", value = "获取短信模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SmsTemplatelController/querySmsTemplatelList") + public void querySmsTemplatelList(InputObject inputObject, OutputObject outputObject) { + smsTemplateService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑短信模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSmsTemplatel", value = "新增/编辑短信模板", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SmsTemplate.class) + @RequestMapping("/post/SmsTemplatelController/writeSmsTemplatel") + public void writeSmsTemplatel(InputObject inputObject, OutputObject outputObject) { + smsTemplateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除短信模板 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSmsTemplatelById", value = "删除短信模板", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SmsTemplatelController/deleteSmsTemplatelById") + public void deleteSmsTemplatelById(InputObject inputObject, OutputObject outputObject) { + smsTemplateService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsCodeProperties.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsCodeProperties.java new file mode 100644 index 0000000..88de98f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsCodeProperties.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import java.time.Duration; + +/** + * @ClassName: SmsCodeProperties + * @Description: 配置 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@ConfigurationProperties(prefix = "skyeye.sms-code") +@Validated +@Data +public class SmsCodeProperties { + + /** + * 过期时间 + */ + @NotNull(message = "过期时间不能为空") + private Duration expireTimes; + + /** + * 短信发送频率 + */ + @NotNull(message = "短信发送频率不能为空") + private Duration sendFrequency; + + /** + * 每日发送最大数量 + */ + @NotNull(message = "每日发送最大数量不能为空") + private Integer sendMaximumQuantityPerDay; + + /** + * 验证码最小值 + */ + @NotNull(message = "验证码最小值不能为空") + private Integer beginCode; + + /** + * 验证码最大值 + */ + @NotNull(message = "验证码最大值不能为空") + private Integer endCode; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsConfiguration.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsConfiguration.java new file mode 100644 index 0000000..675bae0 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/config/SmsConfiguration.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.config; + +import com.skyeye.sms.core.service.SmsClientFactory; +import com.skyeye.sms.core.service.impl.SmsClientFactoryImpl; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: SmsConfiguration + * @Description: 短信配置类,包括短信客户端、短信验证码两部分 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Configuration +@EnableConfigurationProperties(SmsCodeProperties.class) +public class SmsConfiguration { + + @Bean + public SmsClientFactory smsClientFactory() { + return new SmsClientFactoryImpl(); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsReceiveResp.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsReceiveResp.java new file mode 100644 index 0000000..463bc11 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsReceiveResp.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.entity; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * @ClassName: SmsReceiveResp + * @Description: 消息接收 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@Accessors(chain = true) +public class SmsReceiveResp { + + /** + * 是否接收成功 + */ + private Boolean success; + /** + * API 接收结果的编码 + */ + private String errorCode; + /** + * API 接收结果的说明 + */ + private String errorMsg; + + /** + * 手机号 + */ + private String mobile; + /** + * 用户接收时间 + */ + private LocalDateTime receiveTime; + + /** + * 短信 API 发送返回的序号 + */ + private String serialNo; + /** + * 短信日志编号 + *

+ * 对应 SysSmsLogDO 的编号 + */ + private Long logId; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsSendResp.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsSendResp.java new file mode 100644 index 0000000..7d413f1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsSendResp.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.entity; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName: SmsSendResp + * @Description: 短信发送 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@Accessors(chain = true) +public class SmsSendResp { + + /** + * 是否成功 + */ + private Boolean success; + + /** + * API 请求编号 + */ + private String apiRequestId; + + // ==================== 成功时字段 ==================== + + /** + * 短信 API 发送返回的序号 + */ + private String serialNo; + + // ==================== 失败时字段 ==================== + + /** + * API 返回错误码 + *

+ * 由于第三方的错误码可能是字符串,所以使用 String 类型 + */ + private String apiCode; + /** + * API 返回提示 + */ + private String apiMsg; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsTemplateResp.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsTemplateResp.java new file mode 100644 index 0000000..693311f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/entity/SmsTemplateResp.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.entity; + +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName: SmsTemplateResp + * @Description: 短信模板 Response DTO + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@Accessors(chain = true) +public class SmsTemplateResp { + + /** + * 模板编号 + */ + private String id; + + /** + * 短信内容 + */ + private String content; + + /** + * 审核状态 + *

+ * 枚举 {@link SmsTemplateAuditStatusEnum} + */ + private Integer auditStatus; + + /** + * 审核未通过的理由 + */ + private String auditReason; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClient.java new file mode 100644 index 0000000..c6aba7f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClient.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service; + +import com.skyeye.common.entity.KeyValue; +import com.skyeye.sms.core.entity.SmsReceiveResp; +import com.skyeye.sms.core.entity.SmsSendResp; +import com.skyeye.sms.core.entity.SmsTemplateResp; + +import java.util.List; + +/** + * @ClassName: SmsClient + * @Description: 短信客户端,用于对接各短信平台的 SDK,实现短信发送等功能 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:02 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsClient { + + /** + * 获得渠道编号 + * + * @return 渠道编号 + */ + String getId(); + + /** + * 发送消息 + * + * @param mobile 手机号 + * @param apiTemplateId 短信 API 的模板编号 + * @param templateParams 短信模板参数。通过 List 数组,保证参数的顺序 + * @return 短信发送结果 + */ + SmsSendResp sendSms(String mobile, String apiTemplateId, + List> templateParams) throws Throwable; + + /** + * 解析接收短信的接收结果 + * + * @param text 结果 + * @return 结果内容 + * @throws Throwable 当解析 text 发生异常时,则会抛出异常 + */ + List parseSmsReceiveStatus(String text) throws Throwable; + + /** + * 查询指定的短信模板 + *

+ * 如果查询失败,则返回 null 空 + * + * @param apiTemplateId 短信 API 的模板编号 + * @return 短信模板 + */ + SmsTemplateResp getSmsTemplate(String apiTemplateId) throws Throwable; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClientFactory.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClientFactory.java new file mode 100644 index 0000000..2d74998 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/SmsClientFactory.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service; + + +import com.skyeye.sms.entity.SmsChannel; + +/** + * @ClassName: SmsClientFactory + * @Description: 短信客户端的工厂接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsClientFactory { + + /** + * 获得短信 Client + * + * @param channelId 渠道编号 + * @return 短信 Client + */ + SmsClient getSmsClientById(String channelId); + + void removeSmsClientById(String channelId); + + /** + * 获得短信 Client + * + * @param channelCode 渠道编码 + * @return 短信 Client + */ + SmsClient getSmsClient(String channelCode); + + /** + * 创建短信 Client + * + * @param properties 配置对象 + */ + void createOrUpdateSmsClient(SmsChannel properties); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AbstractSmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AbstractSmsClient.java new file mode 100644 index 0000000..27b07dc --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AbstractSmsClient.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.entity.SmsChannel; +import lombok.extern.slf4j.Slf4j; + +/** + * 短信客户端的抽象类,提供模板方法,减少子类的冗余代码 + * + * @author zzf + * @since 2021/2/1 9:28 + */ +@Slf4j +public abstract class AbstractSmsClient implements SmsClient { + + /** + * 短信渠道配置 + */ + protected volatile SmsChannel properties; + + public AbstractSmsClient(SmsChannel properties) { + this.properties = properties; + } + + /** + * 初始化 + */ + public final void init() { + doInit(); + log.debug("[init][配置({}) 初始化完成]", properties); + } + + /** + * 自定义初始化 + */ + protected abstract void doInit(); + + public final void refresh(SmsChannel properties) { + // 判断是否更新 + if (properties.equals(this.properties)) { + return; + } + log.info("[refresh][配置({})发生变化,重新初始化]", properties); + this.properties = properties; + // 初始化 + this.init(); + } + + @Override + public String getId() { + return properties.getId(); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AliyunSmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AliyunSmsClient.java new file mode 100644 index 0000000..f2dea53 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/AliyunSmsClient.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import cn.hutool.core.date.format.FastDateFormat; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.digest.DigestUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.google.common.annotations.VisibleForTesting; +import com.skyeye.common.entity.KeyValue; +import com.skyeye.common.enumeration.HttpMethodEnum; +import com.skyeye.common.util.HttpRequestUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import com.skyeye.sms.core.entity.SmsReceiveResp; +import com.skyeye.sms.core.entity.SmsSendResp; +import com.skyeye.sms.core.entity.SmsTemplateResp; +import com.skyeye.sms.entity.SmsChannel; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: AliyunSmsClient + * @Description: 阿里短信客户端的实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class AliyunSmsClient extends AbstractSmsClient { + + private static final String URL = "https://dysmsapi.aliyuncs.com"; + private static final String HOST = "dysmsapi.aliyuncs.com"; + private static final String VERSION = "2017-05-25"; + + private static final String RESPONSE_CODE_SUCCESS = "OK"; + + public AliyunSmsClient(SmsChannel properties) { + super(properties); + Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空"); + Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空"); + } + + @Override + protected void doInit() { + } + + @Override + public SmsSendResp sendSms(String mobile, String apiTemplateId, + List> templateParams) throws Throwable { + Assert.notBlank(properties.getName(), "短信签名不能为空"); + // 1. 执行请求 + // 参考链接 https://api.aliyun.com/document/Dysmsapi/2017-05-25/SendSms + TreeMap queryParam = new TreeMap<>(); + queryParam.put("PhoneNumbers", mobile); + queryParam.put("SignName", properties.getName()); + queryParam.put("TemplateCode", apiTemplateId); + queryParam.put("TemplateParam", JSONUtil.toJsonStr(MapUtil.convertMap(templateParams))); + JSONObject response = request("SendSms", queryParam); + + // 2. 解析请求 + return new SmsSendResp() + .setSuccess(Objects.equals(response.getStr("Code"), RESPONSE_CODE_SUCCESS)) + .setSerialNo(response.getStr("BizId")) + .setApiRequestId(response.getStr("RequestId")) + .setApiCode(response.getStr("Code")) + .setApiMsg(response.getStr("Message")); + } + + @Override + public List parseSmsReceiveStatus(String text) { + JSONArray statuses = JSONUtil.parseArray(text); + // 字段参考 + return statuses.stream().map(bean -> { + JSONObject statusObj = (JSONObject) bean; + return new SmsReceiveResp() + .setSuccess(statusObj.getBool("success")) // 是否接收成功 + .setErrorCode(statusObj.getStr("err_code")) // 状态报告编码 + .setErrorMsg(statusObj.getStr("err_msg")) // 状态报告说明 + .setMobile(statusObj.getStr("phone_number")) // 手机号 + .setReceiveTime(statusObj.getLocalDateTime("report_time", null)) // 状态报告时间 + .setSerialNo(statusObj.getStr("biz_id")) // 发送序列号 + .setLogId(statusObj.getLong("out_id")); // 用户序列号 + }).collect(Collectors.toList()); + } + + @Override + public SmsTemplateResp getSmsTemplate(String apiTemplateId) throws Throwable { + // 1. 执行请求 + // 参考链接 https://api.aliyun.com/document/Dysmsapi/2017-05-25/QuerySmsTemplate + TreeMap queryParam = new TreeMap<>(); + queryParam.put("TemplateCode", apiTemplateId); + JSONObject response = request("QuerySmsTemplate", queryParam); + + // 2.1 请求失败 + String code = response.getStr("Code"); + if (ObjectUtil.notEqual(code, RESPONSE_CODE_SUCCESS)) { + log.error("[getSmsTemplate][模版编号({}) 响应不正确({})]", apiTemplateId, response); + return null; + } + // 2.2 请求成功 + return new SmsTemplateResp() + .setId(response.getStr("TemplateCode")) + .setContent(response.getStr("TemplateContent")) + .setAuditStatus(convertSmsTemplateAuditStatus(response.getInt("TemplateStatus"))) + .setAuditReason(response.getStr("Reason")); + } + + @VisibleForTesting + Integer convertSmsTemplateAuditStatus(Integer templateStatus) { + switch (templateStatus) { + case 0: + return SmsTemplateAuditStatusEnum.CHECKING.getKey(); + case 1: + return SmsTemplateAuditStatusEnum.SUCCESS.getKey(); + case 2: + return SmsTemplateAuditStatusEnum.FAIL.getKey(); + default: + throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus)); + } + } + + /** + * 请求阿里云短信 + * + * @param apiName 请求的 API 名称 + * @param queryParams 请求参数 + * @return 请求结果 + * @see V3 版本请求体&签名机制 + */ + private JSONObject request(String apiName, TreeMap queryParams) { + // 1. 请求参数 + String queryString = queryParams.entrySet().stream() + .map(entry -> percentCode(entry.getKey()) + "=" + percentCode(String.valueOf(entry.getValue()))) + .collect(Collectors.joining("&")); + + // 2.1 请求 Header + TreeMap headers = new TreeMap<>(); + headers.put("host", HOST); + headers.put("x-acs-version", VERSION); + headers.put("x-acs-action", apiName); + headers.put("x-acs-date", FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("GMT")).format(new Date())); + headers.put("x-acs-signature-nonce", IdUtil.randomUUID()); + + // 2.2 构建签名 Header + StringBuilder canonicalHeaders = new StringBuilder(); // 构造请求头,多个规范化消息头,按照消息头名称(小写)的字符代码顺序以升序排列后拼接在一起 + StringBuilder signedHeadersBuilder = new StringBuilder(); // 已签名消息头列表,多个请求头名称(小写)按首字母升序排列并以英文分号(;)分隔 + headers.entrySet().stream().filter(entry -> entry.getKey().toLowerCase().startsWith("x-acs-") + || entry.getKey().equalsIgnoreCase("host") + || entry.getKey().equalsIgnoreCase("content-type")) + .sorted(Map.Entry.comparingByKey()).forEach(entry -> { + String lowerKey = entry.getKey().toLowerCase(); + canonicalHeaders.append(lowerKey).append(":").append(String.valueOf(entry.getValue()).trim()).append("\n"); + signedHeadersBuilder.append(lowerKey).append(";"); + }); + String signedHeaders = signedHeadersBuilder.substring(0, signedHeadersBuilder.length() - 1); + + // 3. 请求 Body + String requestBody = ""; // 短信 API 为 RPC 接口,query parameters 在 uri 中拼接,因此 request body 如果没有特殊要求,设置为空。 + String hashedRequestBody = DigestUtil.sha256Hex(requestBody); + + // 4. 构建 Authorization 签名 + String canonicalRequest = "POST" + "\n" + "/" + "\n" + queryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestBody; + String hashedCanonicalRequest = DigestUtil.sha256Hex(canonicalRequest); + String stringToSign = "ACS3-HMAC-SHA256" + "\n" + hashedCanonicalRequest; + String signature = SecureUtil.hmacSha256(properties.getApiSecret()).digestHex(stringToSign); // 计算签名 + headers.put("Authorization", "ACS3-HMAC-SHA256" + " " + "Credential=" + properties.getApiKey() + + ", " + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature); + + // 5. 发起请求 + String responseBody = HttpRequestUtil.getDataByRequest(URL + "?" + queryString, HttpMethodEnum.POST_REQUEST.getKey(), headers, requestBody); + return JSONUtil.parseObj(responseBody); + } + + /** + * 对指定的字符串进行 URL 编码,并对特定的字符进行替换,以符合URL编码规范 + * + * @param str 需要进行 URL 编码的字符串 + * @return 编码后的字符串 + */ + @SneakyThrows + private static String percentCode(String str) { + Assert.notNull(str, "str 不能为空"); + return URLEncoder.encode(str, StandardCharsets.UTF_8.name()) + .replace("+", "%20") // 加号 "+" 被替换为 "%20" + .replace("*", "%2A") // 星号 "*" 被替换为 "%2A" + .replace("%7E", "~"); // 波浪号 "%7E" 被替换为 "~" + } + +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/DebugDingTalkSmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/DebugDingTalkSmsClient.java new file mode 100644 index 0000000..204f10a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/DebugDingTalkSmsClient.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; +import cn.hutool.crypto.digest.HmacAlgorithm; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.entity.KeyValue; +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import com.skyeye.sms.core.entity.SmsReceiveResp; +import com.skyeye.sms.core.entity.SmsSendResp; +import com.skyeye.sms.core.entity.SmsTemplateResp; +import com.skyeye.sms.entity.SmsChannel; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @ClassName: DebugDingTalkSmsClient + * @Description: 基于钉钉 WebHook 实现的调试的短信客户端实现类 + * 考虑到省钱,我们使用钉钉 WebHook 模拟发送短信,方便调试。 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class DebugDingTalkSmsClient extends AbstractSmsClient { + + public DebugDingTalkSmsClient(SmsChannel properties) { + super(properties); + Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空"); + Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空"); + } + + @Override + protected void doInit() { + } + + @Override + public SmsSendResp sendSms(String mobile, + String apiTemplateId, List> templateParams) throws Throwable { + // 构建请求 + String url = buildUrl("robot/send"); + Map params = new HashMap<>(); + params.put("msgtype", "text"); + String content = String.format("【模拟短信】\n手机号:%s\n模板参数:%s", + mobile, com.skyeye.common.util.MapUtil.convertMap(templateParams)); + params.put("text", MapUtil.builder().put("content", content).build()); + // 执行请求 + String responseText = HttpUtil.post(url, JSONUtil.toJsonStr(params)); + // 解析结果 + Map responseObj = JSONUtil.toBean(responseText, Map.class); + String errorCode = MapUtil.getStr(responseObj, "errcode"); + return new SmsSendResp().setSuccess(Objects.equals(errorCode, "0")).setSerialNo(StrUtil.uuid()) + .setApiCode(errorCode).setApiMsg(MapUtil.getStr(responseObj, "errorMsg")); + } + + /** + * 构建请求地址 + *

+ * 参见 文档 + * + * @param path 请求路径 + * @return 请求地址 + */ + @SuppressWarnings("SameParameterValue") + private String buildUrl(String path) { + // 生成 timestamp + long timestamp = System.currentTimeMillis(); + // 生成 sign + String secret = properties.getApiSecret(); + String stringToSign = timestamp + "\n" + secret; + byte[] signData = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, StrUtil.bytes(secret)).digest(stringToSign); + String sign = Base64.encode(signData); + // 构建最终 URL + return String.format("https://oapi.dingtalk.com/%s?access_token=%s×tamp=%d&sign=%s", + path, properties.getApiKey(), timestamp, sign); + } + + @Override + public List parseSmsReceiveStatus(String text) { + throw new UnsupportedOperationException("模拟短信客户端,暂时无需解析回调"); + } + + @Override + public SmsTemplateResp getSmsTemplate(String apiTemplateId) { + return new SmsTemplateResp().setId(apiTemplateId).setContent("") + .setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getKey()).setAuditReason(""); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/HuaweiSmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/HuaweiSmsClient.java new file mode 100644 index 0000000..3056379 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/HuaweiSmsClient.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.skyeye.common.entity.KeyValue; +import com.skyeye.common.util.DateUtil; +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import com.skyeye.sms.core.entity.SmsReceiveResp; +import com.skyeye.sms.core.entity.SmsSendResp; +import com.skyeye.sms.core.entity.SmsTemplateResp; +import com.skyeye.sms.entity.SmsChannel; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +import static cn.hutool.crypto.digest.DigestUtil.sha256Hex; + +// todo @scholar:参考阿里云在优化下 + +/** + * @ClassName: HuaweiSmsClient + * @Description: 华为短信客户端的实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +public class HuaweiSmsClient extends AbstractSmsClient { + + /** + * 调用成功 code + */ + public static final String URL = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1";//APP接入地址+接口访问URI + public static final String HOST = "smsapi.cn-north-4.myhuaweicloud.com:443"; + public static final String SIGNEDHEADERS = "content-type;host;x-sdk-date"; + + @Override + protected void doInit() { + } + + public HuaweiSmsClient(SmsChannel properties) { + super(properties); + Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空"); + Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空"); + } + + @Override + public SmsSendResp sendSms(String mobile, String apiTemplateId, + List> templateParams) throws Throwable { + // 参考链接 https://support.huaweicloud.com/api-msgsms/sms_05_0001.html + // 相比较阿里短信,华为短信发送的时候需要额外的参数“通道号”,考虑到不破坏原有的的结构 + // 所以将 通道号 拼接到 apiTemplateId 字段中,格式为 "apiTemplateId 通道号"。空格为分隔符。 + String sender = StrUtil.subAfter(apiTemplateId, " ", true); //中国大陆短信签名通道号或全球短信通道号 + String templateId = StrUtil.subBefore(apiTemplateId, " ", true); //模板ID + + //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 + String statusCallBack = properties.getCallbackUrl(); + + List templateParas = templateParams.stream().map(bean -> String.valueOf(bean.getValue())).collect(Collectors.toList()); + + JSONObject JsonResponse = sendSmsRequest(sender, mobile, templateId, templateParas, statusCallBack); + SmsResponse smsResponse = getSmsSendResponse(JsonResponse); + + return new SmsSendResp().setSuccess(smsResponse.success).setApiMsg(smsResponse.data.toString()); + } + + JSONObject sendSmsRequest(String sender, String mobile, String templateId, List templateParas, String statusCallBack) throws UnsupportedEncodingException { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + String sdkDate = sdf.format(new Date()); + + // ************* 步骤 1:拼接规范请求串 ************* + String httpRequestMethod = "POST"; + String canonicalUri = "/sms/batchSendSms/v1/"; + String canonicalQueryString = "";//查询参数为空 + String canonicalHeaders = "content-type:application/x-www-form-urlencoded\n" + + "host:" + HOST + "\n" + + "x-sdk-date:" + sdkDate + "\n"; + //请求Body,不携带签名名称时,signature请填null + String body = buildRequestBody(sender, mobile, templateId, templateParas, statusCallBack, null); + if (null == body || body.isEmpty()) { + return null; + } + String hashedRequestBody = sha256Hex(body); + String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + + canonicalHeaders + "\n" + SIGNEDHEADERS + "\n" + hashedRequestBody; + + // ************* 步骤 2:拼接待签名字符串 ************* + String hashedCanonicalRequest = sha256Hex(canonicalRequest); + String stringToSign = "SDK-HMAC-SHA256" + "\n" + sdkDate + "\n" + hashedCanonicalRequest; + + // ************* 步骤 3:计算签名 ************* + String signature = SecureUtil.hmacSha256(properties.getApiSecret()).digestHex(stringToSign); + + // ************* 步骤 4:拼接 Authorization ************* + String authorization = "SDK-HMAC-SHA256" + " " + "Access=" + properties.getApiKey() + ", " + + "SignedHeaders=" + SIGNEDHEADERS + ", " + "Signature=" + signature; + + // ************* 步骤 5:构造HttpRequest 并执行request请求,获得response ************* + HttpResponse response = HttpRequest.post(URL) + .header("Content-Type", "application/x-www-form-urlencoded") + .header("X-Sdk-Date", sdkDate) + .header("host", HOST) + .header("Authorization", authorization) + .body(body) + .execute(); + + return JSONUtil.parseObj(response.body()); + } + + private SmsResponse getSmsSendResponse(JSONObject resJson) { + SmsResponse smsResponse = new SmsResponse(); + smsResponse.setSuccess("000000".equals(resJson.getStr("code"))); + smsResponse.setData(resJson); + return smsResponse; + } + + static String buildRequestBody(String sender, String receiver, String templateId, List templateParas, + String statusCallBack, String signature) throws UnsupportedEncodingException { + if (null == sender || null == receiver || null == templateId || sender.isEmpty() || receiver.isEmpty() + || templateId.isEmpty()) { + System.out.println("buildRequestBody(): sender, receiver or templateId is null."); + return null; + } + + StringBuilder body = new StringBuilder(); + appendToBody(body, "from=", sender); + appendToBody(body, "&to=", receiver); + appendToBody(body, "&templateId=", templateId); + appendToBody(body, "&templateParas=", JSONUtil.toJsonStr(templateParas)); + appendToBody(body, "&statusCallback=", statusCallBack); + appendToBody(body, "&signature=", signature); + return body.toString(); + } + + private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException { + if (null != val && !val.isEmpty()) { + body.append(key).append(URLEncoder.encode(val, "UTF-8")); + } + } + + @Override + public List parseSmsReceiveStatus(String text) { + List statuses = JSONUtil.toList(text, SmsReceiveStatus.class); + return statuses.stream().map(status -> { + return new SmsReceiveResp().setSuccess(Objects.equals(status.getStatus(), "DELIVRD")) + .setErrorCode(status.getStatus()).setErrorMsg(status.getStatus()) + .setMobile(status.getPhoneNumber()).setReceiveTime(status.getUpdateTime()) + .setSerialNo(status.getSmsMsgId()); + }).collect(Collectors.toList()); + } + + @Override + public SmsTemplateResp getSmsTemplate(String apiTemplateId) throws Throwable { + //华为短信模板查询和发送短信,是不同的两套key和secret,与阿里、腾讯的区别较大,这里模板查询校验暂不实现。 + return new SmsTemplateResp().setId(null).setContent(null) + .setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getKey()).setAuditReason(null); + + } + + @Data + public static class SmsResponse { + + /** + * 是否成功 + */ + private boolean success; + + /** + * 厂商原返回体 + */ + private Object data; + + } + + + /** + * 短信接收状态 + *

+ * 参见 文档 + * + * @author scholar + */ + @Data + public static class SmsReceiveStatus { + + /** + * 本条状态报告对应的短信的接收方号码,仅当状态报告中携带了extend参数时才会同时携带该参数 + */ + @JsonProperty("to") + private String phoneNumber; + + /** + * 短信资源的更新时间,通常为短信平台接收短信状态报告的时间 + */ + @JsonFormat(pattern = DateUtil.YYYY_MM_DD_HH_MM_SS, timezone = DateUtil.TIME_ZONE_DEFAULT) + private LocalDateTime updateTime; + + /** + * 短信状态报告枚举值 + */ + private String status; + + /** + * 发送短信成功时返回的短信唯一标识。 + */ + private String smsMsgId; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/SmsClientFactoryImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/SmsClientFactoryImpl.java new file mode 100644 index 0000000..21c2741 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/SmsClientFactoryImpl.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import com.skyeye.sms.classenum.SmsChannelEnum; +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.core.service.SmsClientFactory; +import com.skyeye.sms.entity.SmsChannel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; + +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @ClassName: SmsClientFactoryImpl + * @Description: 短信客户端工厂接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Validated +@Slf4j +public class SmsClientFactoryImpl implements SmsClientFactory { + + /** + * 短信客户端 Map + * key:渠道编号,使用 {@link SmsChannel#getId()} + */ + private final ConcurrentMap channelIdClients = new ConcurrentHashMap<>(); + + /** + * 短信客户端 Map + * key:渠道编码,使用 {@link SmsChannel#getCodeNum()} ()} ()} + *

+ * 注意,一些场景下,需要获得某个渠道类型的客户端,所以需要使用它。 + * 例如说,解析短信接收结果,是相对通用的,不需要使用某个渠道编号的 {@link #channelIdClients} + */ + private final ConcurrentMap channelCodeClients = new ConcurrentHashMap<>(); + + public SmsClientFactoryImpl() { + // 初始化 channelCodeClients 集合 + Arrays.stream(SmsChannelEnum.values()).forEach(channel -> { + // 创建一个空的 SmsChannelProperties 对象 + SmsChannel properties = new SmsChannel().setCodeNum(channel.getKey()) + .setApiKey("default default").setApiSecret("default"); + // 创建 Sms 客户端 + AbstractSmsClient smsClient = createSmsClient(properties); + channelCodeClients.put(channel.getKey(), smsClient); + }); + } + + @Override + public SmsClient getSmsClientById(String channelId) { + return channelIdClients.get(channelId); + } + + @Override + public void removeSmsClientById(String channelId) { + channelIdClients.remove(channelId); + } + + @Override + public SmsClient getSmsClient(String channelCode) { + return channelCodeClients.get(channelCode); + } + + @Override + public void createOrUpdateSmsClient(SmsChannel properties) { + AbstractSmsClient client = channelIdClients.get(properties.getId()); + if (client == null) { + client = this.createSmsClient(properties); + client.init(); + channelIdClients.put(client.getId(), client); + } else { + client.refresh(properties); + } + } + + private AbstractSmsClient createSmsClient(SmsChannel properties) { + SmsChannelEnum channelEnum = SmsChannelEnum.getByCode(properties.getCodeNum()); + Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channelEnum)); + // 创建客户端 + switch (channelEnum) { + case ALIYUN: + return new AliyunSmsClient(properties); + case DEBUG_DING_TALK: + return new DebugDingTalkSmsClient(properties); + case TENCENT: + return new TencentSmsClient(properties); + case HUAWEI: + return new HuaweiSmsClient(properties); + } + // 创建失败,错误日志 + 抛出异常 + log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", properties); + throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties)); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/TencentSmsClient.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/TencentSmsClient.java new file mode 100644 index 0000000..6deb8bf --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/core/service/impl/TencentSmsClient.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.core.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.google.common.annotations.VisibleForTesting; +import com.skyeye.common.entity.KeyValue; +import com.skyeye.common.enumeration.HttpMethodEnum; +import com.skyeye.common.util.HttpRequestUtil; +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import com.skyeye.sms.core.entity.SmsReceiveResp; +import com.skyeye.sms.core.entity.SmsSendResp; +import com.skyeye.sms.core.entity.SmsTemplateResp; +import com.skyeye.sms.entity.SmsChannel; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.xml.bind.DatatypeConverter; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +import static cn.hutool.crypto.digest.DigestUtil.sha256Hex; + +/** + * @ClassName: TencentSmsClient + * @Description: 腾讯云短信功能实现 + * 参见 文档 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 23:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class TencentSmsClient extends AbstractSmsClient { + + private static final String VERSION = "2021-01-11"; + private static final String REGION = "ap-guangzhou"; + + /** + * 调用成功 code + */ + public static final String API_CODE_SUCCESS = "Ok"; + + /** + * 是否国际/港澳台短信: + *

+ * 0:表示国内短信。 + * 1:表示国际/港澳台短信。 + */ + private static final long INTERNATIONAL_CHINA = 0L; + + public TencentSmsClient(SmsChannel properties) { + super(properties); + Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空"); + validateSdkAppId(properties); + } + + @Override + protected void doInit() { + } + + /** + * 参数校验腾讯云的 SDK AppId + *

+ * 原因是:腾讯云发放短信的时候,需要额外的参数 sdkAppId + *

+ * 解决方案:考虑到不破坏原有的 apiKey + apiSecret 的结构,所以将 secretId 拼接到 apiKey 字段中,格式为 "secretId sdkAppId"。 + * + * @param properties 配置 + */ + private static void validateSdkAppId(SmsChannel properties) { + String combineKey = properties.getApiKey(); + Assert.notEmpty(combineKey, "apiKey 不能为空"); + String[] keys = combineKey.trim().split(" "); + Assert.isTrue(keys.length == 2, "腾讯云短信 apiKey 配置格式错误,请配置 为[secretId sdkAppId]"); + } + + private String getSdkAppId() { + return StrUtil.subAfter(properties.getApiKey(), " ", true); + } + + private String getApiKey() { + return StrUtil.subBefore(properties.getApiKey(), " ", true); + } + + @Override + public SmsSendResp sendSms(String mobile, + String apiTemplateId, List> templateParams) throws Throwable { + // 1. 执行请求 + // 参考链接 https://cloud.tencent.com/document/product/382/55981 + TreeMap body = new TreeMap<>(); + body.put("PhoneNumberSet", new String[]{mobile}); + body.put("SmsSdkAppId", getSdkAppId()); + body.put("SignName", properties.getName()); + body.put("TemplateId", apiTemplateId); + List templateParas = templateParams.stream().map(bean -> String.valueOf(bean.getValue())).collect(Collectors.toList()); + body.put("TemplateParamSet", templateParas); + JSONObject response = request("SendSms", body); + + // 2. 解析请求 + JSONObject responseResult = response.getJSONObject("Response"); + JSONObject error = responseResult.getJSONObject("Error"); + if (error != null) { + return new SmsSendResp().setSuccess(false) + .setApiRequestId(responseResult.getStr("RequestId")) + .setApiCode(error.getStr("Code")) + .setApiMsg(error.getStr("Message")); + } + JSONObject responseData = responseResult.getJSONArray("SendStatusSet").getJSONObject(0); + return new SmsSendResp().setSuccess(Objects.equals(API_CODE_SUCCESS, responseData.getStr("Code"))) + .setApiRequestId(responseResult.getStr("RequestId")) + .setSerialNo(responseData.getStr("SerialNo")) + .setApiMsg(responseData.getStr("Message")); + } + + @Override + public List parseSmsReceiveStatus(String text) { + JSONArray statuses = JSONUtil.parseArray(text); + return statuses.stream().map(bean -> { + JSONObject statusObj = (JSONObject) bean; + return new SmsReceiveResp() + .setSuccess("SUCCESS".equals(statusObj.getStr("report_status"))) // 是否接收成功 + .setErrorCode(statusObj.getStr("errmsg")) // 状态报告编码 + .setMobile(statusObj.getStr("mobile")) // 手机号 + .setReceiveTime(statusObj.getLocalDateTime("user_receive_time", null)) // 状态报告时间 + .setSerialNo(statusObj.getStr("sid")); // 发送序列号 + }).collect(Collectors.toList()); + } + + @Override + public SmsTemplateResp getSmsTemplate(String apiTemplateId) throws Throwable { + // 1. 构建请求 + // 参考链接 https://cloud.tencent.com/document/product/382/52067 + TreeMap body = new TreeMap<>(); + body.put("International", INTERNATIONAL_CHINA); + body.put("TemplateIdSet", new Integer[]{Integer.valueOf(apiTemplateId)}); + JSONObject response = request("DescribeSmsTemplateList", body); + + // TODO @scholar:会有请求失败的情况么?类似发送的(那块逻辑我补充了) + JSONObject TemplateStatusSet = response.getJSONObject("Response").getJSONArray("DescribeTemplateStatusSet").getJSONObject(0); + String content = TemplateStatusSet.get("TemplateContent").toString(); + int templateStatus = Integer.parseInt(TemplateStatusSet.get("StatusCode").toString()); + String auditReason = TemplateStatusSet.get("ReviewReply").toString(); + + return new SmsTemplateResp().setId(apiTemplateId).setContent(content) + .setAuditStatus(convertSmsTemplateAuditStatus(templateStatus)).setAuditReason(auditReason); + } + + @VisibleForTesting + Integer convertSmsTemplateAuditStatus(int templateStatus) { + switch (templateStatus) { + case 1: + return SmsTemplateAuditStatusEnum.CHECKING.getKey(); + case 0: + return SmsTemplateAuditStatusEnum.SUCCESS.getKey(); + case -1: + return SmsTemplateAuditStatusEnum.FAIL.getKey(); + default: + throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus)); + } + } + + /** + * 请求腾讯云短信 + * + * @param action 请求的 API 名称 + * @param body 请求参数 + * @return 请求结果 + * @see 签名方法 v3 + */ + private JSONObject request(String action, TreeMap body) throws Exception { + String timestamp = String.valueOf(System.currentTimeMillis() / 1000); + // TODO @scholar:这个 format,看看怎么写的可以简化点 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + // 注意时区,否则容易出错 + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + String date = sdf.format(new Date(Long.valueOf(timestamp + "000"))); + + // TODO @scholar:这个步骤,看看怎么参考阿里云 client,归类下;1. 2.1 2.2 这种 + // ************* 步骤 1:拼接规范请求串 ************* + // TODO @scholar:这个 hsot 枚举下; + String host = "sms.tencentcloudapi.com"; //APP接入地址+接口访问URI + String httpMethod = "POST"; // 请求方式 + String canonicalUri = "/"; + String canonicalQueryString = ""; + + String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + + "host:" + host + "\n" + "x-tc-action:" + action.toLowerCase() + "\n"; + String signedHeaders = "content-type;host;x-tc-action"; + String hashedRequestBody = sha256Hex(JSONUtil.toJsonStr(body)); + // TODO @scholar:换行下,不然单行太长了 + String canonicalRequest = httpMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestBody; + + // ************* 步骤 2:拼接待签名字符串 ************* + String credentialScope = date + "/" + "sms" + "/" + "tc3_request"; + String hashedCanonicalRequest = sha256Hex(canonicalRequest); + String stringToSign = "TC3-HMAC-SHA256" + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest; + + // ************* 步骤 3:计算签名 ************* + byte[] secretDate = hmac256(("TC3" + properties.getApiSecret()).getBytes(StandardCharsets.UTF_8), date); + byte[] secretService = hmac256(secretDate, "sms"); + byte[] secretSigning = hmac256(secretService, "tc3_request"); + String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase(); + + // ************* 步骤 4:拼接 Authorization ************* + String authorization = "TC3-HMAC-SHA256" + " " + "Credential=" + getApiKey() + "/" + credentialScope + ", " + + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature; + + // ************* 步骤 5:构造HttpRequest 并执行request请求,获得response ************* + Map headers = new HashMap<>(); + headers.put("Authorization", authorization); + headers.put("Content-Type", "application/json; charset=utf-8"); + headers.put("Host", host); + headers.put("X-TC-Action", action); + headers.put("X-TC-Timestamp", timestamp); + headers.put("X-TC-Version", VERSION); + headers.put("X-TC-Region", REGION); + + String responseBody = HttpRequestUtil.getDataByRequest("https://" + host, HttpMethodEnum.POST_REQUEST.getKey(), headers, JSONUtil.toJsonStr(body)); + + return JSONUtil.parseObj(responseBody); + } + + // TODO @scholar:使用 hutool 简化下 + private static byte[] hmac256(byte[] key, String msg) throws Exception { + Mac mac = Mac.getInstance("HmacSHA256"); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm()); + mac.init(secretKeySpec); + return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8)); + } +} \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsChannelDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsChannelDao.java new file mode 100644 index 0000000..e28cb9c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsChannelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.sms.entity.SmsChannel; + +/** + * @ClassName: SmsChannelDao + * @Description: 短信通道数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsChannelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsTemplateDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsTemplateDao.java new file mode 100644 index 0000000..076617d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/dao/SmsTemplateDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.sms.entity.SmsTemplate; + +/** + * @ClassName: SmsTemplateDao + * @Description: 短信模板数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsTemplateDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsChannel.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsChannel.java new file mode 100644 index 0000000..d855e33 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsChannel.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Map; + +/** + * @ClassName: SmsChannel + * @Description: 短信渠道 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sms:channel", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "skyeye_sms_channel") +@ApiModel("短信模板") +@Accessors(chain = true) +public class SmsChannel extends BaseGeneralInfo { + + @TableField("code_num") + @ApiModelProperty(value = "渠道编码,参考#SmsChannelEnum", required = "required", fuzzyLike = true) + private String codeNum; + + @TableField(exist = false) + @Property("渠道编码对应的信息") + private Map codeNumMation; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum枚举类", required = "required,num") + private Integer enabled; + + @TableField("api_key") + @ApiModelProperty(value = "短信 API 的账号", required = "required") + private String apiKey; + + @TableField("api_secret") + @ApiModelProperty(value = "短信 API 的密钥") + private String apiSecret; + + @TableField("callback_url") + @ApiModelProperty(value = "短信发送回调 URL") + private String callbackUrl; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeSendReq.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeSendReq.java new file mode 100644 index 0000000..7702b26 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeSendReq.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @ClassName: SmsCodeSendReq + * @Description: 短信验证码的发送 Request + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("短信验证码的发送 Request") +@Accessors(chain = true) +public class SmsCodeSendReq implements Serializable { + + @ApiModelProperty(value = "手机号", required = "required,phone") + private String mobile; + + @ApiModelProperty(value = "发送场景,参考#SmsSceneEnum", required = "required") + private Integer scene; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeUseReq.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeUseReq.java new file mode 100644 index 0000000..d97f724 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeUseReq.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +@ApiModel("短信验证码的使用 Request") +public class SmsCodeUseReq implements Serializable { + + @ApiModelProperty(value = "手机号", required = "required,phone") + private String mobile; + + @ApiModelProperty(value = "发送场景,参考#SmsSceneEnum", required = "required") + private Integer scene; + + @ApiModelProperty(value = "验证码", required = "required") + private String code; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeValidateReq.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeValidateReq.java new file mode 100644 index 0000000..6766162 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsCodeValidateReq.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: SmsCodeSendReq + * @Description: 短信验证码的校验 Request + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("短信验证码的校验 Request") +public class SmsCodeValidateReq implements Serializable { + + @ApiModelProperty(value = "手机号", required = "required,phone") + private String mobile; + + @ApiModelProperty(value = "发送场景,参考#SmsSceneEnum", required = "required") + private Integer scene; + + @ApiModelProperty(value = "验证码", required = "required") + private String smsCode; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsSendMessage.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsSendMessage.java new file mode 100644 index 0000000..32e4df5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsSendMessage.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.KeyValue; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SmsSendMessage + * @Description: 短信发送消息 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 21:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +public class SmsSendMessage { + + @ApiModelProperty(value = "手机号", required = "required") + private String mobile; + + @ApiModelProperty(value = "短信渠道编号", required = "required") + private String channelId; + + @ApiModelProperty(value = "短信 API 的模板编号", required = "required") + private String apiTemplateId; + + @ApiModelProperty(value = "短信模板参数") + private List> templateParams; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsTemplate.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsTemplate.java new file mode 100644 index 0000000..1c3cf70 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/entity/SmsTemplate.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SmsTemplate + * @Description: 短信模板 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 21:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sms:template", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "skyeye_sms_template", autoResultMap = true) +@ApiModel("短信模板") +public class SmsTemplate extends BaseGeneralInfo { + + @TableField("type") + @ApiModelProperty(value = "短信类型,参考#SmsTemplateTypeEnum", required = "required") + private Integer type; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum枚举类", required = "required,num") + private Integer enabled; + + @TableField("code_num") + @ApiModelProperty(value = "模板编码,保证唯一", required = "required") + private String codeNum; + + @TableField("content") + @ApiModelProperty(value = "模板内容。内容的参数,使用 {} 包括,例如说 {name}", required = "required") + private String content; + + @TableField(value = "params", typeHandler = JacksonTypeHandler.class) + @Property(value = "参数数组(自动根据内容生成)") + private List params; + + @TableField("api_template_id") + @ApiModelProperty(value = "短信 API 的模板编号") + private String apiTemplateId; + + @TableField(value = "channel_id") + @ApiModelProperty(value = "短信渠道id", required = "required") + private String channelId; + + @TableField(exist = false) + @Property(value = "短信渠道信息") + private SmsChannel channelMation; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsChannelService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsChannelService.java new file mode 100644 index 0000000..af23cf2 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsChannelService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.entity.SmsChannel; + +/** + * @ClassName: SmsChannelService + * @Description: 短信渠道服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsChannelService extends SkyeyeBusinessService { + + SmsClient getSmsClientById(String channelId); + + SmsClient getSmsClient(String channelCode); + + SmsChannel selectByCodeNum(String codeNum); + + void queryEnabledSmsChannelList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsCodeService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsCodeService.java new file mode 100644 index 0000000..ebc3801 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsCodeService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.sms.entity.SmsCodeSendReq; +import com.skyeye.sms.entity.SmsCodeUseReq; +import com.skyeye.sms.entity.SmsCodeValidateReq; + +/** + * @ClassName: SmsCodeService + * @Description: 短信验证码服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/30 12:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SmsCodeService { + + void sendSmsCodeReq(InputObject inputObject, OutputObject outputObject); + + void sendSmsCodeReq(SmsCodeSendReq smsCodeSendReq); + + void useSmsCodeReq(InputObject inputObject, OutputObject outputObject); + + void useSmsCodeReq(SmsCodeUseReq smsCodeUseReq); + + void validateSmsCode(InputObject inputObject, OutputObject outputObject); + + void validateSmsCode(SmsCodeValidateReq smsCodeValidateReq); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsSendService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsSendService.java new file mode 100644 index 0000000..13c45d1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsSendService.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service; + +import com.skyeye.sms.entity.SmsSendMessage; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SmsSendService + * @Description: 短信发送 Service 接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 20:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsSendService { + + /** + * 发送单条短信给管理后台的用户 + *

+ * 在 mobile 为空时,使用 userId 加载对应管理员的手机号 + * + * @param mobile 手机号 + * @param staffId 员工id + * @param templateCode 短信模板编号 + * @param templateParams 短信模板参数 + * @return 发送日志编号 + */ + void sendSingleSmsToAdmin(String mobile, String staffId, + String templateCode, Map templateParams); + + /** + * 发送单条短信给用户 APP 的用户 + *

+ * 在 mobile 为空时,使用 userId 加载对应会员的手机号 + * + * @param mobile 手机号 + * @param staffId 员工id + * @param templateCode 短信模板编号 + * @param templateParams 短信模板参数 + * @return 发送日志编号 + */ + void sendSingleSmsToMember(String mobile, String staffId, + String templateCode, Map templateParams); + + /** + * 发送单条短信给用户 + * + * @param mobile 手机号 + * @param staffId 员工id + * @param templateCode 短信模板编号 + * @param templateParams 短信模板参数 + * @return 发送日志编号 + */ + void sendSingleSms(String mobile, String staffId, + String templateCode, Map templateParams); + + default void sendBatchSms(List mobiles, List staffIds, + String templateCode, Map templateParams) { + throw new UnsupportedOperationException("暂时不支持该操作,感兴趣可以实现该功能哟!"); + } + + /** + * 执行真正的短信发送 + * 注意,该方法仅仅提供给 MQ Consumer 使用 + * + * @param message 短信 + */ + void doSendSms(SmsSendMessage message); + + /** + * 接收短信的接收结果 + * + * @param channelCode 渠道编码 + * @param text 结果内容 + * @throws Throwable 处理失败时,抛出异常 + */ + void receiveSmsStatus(String channelCode, String text) throws Throwable; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsTemplateService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsTemplateService.java new file mode 100644 index 0000000..07c72f1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/SmsTemplateService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.sms.entity.SmsTemplate; + +import java.util.Map; + +/** + * @ClassName: SmsTemplateService + * @Description: 短信模板服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SmsTemplateService extends SkyeyeBusinessService { + + SmsTemplate selectByCodeNum(String codeNum); + + String formatSmsTemplateContent(String content, Map params); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsChannelServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsChannelServiceImpl.java new file mode 100644 index 0000000..405d9b6 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsChannelServiceImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.sms.classenum.SmsChannelEnum; +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.core.service.SmsClientFactory; +import com.skyeye.sms.dao.SmsChannelDao; +import com.skyeye.sms.entity.SmsChannel; +import com.skyeye.sms.service.SmsChannelService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SmsChannelServiceImpl + * @Description: 短信渠道服务实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "短信渠道", groupName = "短信渠道") +public class SmsChannelServiceImpl extends SkyeyeBusinessServiceImpl implements SmsChannelService { + + @Autowired + private SmsClientFactory smsClientFactory; + + @Override + public void validatorEntity(SmsChannel entity) { + // 校验渠道编码是否重复 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SmsChannel::getCodeNum), entity.getCodeNum()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SmsChannel checkSmsChannel = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(checkSmsChannel)) { + throw new CustomException("渠道编码已存在."); + } + } + + @Override + protected List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SmsChannel::getEnabled), CommonNumConstants.NUM_ONE); + List list = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(list), null); + } + + @Override + public void updatePostpose(SmsChannel entity, String userId) { + smsClientFactory.removeSmsClientById(entity.getId()); + } + + @Override + public SmsClient getSmsClientById(String channelId) { + SmsChannel smsChannel = selectById(channelId); + if (smsChannel != null) { + smsClientFactory.createOrUpdateSmsClient(smsChannel); + } + return smsClientFactory.getSmsClientById(channelId); + } + + @Override + public SmsChannel selectById(String id) { + SmsChannel smsChannel = super.selectById(id); + smsChannel.setCodeNumMation(SmsChannelEnum.getMation(smsChannel.getCodeNum())); + return smsChannel; + } + + @Override + public SmsClient getSmsClient(String channelCode) { + SmsChannel smsChannel = selectByCodeNum(channelCode); + if (smsChannel != null) { + smsClientFactory.createOrUpdateSmsClient(smsChannel); + } + return smsClientFactory.getSmsClient(channelCode); + } + + @Override + public SmsChannel selectByCodeNum(String codeNum) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(SmsChannel::getCodeNum), codeNum); + SmsChannel smsChannel = getOne(wrapper, false); + return smsChannel; + } + + @Override + public void queryEnabledSmsChannelList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SmsChannel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List smsChannelList = list(queryWrapper); + outputObject.setBeans(smsChannelList); + outputObject.settotal(smsChannelList.size()); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsCodeServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsCodeServiceImpl.java new file mode 100644 index 0000000..faa66e8 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsCodeServiceImpl.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.enumeration.SmsSceneEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.sms.core.config.SmsCodeProperties; +import com.skyeye.sms.entity.SmsCodeSendReq; +import com.skyeye.sms.entity.SmsCodeUseReq; +import com.skyeye.sms.entity.SmsCodeValidateReq; +import com.skyeye.sms.service.SmsCodeService; +import com.skyeye.sms.service.SmsSendService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import static cn.hutool.core.util.RandomUtil.randomInt; + +/** + * @ClassName: SmsCodeServiceImpl + * @Description: 短信验证码服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/30 12:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "短信验证码", groupName = "短信验证码") +public class SmsCodeServiceImpl implements SmsCodeService { + + @Autowired + private SmsCodeProperties smsCodeProperties; + + @Autowired + private SmsSendService smsSendService; + + @Autowired + public JedisClientService jedisClientService; + + /** + * 缓存key:手机号-场景 + */ + private static final String MOBILE_SMS_CODE = "sms:mobile:code:%s:%s"; + + /** + * 缓存key:日期-手机号 + * 不区分场景 + */ + private static final String MOBILE_SMS_DAY_SEND_NUM = "sms:mobile:daySendNum:%s:%s"; + + @Value("${sms.template.enabled}") + private Boolean smsTemplateEnabled; + + @Value("${sms.template.code}") + private String smsTemplateCode; + + @Override + public void sendSmsCodeReq(InputObject inputObject, OutputObject outputObject) { + SmsCodeSendReq smsCodeSendReq = inputObject.getParams(SmsCodeSendReq.class); + sendSmsCodeReq(smsCodeSendReq); + } + + @Override + public void sendSmsCodeReq(SmsCodeSendReq smsCodeSendReq) { + SmsSceneEnum sceneEnum = SmsSceneEnum.getCodeByScene(smsCodeSendReq.getScene()); + Assert.notNull(sceneEnum, "验证码场景({}) 查找不到配置", smsCodeSendReq.getScene()); + if (smsTemplateEnabled) { + return; + } + // 创建验证码 + String code = createSmsCode(smsCodeSendReq.getMobile(), smsCodeSendReq.getScene()); + // 发送验证码 + smsSendService.sendSingleSms(smsCodeSendReq.getMobile(), null, + sceneEnum.getValue(), MapUtil.of("code", code)); + } + + private String createSmsCode(String mobile, Integer scene) { + String key = String.format(MOBILE_SMS_CODE, mobile, scene); + // 校验是否可以发送验证码 + if (jedisClientService.exists(key)) { + throw new CustomException("验证码发送过于频繁,请稍后再试"); + } + // 创建验证码记录 + String code = String.format("%0" + smsCodeProperties.getEndCode().toString().length() + "d", + randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); + jedisClientService.set(key, code, (int) smsCodeProperties.getExpireTimes().getSeconds()); + + // 校验次数 + String key2 = String.format(MOBILE_SMS_DAY_SEND_NUM, DateUtil.getYmdTimeAndToString(), mobile); + String ss = jedisClientService.get(key2); + int number = StrUtil.isEmpty(ss) ? CommonNumConstants.NUM_ZERO : Integer.parseInt(ss); + if (number >= smsCodeProperties.getSendMaximumQuantityPerDay()) { + throw new CustomException("超过当天发送的上限"); + } + number++; + // 失效时间为 1 天 + jedisClientService.set(key2, String.valueOf(number), RedisConstants.ONE_DAY_SECONDS); + return code; + } + + @Override + public void useSmsCodeReq(InputObject inputObject, OutputObject outputObject) { + SmsCodeUseReq smsCodeUseReq = inputObject.getParams(SmsCodeUseReq.class); + useSmsCodeReq(smsCodeUseReq); + } + + @Override + public void useSmsCodeReq(SmsCodeUseReq smsCodeUseReq) { + // 检测验证码是否有效 + String chcheCode = validateSmsCode0(smsCodeUseReq.getMobile(), smsCodeUseReq.getScene()); + if (StrUtil.equals(chcheCode, smsCodeUseReq.getCode())) { + // 验证码使用过后,删除缓存 + String key = String.format(MOBILE_SMS_CODE, smsCodeUseReq.getMobile(), smsCodeUseReq.getScene()); + jedisClientService.del(key); + } + } + + @Override + public void validateSmsCode(InputObject inputObject, OutputObject outputObject) { + SmsCodeValidateReq smsCodeValidateReq = inputObject.getParams(SmsCodeValidateReq.class); + validateSmsCode(smsCodeValidateReq); + } + + @Override + public void validateSmsCode(SmsCodeValidateReq smsCodeValidateReq) { + if (smsTemplateEnabled) { + if (!StrUtil.equals(smsTemplateCode, smsCodeValidateReq.getSmsCode())) { + throw new CustomException("验证码错误"); + } + return; + } + String chcheCode = validateSmsCode0(smsCodeValidateReq.getMobile(), smsCodeValidateReq.getScene()); + if (!StrUtil.equals(chcheCode, smsCodeValidateReq.getSmsCode())) { + throw new CustomException("验证码错误"); + } + // 验证码使用过后,删除缓存 + String key = String.format(MOBILE_SMS_CODE, smsCodeValidateReq.getMobile(), smsCodeValidateReq.getScene()); + jedisClientService.del(key); + } + + private String validateSmsCode0(String mobile, Integer scene) { + String key = String.format(MOBILE_SMS_CODE, mobile, scene); + // 校验是否可以发送验证码 + if (!jedisClientService.exists(key)) { + throw new CustomException("验证码不存在或已过期"); + } + return jedisClientService.get(key); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsSendServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsSendServiceImpl.java new file mode 100644 index 0000000..b492bbd --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsSendServiceImpl.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.google.common.annotations.VisibleForTesting; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.entity.KeyValue; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import com.skyeye.personnel.entity.SysEveUserStaff; +import com.skyeye.personnel.service.SysEveUserStaffService; +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.entity.SmsChannel; +import com.skyeye.sms.entity.SmsSendMessage; +import com.skyeye.sms.entity.SmsTemplate; +import com.skyeye.sms.service.SmsChannelService; +import com.skyeye.sms.service.SmsSendService; +import com.skyeye.sms.service.SmsTemplateService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SmsSendServiceImpl + * @Description: 短信发送 Service 发送的实现 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 20:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@Slf4j +public class SmsSendServiceImpl implements SmsSendService { + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private SysEveUserStaffService sysEveUserStaffService; + + @Autowired + private SmsChannelService smsChannelService; + + @Autowired + private SmsTemplateService smsTemplateService; + + @Override + public void sendSingleSmsToAdmin(String mobile, String staffId, String templateCode, Map templateParams) { + // 如果 mobile 为空,则加载用户编号对应的手机号 + if (StrUtil.isEmpty(mobile)) { + SysEveUserStaff userStaff = sysEveUserStaffService.selectById(staffId); + if (userStaff != null) { + mobile = userStaff.getPhone(); + } + } + // 执行发送 + sendSingleSms(mobile, staffId, templateCode, templateParams); + } + + @Override + public void sendSingleSmsToMember(String mobile, String staffId, String templateCode, Map templateParams) { + // 如果 mobile 为空,则加载用户编号对应的手机号 + if (StrUtil.isEmpty(mobile)) { + SysEveUserStaff userStaff = sysEveUserStaffService.selectById(staffId); + if (userStaff != null) { + mobile = userStaff.getPhone(); + } + } + // 执行发送 + sendSingleSms(mobile, staffId, templateCode, templateParams); + } + + @Override + public void sendSingleSms(String mobile, String staffId, String templateCode, Map templateParams) { + // 校验短信模板是否合法 + SmsTemplate template = validateSmsTemplate(templateCode); + // 校验短信渠道是否合法 + SmsChannel smsChannel = validateSmsChannel(template.getChannelId()); + + // 校验手机号码是否存在 + mobile = validateMobile(mobile); + // 构建有序的模板参数。为什么放在这个位置,是提前保证模板参数的正确性,而不是到了插入发送日志 + List> newTemplateParams = buildTemplateParams(template, templateParams); + + // 如果模板被禁用,则不发送短信 + Boolean isSend = EnableEnum.ENABLE_USING.getKey().equals(template.getEnabled()) + && EnableEnum.ENABLE_USING.getKey().equals(smsChannel.getEnabled()); + // 发送 MQ 消息,异步执行发送短信 + if (isSend) { + SmsSendMessage smsSendMessage = new SmsSendMessage(); + smsSendMessage.setMobile(mobile); + smsSendMessage.setChannelId(smsChannel.getId()); + smsSendMessage.setApiTemplateId(template.getApiTemplateId()); + smsSendMessage.setTemplateParams(newTemplateParams); + + Map emailNotice = new HashMap<>(); + emailNotice.put("content", JSONUtil.toJsonStr(smsSendMessage)); + emailNotice.put("type", MqConstants.JobMateMationJobType.SMS_SEND.getJobType()); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(emailNotice)); + Map user = InputObject.getLogParamsStatic(); + jobMateMation.setUserId(CollectionUtil.isEmpty(user) ? CommonConstants.ADMIN_USER_ID : user.get("id").toString()); + iJobMateMationService.sendMQProducer(jobMateMation); + } + } + + private SmsChannel validateSmsChannel(String channelId) { + // 获得短信模板。考虑到效率,从缓存中获取 + SmsChannel channel = smsChannelService.selectById(channelId); + // 短信模板不存在 + if (channel == null) { + throw new CustomException("短信渠道不存在"); + } + return channel; + } + + private SmsTemplate validateSmsTemplate(String codeNum) { + // 获得短信模板。考虑到效率,从缓存中获取 + SmsTemplate template = smsTemplateService.selectByCodeNum(codeNum); + // 短信模板不存在 + if (template == null) { + throw new CustomException("短信模板不存在"); + } + return template; + } + + /** + * 将参数模板,处理成有序的 KeyValue 数组 + *

+ * 原因是,部分短信平台并不是使用 key 作为参数,而是数组下标,例如说 腾讯云 + * + * @param template 短信模板 + * @param templateParams 原始参数 + * @return 处理后的参数 + */ + @VisibleForTesting + List> buildTemplateParams(SmsTemplate template, Map templateParams) { + return template.getParams().stream().map(key -> { + Object value = templateParams.get(key); + if (value == null) { + throw new CustomException("模板参数缺少:" + key); + } + return new KeyValue<>(key, value); + }).collect(Collectors.toList()); + } + + public String validateMobile(String mobile) { + if (StrUtil.isEmpty(mobile)) { + throw new CustomException("手机号码不能为空"); + } + return mobile; + } + + @Override + public void doSendSms(SmsSendMessage message) { + // 获得渠道对应的 SmsClient 客户端 + SmsClient smsClient = smsChannelService.getSmsClientById(message.getChannelId()); + Assert.notNull(smsClient, "短信客户端({}) 不存在", message.getChannelId()); + // 发送短信 + try { + smsClient.sendSms(message.getMobile(), + message.getApiTemplateId(), message.getTemplateParams()); + } catch (Throwable ex) { + log.error("[doSendSms][发送短信异常]", ex); + } + } + + @Override + public void receiveSmsStatus(String channelCode, String text) throws Throwable { + // 获得渠道对应的 SmsClient 客户端 + SmsClient smsClient = smsChannelService.getSmsClient(channelCode); + Assert.notNull(smsClient, "短信客户端({}) 不存在", channelCode); + // 解析内容 + smsClient.parseSmsReceiveStatus(text); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsTemplateServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsTemplateServiceImpl.java new file mode 100644 index 0000000..2898346 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/sms/service/impl/SmsTemplateServiceImpl.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sms.service.impl; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.sms.classenum.SmsTemplateAuditStatusEnum; +import com.skyeye.sms.core.entity.SmsTemplateResp; +import com.skyeye.sms.core.service.SmsClient; +import com.skyeye.sms.dao.SmsTemplateDao; +import com.skyeye.sms.entity.SmsTemplate; +import com.skyeye.sms.service.SmsChannelService; +import com.skyeye.sms.service.SmsTemplateService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + +/** + * @ClassName: SmsTemplateServiceImpl + * @Description: 短信模板服务实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/28 22:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "短信模板", groupName = "短信模板") +public class SmsTemplateServiceImpl extends SkyeyeBusinessServiceImpl implements SmsTemplateService { + + /** + * 正则表达式,匹配 {} 中的变量 + */ + private static final Pattern PATTERN_PARAMS = Pattern.compile("\\{(.*?)}"); + + @Autowired + private SmsChannelService smsChannelService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + smsChannelService.setMationForMap(beans, "channelId", "channelMation"); + return beans; + } + + @Override + public void validatorEntity(SmsTemplate entity) { + // 校验短信编码是否重复 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SmsTemplate::getCodeNum), entity.getCodeNum()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SmsTemplate checkSmsTemplate = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(checkSmsTemplate)) { + throw new CustomException("模板编码已存在."); + } + // 校验短信模板 + validateApiTemplate(entity.getChannelId(), entity.getApiTemplateId()); + + entity.setParams(parseTemplateContentParams(entity.getContent())); + } + + @Override + public SmsTemplate selectById(String id) { + SmsTemplate smsTemplate = super.selectById(id); + smsChannelService.setDataMation(smsTemplate, SmsTemplate::getChannelId); + return smsTemplate; + } + + /** + * 校验 API 短信平台的模板是否有效 + * + * @param channelId 渠道编号 + * @param apiTemplateId API 模板编号 + */ + private void validateApiTemplate(String channelId, String apiTemplateId) { + // 获得短信模板 + SmsClient smsClient = smsChannelService.getSmsClientById(channelId); + Assert.notNull(smsClient, String.format("短信客户端(%s) 不存在", channelId)); + SmsTemplateResp template; + try { + template = smsClient.getSmsTemplate(apiTemplateId); + } catch (Throwable ex) { + throw new CustomException("短信 API 模板调用失败"); + } + // 校验短信模版 + if (template == null) { + throw new CustomException("短信 API 模版无法使用,原因:模版不存在"); + } + if (Objects.equals(template.getAuditStatus(), SmsTemplateAuditStatusEnum.CHECKING.getKey())) { + throw new CustomException("短信 API 模版无法使用,原因:审批中"); + } + if (Objects.equals(template.getAuditStatus(), SmsTemplateAuditStatusEnum.FAIL.getKey())) { + throw new CustomException("短信 API 模版无法使用,原因:审批不通过"); + } + Assert.equals(template.getAuditStatus(), SmsTemplateAuditStatusEnum.SUCCESS.getKey(), + String.format("短信模板(%s) 审核状态(%d) 不正确", apiTemplateId, template.getAuditStatus())); + } + + @Override + public SmsTemplate selectByCodeNum(String codeNum) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(SmsTemplate::getCodeNum), codeNum); + SmsTemplate smsTemplate = getOne(wrapper, false); + return smsTemplate; + } + + @Override + public String formatSmsTemplateContent(String content, Map params) { + return StrUtil.format(content, params); + } + + private List parseTemplateContentParams(String content) { + return ReUtil.findAllGroup1(PATTERN_PARAMS, content); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/classenum/TenantAppMenuType.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/classenum/TenantAppMenuType.java new file mode 100644 index 0000000..a3ea8c7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/classenum/TenantAppMenuType.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: TenantAppMenuType + * @Description: 应用与菜单的关系中菜单的类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 17:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TenantAppMenuType implements SkyeyeEnumClass { + PC(1, "PC端菜单", true, false), + APP(2, "APP端菜单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppBuyOrderController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppBuyOrderController.java new file mode 100644 index 0000000..a942a28 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppBuyOrderController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tenant.entity.TenantAppBuyOrder; +import com.skyeye.tenant.service.TenantAppBuyOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TenantAppBuyOrderController + * @Description: 订单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:26 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "订单管理", tags = "订单管理", modelName = "租户管理") +public class TenantAppBuyOrderController { + + @Autowired + private TenantAppBuyOrderService tenantAppBuyOrderService; + + /** + * 获取订单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantAppBuyOrderList", value = "获取订单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TenantAppBuyOrderController/queryTenantAppBuyOrderList") + public void queryTenantAppBuyOrderList(InputObject inputObject, OutputObject outputObject) { + tenantAppBuyOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTenantAppBuyOrder", value = "新增/编辑订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TenantAppBuyOrder.class) + @RequestMapping("/post/TenantAppBuyOrderController/writeTenantAppBuyOrder") + public void writeTenantAppBuyOrder(InputObject inputObject, OutputObject outputObject) { + tenantAppBuyOrderService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 订单提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitTenantAppBuyOrder", value = "订单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/TenantAppBuyOrderController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + tenantAppBuyOrderService.submitToApproval(inputObject, outputObject); + } + + /** + * 删除订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTenantAppBuyOrderById", value = "删除订单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TenantAppBuyOrderController/deleteTenantAppBuyOrderById") + public void deleteTenantAppBuyOrderById(InputObject inputObject, OutputObject outputObject) { + tenantAppBuyOrderService.deleteById(inputObject, outputObject); + } + + /** + * 撤销订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeTenantAppBuyOrder", value = "撤销订单", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/TenantAppBuyOrderController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + tenantAppBuyOrderService.revoke(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppController.java new file mode 100644 index 0000000..1c655b2 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppController.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tenant.entity.TenantApp; +import com.skyeye.tenant.service.TenantAppService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TenantAppController + * @Description: 租户应用管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "租户应用管理", tags = "租户应用管理", modelName = "租户管理") +public class TenantAppController { + + @Autowired + private TenantAppService tenantAppService; + + /** + * 获取租户应用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantAppList", value = "获取租户应用列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TenantAppController/queryTenantAppList") + public void queryTenantAppList(InputObject inputObject, OutputObject outputObject) { + tenantAppService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑租户应用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTenantApp", value = "新增/编辑租户应用", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TenantApp.class) + @RequestMapping("/post/TenantAppController/writeTenantApp") + public void writeTenantApp(InputObject inputObject, OutputObject outputObject) { + tenantAppService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询租户应用信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantAppById", value = "根据id查询租户应用信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "租户应用ID", required = "required")}) + @RequestMapping("/post/TenantAppController/queryTenantAppById") + public void queryTenantAppById(InputObject inputObject, OutputObject outputObject) { + tenantAppService.selectById(inputObject, outputObject); + } + + /** + * 删除租户应用 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTenantAppById", value = "删除租户应用", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "租户应用ID", required = "required")}) + @RequestMapping("/post/TenantAppController/deleteTenantAppById") + public void deleteTenantAppById(InputObject inputObject, OutputObject outputObject) { + tenantAppService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有模块(桌面)/菜单/权限点/分组/数据权限列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantAppBandMenuList", value = "获取所有模块(桌面)/菜单/权限点/分组/数据权限列表", method = "GET", allUse = "2") + @RequestMapping("/post/TenantAppController/queryTenantAppBandMenuList") + public void queryTenantAppBandMenuList(InputObject inputObject, OutputObject outputObject) { + tenantAppService.queryTenantAppBandMenuList(inputObject, outputObject); + } + + /** + * 编辑租户应用PC端权限 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editTenantAppPCAuth", value = "编辑租户应用PC端权限", method = "PUT", allUse = "1") + @ApiImplicitParams(classBean = TenantApp.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TenantAppController/editTenantAppPCAuth") + public void editTenantAppPCAuth(InputObject inputObject, OutputObject outputObject) { + tenantAppService.editTenantAppPCAuth(inputObject, outputObject); + } + + /** + * 获取租户应用需要绑定的手机端菜单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantAppBandAppMenuList", value = "获取租户应用需要绑定的手机端菜单列表", method = "GET", allUse = "2") + @RequestMapping("/post/TenantAppController/queryTenantAppBandAppMenuList") + public void queryTenantAppBandAppMenuList(InputObject inputObject, OutputObject outputObject) { + tenantAppService.queryTenantAppBandAppMenuList(inputObject, outputObject); + } + + /** + * 手机端菜单授权 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editTenantAppAppMenuById", value = "手机端菜单授权", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = TenantApp.class, value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TenantAppController/editTenantAppAppMenuById") + public void editTenantAppAppMenuById(InputObject inputObject, OutputObject outputObject) { + tenantAppService.editTenantAppAppMenuById(inputObject, outputObject); + } + + /** + * 获取所有租户应用列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllTenantAppList", value = "获取所有租户应用列表", method = "GET", allUse = "2") + @RequestMapping("/post/TenantAppController/queryAllTenantAppList") + public void queryAllTenantAppList(InputObject inputObject, OutputObject outputObject) { + tenantAppService.queryAllTenantAppList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppLinkController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppLinkController.java new file mode 100644 index 0000000..2be5d99 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantAppLinkController.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.tenant.service.TenantAppLinkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TenantAppLinkController + * @Description: 租户与应用的关系管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 20:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "租户与应用的关系管理", tags = "租户与应用的关系管理", modelName = "租户管理") +public class TenantAppLinkController { + + @Autowired + private TenantAppLinkService tenantAppLinkService; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantController.java new file mode 100644 index 0000000..3a996a1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/controller/TenantController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tenant.entity.Tenant; +import com.skyeye.tenant.service.TenantService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TenantController + * @Description: 租户控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/28 20:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "租户管理", tags = "租户管理", modelName = "租户管理") +public class TenantController { + + @Autowired + private TenantService tenantService; + + /** + * 获取租户列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantList", value = "获取租户列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TenantController/queryTenantList") + public void queryTenantList(InputObject inputObject, OutputObject outputObject) { + tenantService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑租户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTenant", value = "新增/编辑租户", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Tenant.class) + @RequestMapping("/post/TenantController/writeTenant") + public void writeTenant(InputObject inputObject, OutputObject outputObject) { + tenantService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询租户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTenantById", value = "根据id查询租户信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "租户ID", required = "required")}) + @RequestMapping("/post/TenantController/queryTenantById") + public void queryTenantById(InputObject inputObject, OutputObject outputObject) { + tenantService.selectById(inputObject, outputObject); + } + + /** + * 删除租户 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTenantById", value = "删除租户", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "租户ID", required = "required")}) + @RequestMapping("/post/TenantController/deleteTenantById") + public void deleteTenantById(InputObject inputObject, OutputObject outputObject) { + tenantService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有租户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllTenantList", value = "获取所有租户信息", method = "GET", allUse = "2") + @RequestMapping("/post/TenantController/queryAllTenantList") + public void queryAllTenantList(InputObject inputObject, OutputObject outputObject) { + tenantService.queryAllTenantList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderDao.java new file mode 100644 index 0000000..6706761 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantAppBuyOrder; + +/** + * @ClassName: TenantAppBuyOrderDao + * @Description: 订单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:24 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderNumDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderNumDao.java new file mode 100644 index 0000000..13b46d7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderNumDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantAppBuyOrderNum; + +/** + * @ClassName: TenantAppBuyOrderNumDao + * @Description: 订单-购买租户数量管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderNumDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderYearDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderYearDao.java new file mode 100644 index 0000000..7cd4167 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppBuyOrderYearDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantAppBuyOrderYear; + +/** + * @ClassName: TenantAppBuyOrderYearDao + * @Description: 订单-购买应用年限管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 22:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderYearDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppDao.java new file mode 100644 index 0000000..f5b3188 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantApp; + +/** + * @ClassName: TenantAppDao + * @Description: 租户应用管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppLinkDo.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppLinkDo.java new file mode 100644 index 0000000..948cc98 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppLinkDo.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantAppLink; + +/** + * @ClassName: TenantAppLinkDo + * @Description: 租户与应用的关系管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 20:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppLinkDo extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppMenuDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppMenuDao.java new file mode 100644 index 0000000..8ca1c50 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantAppMenuDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.TenantAppMenu; + +/** + * @ClassName: TenantAppMenuDao + * @Description: 应用与菜单的关系管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppMenuDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantDao.java new file mode 100644 index 0000000..ae0901c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/dao/TenantDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tenant.entity.Tenant; + +/** + * @ClassName: TenantDao + * @Description: 租户数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/28 20:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/Tenant.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/Tenant.java new file mode 100644 index 0000000..e260827 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/Tenant.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Tenant + * @Description: 租户实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/28 20:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "tenant:detail", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "tenant") +@ApiModel("租户实体类") +public class Tenant extends BaseGeneralInfo { + + @TableField("account_num") + @Property(value = "允许的账号数量") + private Integer accountNum; + + @TableField(exist = false) + @ApiModelProperty("应用信息") + private List tenantAppLinkList; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantApp.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantApp.java new file mode 100644 index 0000000..bbcfc05 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantApp.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: TenantApp + * @Description: 租户应用管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "tenant:app", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "tenant_app") +@ApiModel("租户应用管理实体类") +public class TenantApp extends BaseGeneralInfo { + + @TableField(exist = false) + @ApiModelProperty(value = "PC端菜单权限") + private List menuIds; + + @TableField(exist = false) + @ApiModelProperty(value = "手机端菜单权限") + private List appMenuIds; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrder.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrder.java new file mode 100644 index 0000000..43589de --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrder.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: TenantAppBuyOrder + * @Description: 订单管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "tenant:order", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "tenant_app_buy_order") +@ApiModel("订单管理实体类") +public class TenantAppBuyOrder extends SkyeyeFlowable { + + @TableField("oper_time") + @ApiModelProperty(value = "单据日期", required = "required") + private String operTime; + + @TableField(value = "tenant_id") + @ApiModelProperty(value = "租户id", required = "required") + private String tenantId; + + @TableField(exist = false) + @Property("租户信息") + private Tenant tenantMation; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "all_price") + @Property(value = "总价") + private String allPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "租户数量信息", required = "json") + private List tenantAppBuyOrderNumList; + + @TableField(exist = false) + @ApiModelProperty(value = "租户应用信息", required = "json") + private List tenantAppBuyOrderYearList; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderNum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderNum.java new file mode 100644 index 0000000..9b4806a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderNum.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: TenantAppBuyOrderNum + * @Description: 订单-购买租户数量管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "tenant_app_buy_order_num") +@ApiModel("订单-购买租户数量管理实体类") +public class TenantAppBuyOrderNum extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property(value = "单据ID") + private String parentId; + + @TableField(value = "account_num") + @ApiModelProperty(value = "购买的数量", required = "required,num") + private Integer accountNum; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "required") + private String unitPrice; + + @TableField(value = "all_price") + @Property(value = "总价") + private String allPrice; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderYear.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderYear.java new file mode 100644 index 0000000..5df9de5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppBuyOrderYear.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: TenantAppBuyOrderYear + * @Description: 订单-购买应用年限管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "tenant_app_buy_order_year") +@ApiModel("订单-购买应用年限管理实体类") +public class TenantAppBuyOrderYear extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("parent_id") + @Property(value = "单据ID") + private String parentId; + + @TableField(value = "app_id") + @ApiModelProperty(value = "应用id", required = "required") + private String appId; + + @TableField(exist = false) + @Property("应用信息") + private TenantApp appMation; + + @TableField(value = "account_year") + @ApiModelProperty(value = "购买的年限", required = "required,num") + private Integer accountYear; + + @TableField(value = "unit_price") + @ApiModelProperty(value = "单价", required = "required") + private String unitPrice; + + @TableField(value = "all_price") + @Property(value = "总价") + private String allPrice; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppLink.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppLink.java new file mode 100644 index 0000000..635c11d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppLink.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: TenantAppLink + * @Description: 租户与应用的关系管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "tenant_app_link") +@ApiModel("租户与应用的关系管理实体类") +public class TenantAppLink extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "tenant_id") + @Property(value = "租户id") + private String tenantId; + + @TableField(value = "app_id") + @Property(value = "应用id") + private String appId; + + @TableField(exist = false) + @Property("应用信息") + private TenantApp appMation; + + @TableField(value = "start_time") + @Property(value = "有效期开始时间") + private String startTime; + + @TableField(value = "end_time") + @Property(value = "有效期结束时间") + private String endTime; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppMenu.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppMenu.java new file mode 100644 index 0000000..d8b7153 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/entity/TenantAppMenu.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: TenantAppMenu + * @Description: 应用与菜单的关系管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "tenant_app_menu") +@ApiModel("应用与菜单的关系管理实体类") +public class TenantAppMenu extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "app_id") + @Property(value = "应用id") + private String appId; + + @TableField(value = "object_id") + @Property(value = "菜单/权限点ID") + private String objectId; + + @TableField(value = "type") + @Property(value = "类型") + private Integer type; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderNumService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderNumService.java new file mode 100644 index 0000000..4834fe5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderNumService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.tenant.entity.TenantAppBuyOrderNum; + +import java.util.List; + +/** + * @ClassName: TenantAppBuyOrderNumService + * @Description: 订单-购买租户数量管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:17 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderNumService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderService.java new file mode 100644 index 0000000..6bc6ce0 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.tenant.entity.TenantAppBuyOrder; + +/** + * @ClassName: TenantAppBuyOrderService + * @Description: 订单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderService extends SkyeyeFlowableService { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderYearService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderYearService.java new file mode 100644 index 0000000..1f1e7e3 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppBuyOrderYearService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.tenant.entity.TenantAppBuyOrderYear; + +import java.util.List; + +/** + * @ClassName: TenantAppBuyOrderYearService + * @Description: 订单-购买应用年限管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppBuyOrderYearService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + + void deleteByParentId(String parentId); + + List selectByParentId(String parentId); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppLinkService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppLinkService.java new file mode 100644 index 0000000..111ae93 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppLinkService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.tenant.entity.TenantAppLink; + +import java.util.List; + +/** + * @ClassName: TenantAppLinkService + * @Description: 租户与应用的关系管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 20:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppLinkService extends SkyeyeBusinessService { + + void saveTenantAppLink(String tenantId, String appId, Integer year); + + List selectByTenantId(String tenantId); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppMenuService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppMenuService.java new file mode 100644 index 0000000..c786814 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppMenuService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.tenant.entity.TenantAppMenu; + +import java.util.List; + +/** + * @ClassName: TenantAppMenuService + * @Description: 应用与菜单的关系管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppMenuService extends SkyeyeBusinessService { + + void saveList(String appId, Integer type, List beans); + + void deleteByAppId(String appId, Integer type); + + void deleteByAppId(String appId); + + List selectByAppId(String appId, Integer type); + + List selectObjectIdsByAppId(String appId, Integer type); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppService.java new file mode 100644 index 0000000..4b90a7a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantAppService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tenant.entity.TenantApp; + +import java.util.Map; + +/** + * @ClassName: TenantAppService + * @Description: 租户应用管理服务层接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantAppService extends SkyeyeBusinessService { + + void queryTenantAppBandMenuList(InputObject inputObject, OutputObject outputObject); + + void editTenantAppPCAuth(InputObject inputObject, OutputObject outputObject); + + void queryTenantAppBandAppMenuList(InputObject inputObject, OutputObject outputObject); + + void editTenantAppAppMenuById(InputObject inputObject, OutputObject outputObject); + + void queryAllTenantAppList(InputObject inputObject, OutputObject outputObject); + + Map queryTenantAppByAppId(String... appId); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantService.java new file mode 100644 index 0000000..e503111 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/TenantService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tenant.entity.Tenant; + +/** + * @ClassName: TenantService + * @Description: 租户服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/28 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TenantService extends SkyeyeBusinessService { + + void editTenantAccountNumber(String tenantId, Integer accountNumber); + + void queryAllTenantList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderNumServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderNumServiceImpl.java new file mode 100644 index 0000000..914a111 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderNumServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tenant.dao.TenantAppBuyOrderNumDao; +import com.skyeye.tenant.entity.TenantAppBuyOrderNum; +import com.skyeye.tenant.service.TenantAppBuyOrderNumService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: TenantAppBuyOrderNumServiceImpl + * @Description: 订单-购买租户数量管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "订单-购买租户数量管理", groupName = "租户管理", manageShow = false) +public class TenantAppBuyOrderNumServiceImpl extends SkyeyeBusinessServiceImpl implements TenantAppBuyOrderNumService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (TenantAppBuyOrderNum tenantAppBuyOrderNum : beans) { + tenantAppBuyOrderNum.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppBuyOrderNum::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppBuyOrderNum::getParentId), parentId); + List list = list(queryWrapper); + return list; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderServiceImpl.java new file mode 100644 index 0000000..ae8809a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderServiceImpl.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.tenant.dao.TenantAppBuyOrderDao; +import com.skyeye.tenant.entity.TenantApp; +import com.skyeye.tenant.entity.TenantAppBuyOrder; +import com.skyeye.tenant.entity.TenantAppBuyOrderNum; +import com.skyeye.tenant.entity.TenantAppBuyOrderYear; +import com.skyeye.tenant.service.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: TenantAppBuyOrderServiceImpl + * @Description: 订单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/30 16:25 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "订单管理", groupName = "租户管理", flowable = true) +public class TenantAppBuyOrderServiceImpl extends SkyeyeFlowableServiceImpl implements TenantAppBuyOrderService { + + @Autowired + private TenantService tenantService; + + @Autowired + private TenantAppService tenantAppService; + + @Autowired + private TenantAppBuyOrderNumService tenantAppBuyOrderNumService; + + @Autowired + private TenantAppBuyOrderYearService tenantAppBuyOrderYearService; + + @Autowired + private TenantAppLinkService tenantAppLinkService; + + @Override + public List> queryPageData(InputObject inputObject) { + List> beans = super.queryPageData(inputObject); + tenantService.setMationForMap(beans, "tenantId", "tenantMation"); + return beans; + } + + @Override + public void validatorEntity(TenantAppBuyOrder entity) { + if (CollectionUtil.isEmpty(entity.getTenantAppBuyOrderNumList()) && CollectionUtil.isEmpty(entity.getTenantAppBuyOrderYearList())) { + throw new CustomException("订单信息不能为空."); + } + String totalPrice = "0"; + if (CollectionUtil.isNotEmpty(entity.getTenantAppBuyOrderNumList())) { + for (TenantAppBuyOrderNum tenantAppBuyOrderNum : entity.getTenantAppBuyOrderNumList()) { + String allPrice = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(tenantAppBuyOrderNum.getAccountNum()), tenantAppBuyOrderNum.getUnitPrice()); + tenantAppBuyOrderNum.setAllPrice(allPrice); + totalPrice = CalculationUtil.add(totalPrice, allPrice); + } + } + if (CollectionUtil.isNotEmpty(entity.getTenantAppBuyOrderYearList())) { + for (TenantAppBuyOrderYear tenantAppBuyOrderYear : entity.getTenantAppBuyOrderYearList()) { + String allPrice = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(tenantAppBuyOrderYear.getAccountYear()), tenantAppBuyOrderYear.getUnitPrice()); + tenantAppBuyOrderYear.setAllPrice(allPrice); + totalPrice = CalculationUtil.add(totalPrice, allPrice); + } + } + entity.setAllPrice(totalPrice); + } + + @Override + public void writePostpose(TenantAppBuyOrder entity, String userId) { + tenantAppBuyOrderNumService.saveList(entity.getId(), entity.getTenantAppBuyOrderNumList()); + tenantAppBuyOrderYearService.saveList(entity.getId(), entity.getTenantAppBuyOrderYearList()); + super.writePostpose(entity, userId); + } + + @Override + public TenantAppBuyOrder getDataFromDb(String id) { + TenantAppBuyOrder tenantAppBuyOrder = super.getDataFromDb(id); + tenantAppBuyOrder.setTenantAppBuyOrderNumList(tenantAppBuyOrderNumService.selectByParentId(id)); + tenantAppBuyOrder.setTenantAppBuyOrderYearList(tenantAppBuyOrderYearService.selectByParentId(id)); + return tenantAppBuyOrder; + } + + @Override + public TenantAppBuyOrder selectById(String id) { + TenantAppBuyOrder tenantAppBuyOrder = super.selectById(id); + tenantService.setDataMation(tenantAppBuyOrder, TenantAppBuyOrder::getTenantId); + if (CollectionUtil.isNotEmpty(tenantAppBuyOrder.getTenantAppBuyOrderYearList())) { + List appIds = tenantAppBuyOrder.getTenantAppBuyOrderYearList().stream().map(TenantAppBuyOrderYear::getAppId).collect(Collectors.toList()); + Map tenantAppMap = tenantAppService.queryTenantAppByAppId(appIds.toArray(new String[]{})); + tenantAppBuyOrder.getTenantAppBuyOrderYearList().forEach(tenantAppBuyOrderYear -> { + tenantAppBuyOrderYear.setAppMation(tenantAppMap.get(tenantAppBuyOrderYear.getAppId())); + }); + } + return tenantAppBuyOrder; + } + + @Override + public void approvalEndIsSuccess(TenantAppBuyOrder entity) { + TenantAppBuyOrder tenantAppBuyOrder = selectById(entity.getId()); + if (CollectionUtil.isNotEmpty(tenantAppBuyOrder.getTenantAppBuyOrderNumList())) { + tenantAppBuyOrder.getTenantAppBuyOrderNumList().forEach(tenantAppBuyOrderNum -> { + tenantService.editTenantAccountNumber(tenantAppBuyOrder.getTenantId(), tenantAppBuyOrderNum.getAccountNum()); + }); + } + + if (CollectionUtil.isNotEmpty(tenantAppBuyOrder.getTenantAppBuyOrderYearList())) { + tenantAppBuyOrder.getTenantAppBuyOrderYearList().forEach(tenantAppBuyOrderYear -> { + tenantAppLinkService.saveTenantAppLink(tenantAppBuyOrder.getTenantId(), tenantAppBuyOrderYear.getAppId(), tenantAppBuyOrderYear.getAccountYear()); + }); + } + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderYearServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderYearServiceImpl.java new file mode 100644 index 0000000..ac468c6 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppBuyOrderYearServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tenant.dao.TenantAppBuyOrderYearDao; +import com.skyeye.tenant.entity.TenantAppBuyOrderYear; +import com.skyeye.tenant.service.TenantAppBuyOrderYearService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: TenantAppBuyOrderYearServiceImpl + * @Description: 订单-购买应用年限管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "订单-购买应用年限管理", groupName = "租户管理", manageShow = false) +public class TenantAppBuyOrderYearServiceImpl extends SkyeyeBusinessServiceImpl implements TenantAppBuyOrderYearService { + + @Override + public void saveList(String parentId, List beans) { + deleteByParentId(parentId); + if (CollectionUtil.isNotEmpty(beans)) { + for (TenantAppBuyOrderYear tenantAppBuyOrderYear : beans) { + tenantAppBuyOrderYear.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppBuyOrderYear::getParentId), parentId); + remove(queryWrapper); + } + + @Override + public List selectByParentId(String parentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppBuyOrderYear::getParentId), parentId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppLinkServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppLinkServiceImpl.java new file mode 100644 index 0000000..02a3783 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppLinkServiceImpl.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tenant.dao.TenantAppLinkDo; +import com.skyeye.tenant.entity.TenantAppLink; +import com.skyeye.tenant.service.TenantAppLinkService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: TenantAppLinkServiceImpl + * @Description: 租户与应用的关系管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 20:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "租户与应用的关系管理", groupName = "租户管理") +public class TenantAppLinkServiceImpl extends SkyeyeBusinessServiceImpl implements TenantAppLinkService { + + @Override + public void saveTenantAppLink(String tenantId, String appId, Integer year) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppLink::getTenantId), tenantId); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppLink::getAppId), appId); + TenantAppLink tenantAppLink = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(tenantAppLink)) { + TenantAppLink newTenantAppLink = new TenantAppLink(); + newTenantAppLink.setTenantId(tenantId); + newTenantAppLink.setAppId(appId); + String currentTime = DateUtil.getYmdTimeAndToString(); + newTenantAppLink.setStartTime(currentTime); + String endTime = DateUtil.getDate(currentTime, year); + newTenantAppLink.setEndTime(endTime); + createEntity(newTenantAppLink, StrUtil.EMPTY); + } else { + String endTime = DateUtil.getDate(tenantAppLink.getEndTime(), year); + tenantAppLink.setEndTime(endTime); + updateEntity(tenantAppLink, StrUtil.EMPTY); + } + } + + @Override + public List selectByTenantId(String tenantId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppLink::getTenantId), tenantId); + List tenantAppLinkList = list(queryWrapper); + return tenantAppLinkList; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppMenuServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppMenuServiceImpl.java new file mode 100644 index 0000000..4c8fd9d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppMenuServiceImpl.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tenant.dao.TenantAppMenuDao; +import com.skyeye.tenant.entity.TenantAppMenu; +import com.skyeye.tenant.service.TenantAppMenuService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: TenantAppMenuServiceImpl + * @Description: 应用与菜单的关系管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "应用与菜单的关系管理", groupName = "租户管理", manageShow = false) +public class TenantAppMenuServiceImpl extends SkyeyeBusinessServiceImpl implements TenantAppMenuService { + + @Override + public void saveList(String appId, Integer type, List beans) { + deleteByAppId(appId, type); + if (CollectionUtil.isNotEmpty(beans)) { + for (TenantAppMenu tenantAppMenu : beans) { + tenantAppMenu.setAppId(appId); + tenantAppMenu.setType(type); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByAppId(String appId, Integer type) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppMenu::getAppId), appId); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppMenu::getType), type); + remove(queryWrapper); + } + + @Override + public void deleteByAppId(String appId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppMenu::getAppId), appId); + remove(queryWrapper); + } + + @Override + public List selectByAppId(String appId, Integer type) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppMenu::getAppId), appId); + queryWrapper.eq(MybatisPlusUtil.toColumns(TenantAppMenu::getType), type); + List list = list(queryWrapper); + return list; + } + + @Override + public List selectObjectIdsByAppId(String appId, Integer type) { + List list = selectByAppId(appId, type); + if (CollectionUtil.isNotEmpty(list)) { + return list.stream().map(TenantAppMenu::getObjectId).collect(Collectors.toList()); + } + return CollectionUtil.newArrayList(); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppServiceImpl.java new file mode 100644 index 0000000..0fddcb9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantAppServiceImpl.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.menu.dao.AppWorkPageDao; +import com.skyeye.menu.dao.SysEveMenuDao; +import com.skyeye.tenant.classenum.TenantAppMenuType; +import com.skyeye.tenant.dao.TenantAppDao; +import com.skyeye.tenant.entity.TenantApp; +import com.skyeye.tenant.entity.TenantAppMenu; +import com.skyeye.tenant.service.TenantAppMenuService; +import com.skyeye.tenant.service.TenantAppService; +import com.skyeye.win.service.SysEveDesktopService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: TenantAppServiceImpl + * @Description: 租户应用管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/29 16:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "租户应用管理", groupName = "租户管理") +public class TenantAppServiceImpl extends SkyeyeBusinessServiceImpl implements TenantAppService { + + @Autowired + private TenantAppMenuService tenantAppMenuService; + + @Autowired + private SysEveDesktopService sysEveDesktopService; + + @Autowired + private SysEveMenuDao sysEveMenuDao; + + @Autowired + private AppWorkPageDao appWorkPageDao; + + @Override + public TenantApp getDataFromDb(String id) { + TenantApp tenantApp = super.getDataFromDb(id); + List menuIds = tenantAppMenuService.selectObjectIdsByAppId(id, TenantAppMenuType.PC.getKey()); + List appMenuIds = tenantAppMenuService.selectObjectIdsByAppId(id, TenantAppMenuType.APP.getKey()); + tenantApp.setMenuIds(menuIds); + tenantApp.setAppMenuIds(appMenuIds); + return tenantApp; + } + + @Override + public void deletePostpose(String id) { + tenantAppMenuService.deleteByAppId(id); + } + + @Override + public void queryTenantAppBandMenuList(InputObject inputObject, OutputObject outputObject) { + List> beans = sysEveMenuDao.queryAllMenuList(); + // 获取桌面信息 + List> desktopList = sysEveDesktopService.queryAllDataForMap(); + beans.addAll(desktopList); + + for (Map bean : beans) { + String[] str = bean.get("pId").toString().split(","); + bean.put("pId", str[str.length - 1]); + } + outputObject.setBeans(beans); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editTenantAppPCAuth(InputObject inputObject, OutputObject outputObject) { + TenantApp tenantApp = inputObject.getParams(TenantApp.class); + List beans = tenantApp.getMenuIds().stream().map(menuId -> { + TenantAppMenu tenantAppMenu = new TenantAppMenu(); + tenantAppMenu.setObjectId(menuId); + return tenantAppMenu; + }).collect(Collectors.toList()); + tenantAppMenuService.saveList(tenantApp.getId(), TenantAppMenuType.PC.getKey(), beans); + refreshCache(tenantApp.getId()); + } + + @Override + public void queryTenantAppBandAppMenuList(InputObject inputObject, OutputObject outputObject) { + List> beans = appWorkPageDao.queryAllAppMenuList(); + // 获取桌面信息 + List> desktopList = sysEveDesktopService.queryAllDataForMap(); + beans.addAll(desktopList); + outputObject.setBeans(beans); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editTenantAppAppMenuById(InputObject inputObject, OutputObject outputObject) { + TenantApp tenantApp = inputObject.getParams(TenantApp.class); + List beans = tenantApp.getAppMenuIds().stream().map(appMenuId -> { + TenantAppMenu tenantAppMenu = new TenantAppMenu(); + tenantAppMenu.setObjectId(appMenuId); + return tenantAppMenu; + }).collect(Collectors.toList()); + tenantAppMenuService.saveList(tenantApp.getId(), TenantAppMenuType.APP.getKey(), beans); + refreshCache(tenantApp.getId()); + } + + @Override + public void queryAllTenantAppList(InputObject inputObject, OutputObject outputObject) { + List tenantApps = list(); + outputObject.setBeans(tenantApps); + outputObject.settotal(tenantApps.size()); + } + + @Override + public Map queryTenantAppByAppId(String... appId) { + List appIdList = Arrays.asList(appId); + if (CollectionUtil.isEmpty(appIdList)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, appIdList); + List list = list(queryWrapper); + return list.stream().collect(Collectors.toMap(TenantApp::getId, tenantApp -> tenantApp)); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantServiceImpl.java new file mode 100644 index 0000000..eb9725c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/tenant/service/impl/TenantServiceImpl.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tenant.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.tenant.dao.TenantDao; +import com.skyeye.tenant.entity.Tenant; +import com.skyeye.tenant.entity.TenantApp; +import com.skyeye.tenant.entity.TenantAppLink; +import com.skyeye.tenant.service.TenantAppLinkService; +import com.skyeye.tenant.service.TenantAppService; +import com.skyeye.tenant.service.TenantService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: TenantServiceImpl + * @Description: 租户服务实现层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/28 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "租户管理", groupName = "租户管理") +public class TenantServiceImpl extends SkyeyeBusinessServiceImpl implements TenantService { + + @Autowired + private TenantAppLinkService tenantAppLinkService; + + @Autowired + private TenantAppService tenantAppService; + + @Override + public void createPrepose(Tenant entity) { + entity.setAccountNum(CommonNumConstants.NUM_ZERO); + } + + @Override + public Tenant selectById(String id) { + Tenant tenant = super.selectById(id); + List tenantAppLinkList = tenantAppLinkService.selectByTenantId(id); + if (CollectionUtil.isNotEmpty(tenantAppLinkList)) { + List appIds = tenantAppLinkList.stream().map(TenantAppLink::getAppId).collect(Collectors.toList()); + Map tenantAppMap = tenantAppService.queryTenantAppByAppId(appIds.toArray(new String[]{})); + tenantAppLinkList.forEach(tenantAppLink -> { + tenantAppLink.setAppMation(tenantAppMap.get(tenantAppLink.getAppId())); + }); + } + tenant.setTenantAppLinkList(tenantAppLinkList); + return tenant; + } + + @Override + public void editTenantAccountNumber(String tenantId, Integer accountNumber) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, tenantId); + Tenant tenant = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(tenant) && StrUtil.isNotEmpty(tenant.getId())) { + Integer accountNum = tenant.getAccountNum() + accountNumber; + tenant.setAccountNum(accountNum); + updateById(tenant); + refreshCache(tenantId); + } else { + throw new CustomException("租户不存在"); + } + } + + @Override + public void queryAllTenantList(InputObject inputObject, OutputObject outputObject) { + List tenants = queryAllData(); + outputObject.setBeans(tenants); + outputObject.settotal(tenants.size()); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/EditUploadController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/EditUploadController.java new file mode 100644 index 0000000..ec769bf --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/EditUploadController.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ueditor.controller; + +import com.alibaba.fastjson.JSONObject; +import com.skyeye.ueditor.service.EditUploadService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +@RestController +public class EditUploadController { + + @Autowired + private EditUploadService editUploadService; + + /** + * 上传富文本图片 + * + * @param req + * @return + */ + @RequestMapping("/upload/editUploadController/uploadContentPic") + public Map uploadContentPic(HttpServletRequest req) { + return editUploadService.uploadContentPic(req); + } + + /** + * 回显富文本图片 + * + * @param req + * @param callback + * @return + */ + @RequestMapping("/upload/editUploadController/downloadContentPic") + public String downloadContentPic(HttpServletRequest req, @RequestParam("callback") String callback, @RequestParam("userId") String userId) { + return callback + "(" + JSONObject.toJSONString(editUploadService.downloadContentPic(req, userId)) + ")"; + } + + @RequestMapping("/upload/editUploadController/ueeditorConif") + public String ueeditorConif(HttpServletRequest request, @RequestParam("callback") String callback, + @RequestParam("fileBasePath") String fileBasePath) { + return callback + "(" + PublicMsg.getUeditorConfig(fileBasePath) + ")"; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/PublicMsg.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/PublicMsg.java new file mode 100644 index 0000000..ad34ba8 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/controller/PublicMsg.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.ueditor.controller; + +public class PublicMsg { + public final static String UEDITOR_CONFIG = "{\n" + + " \"imageActionName\": \"uploadimage\",\n" + + " \"imageFieldName\": \"upfile\",\n" + + " \"imageMaxSize\": 2048000,\n" + + " \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + + " \"imageCompressEnable\": true,\n" + + " \"imageCompressBorder\": 1600,\n" + + " \"imageInsertAlign\": \"none\",\n" + + " \"imageUrlPrefix\": \"{imageUrlPrefix}\",\n" + + " \"imagePathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + "\n" + + " \"scrawlActionName\": \"uploadscrawl\",\n" + + " \"scrawlFieldName\": \"upfile\",\n" + + " \"scrawlPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + " \"scrawlMaxSize\": 2048000,\n" + + " \"scrawlUrlPrefix\": \"\",\n" + + " \"scrawlInsertAlign\": \"none\",\n" + + "\n" + + " \"snapscreenActionName\": \"uploadimage\",\n" + + " \"snapscreenPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + " \"snapscreenUrlPrefix\": \"\",\n" + + " \"snapscreenInsertAlign\": \"none\",\n" + + "\n" + + " \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" + + " \"catcherActionName\": \"catchimage\",\n" + + " \"catcherFieldName\": \"source\",\n" + + " \"catcherPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + " \"catcherUrlPrefix\": \"\",\n" + + " \"catcherMaxSize\": 2048000,\n" + + " \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + + "\n" + + " \"videoActionName\": \"uploadvideo\",\n" + + " \"videoFieldName\": \"upfile\",\n" + + " \"videoPathFormat\": \"/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + " \"videoUrlPrefix\": \"\",\n" + + " \"videoMaxSize\": 102400000,\n" + + " \"videoAllowFiles\": [\n" + + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"],\n" + + "\n" + + " \"fileActionName\": \"uploadfile\",\n" + + " \"fileFieldName\": \"upfile\",\n" + + " \"filePathFormat\": \"/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" + + " \"fileUrlPrefix\": \"\",\n" + + " \"fileMaxSize\": 51200000,\n" + + " \"fileAllowFiles\": [\n" + + " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" + + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" + + " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" + + " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" + + " ],\n" + + "\n" + + " \"imageManagerActionName\": \"listimage\",\n" + + " \"imageManagerListPath\": \"/ueditor/jsp/upload/image/\",\n" + + " \"imageManagerListSize\": 20,\n" + + " \"imageManagerUrlPrefix\": \"{imageManagerUrlPrefix}\",\n" + + " \"imageManagerInsertAlign\": \"none\",\n" + + " \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" + + "\n" + + " \"fileManagerActionName\": \"listfile\",\n" + + " \"fileManagerListPath\": \"/ueditor/jsp/upload/file/\",\n" + + " \"fileManagerUrlPrefix\": \"{fileManagerUrlPrefix}\",\n" + + " \"fileManagerListSize\": 20,\n" + + " \"fileManagerAllowFiles\": [\n" + + " \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" + + " \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" + + " \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" + + " \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" + + " \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" + + " ] \n" + + "\n" + + "}"; + + public static String getUeditorConfig(String fileBasePath) { + return UEDITOR_CONFIG + .replace("{imageUrlPrefix}", fileBasePath) + .replace("{fileManagerUrlPrefix}", fileBasePath) + .replace("{imageManagerUrlPrefix}", fileBasePath); + } + + /** + * Ueditor的返回状态类型 + */ + public enum UeditorMsg { + SUCCESS("SUCCESS"), ERROR("上传失败"); + private String v; + + UeditorMsg(String v) { + this.v = v; + } + + public String get() { + return this.v; + } + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/EditUploadService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/EditUploadService.java new file mode 100644 index 0000000..30d2530 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/EditUploadService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ueditor.service; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public interface EditUploadService { + + Map uploadContentPic(HttpServletRequest req); + + Map downloadContentPic(HttpServletRequest req, String userId); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/impl/EditUploadServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/impl/EditUploadServiceImpl.java new file mode 100644 index 0000000..7934056 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/ueditor/service/impl/EditUploadServiceImpl.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.ueditor.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.constans.SysUserAuthConstants; +import com.skyeye.common.object.GetUserToken; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.FileUtil; +import com.skyeye.eve.dao.EditUploadDao; +import com.skyeye.jedis.JedisClientService; +import com.skyeye.ueditor.service.EditUploadService; +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.Service; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + + +@Service +public class EditUploadServiceImpl implements EditUploadService { + + private static final Logger LOGGER = LoggerFactory.getLogger(EditUploadServiceImpl.class); + + @Autowired + private EditUploadDao editUploadDao; + + @Autowired + public JedisClientService jedisClient; + + @Value("${IMAGES_PATH}") + private String tPath; + + /** + * 上传富文本图片 + */ + @Override + public Map uploadContentPic(HttpServletRequest req) { + Map rs = new HashMap<>(); + MultipartHttpServletRequest mReq; + MultipartFile file; + String fileName; + // 原始文件名 UEDITOR创建页面元素时的alt和title属性 + String originalFileName = ""; + try { + mReq = (MultipartHttpServletRequest) req; + // 从config.json中取得上传文件的ID + file = mReq.getFile("upfile"); + // 取得文件的原始文件名称 + fileName = file.getOriginalFilename(); + originalFileName = fileName; + /*你的处理图片的代码*/ + rs.put("state", "SUCCESS");// UEDITOR的规则:不为SUCCESS则显示state的内容 + rs.put("title", originalFileName); + rs.put("original", originalFileName); + String basePath = tPath + FileConstants.FileUploadPath.getSavePath(FileConstants.FileUploadPath.UEDITOR.getType()[0]); + FileUtil.createDirs(basePath); + + // 得到文件扩展名 + String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1); + // 自定义的文件名称 + String newFileName = String.format(Locale.ROOT, "%s.%s", System.currentTimeMillis(), fileExtName); + String path = basePath + "/" + newFileName; + file.transferTo(new File(path)); + // 能访问到你现在图片的路径 + String filePath = FileConstants.FileUploadPath.getVisitPath(FileConstants.FileUploadPath.UEDITOR.getType()[0]) + newFileName; + rs.put("url", filePath); + Map bean = new HashMap<>(); + bean.put("imgPath", filePath); + bean.put("fileOriginalName", fileName); + // 用户信息 + Map userMation = SysUserAuthConstants.getUserLoginRedisCache(GetUserToken.getUserTokenUserId(req)); + DataCommonUtil.setCommonData(bean, userMation.get("id").toString()); + bean.put("createType", "2"); + editUploadDao.insertFileImgMation(bean); + } catch (Exception ee) { + LOGGER.warn("uploadContentPic failed {}.", ee); + rs.put("state", "文件上传失败!"); + rs.put("url", ""); + rs.put("title", ""); + rs.put("original", ""); + } + return rs; + } + + /** + * 回显富文本图片 + */ + @Override + public Map downloadContentPic(HttpServletRequest req, String userId) { + Map rs = new HashMap<>(); + rs.put("state", "SUCCESS");// UEDITOR的规则:不为SUCCESS则显示state的内容 + Map bean = new HashMap<>(); + // 用户信息 + bean.put("createId", userId); + bean.put("url", ""); + int page = Integer.parseInt(req.getParameter("start")) / Integer.parseInt(req.getParameter("size")); + page++; + int limit = Integer.parseInt(req.getParameter("size")); + Page pages = PageHelper.startPage(page, limit); + List> beans = editUploadDao.queryFileImgMation(bean); + //获取当前页数的总数 + long total = pages.getTotal(); + rs.put("list", beans); + rs.put("total", total); + rs.put("start", req.getParameter("start")); + return rs; + } + + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/TalkWebSocket.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/TalkWebSocket.java new file mode 100644 index 0000000..35090e1 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/TalkWebSocket.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.websocket; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.constans.SocketConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.SpringUtils; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.eve.dao.CompanyTalkGroupDao; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @ClassName: TalkWebSocket + * @Description: 聊天/消息推送 + * @author: skyeye云系列--卫志强 + * @date: 2020年11月14日 下午9:36:38 + * @Copyright: 2020 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Component +@ServerEndpoint("/talkwebsocket/{userId}") +public class TalkWebSocket { + + private static final Logger LOGGER = LoggerFactory.getLogger(TalkWebSocket.class); + + /** + * 在线人数 + */ + public static int onlineNumber = 0; + /** + * 以用户的姓名为key,WebSocket为对象保存起来 + */ + private static Map clients = new ConcurrentHashMap(); + /** + * 会话 + */ + private Session session; + /** + * 用户id + */ + private String userId; + + /** + * 建立连接 + * + * @param session + */ + @OnOpen + public void onOpen(@PathParam("userId") String userId, Session session) { + if (clients.containsKey(userId)) { + return; + } + onlineNumber++; + LOGGER.info("现在来连接的客户id: {}, 用户名: {}", session.getId(), userId); + this.userId = userId; + this.session = session; + LOGGER.info("有新连接加入! 当前在线人数: {}", onlineNumber); + // 先给所有人发送通知,说我上线了 + Map map1 = new HashMap<>(); + map1.put("messageType", SocketConstants.MessageType.First.getType()); + map1.put("userId", userId); + sendMessageAll(JSONUtil.toJsonStr(map1), userId); + + // 把自己的信息加入到map当中去 + clients.put(userId, this); + // 给自己发一条消息:告诉自己现在都有谁在线 + Map map2 = new HashMap<>(); + map2.put("messageType", SocketConstants.MessageType.Third.getType()); + map2.put("onlineUsers", clients.keySet()); + sendMessageTo(JSONUtil.toJsonStr(map2), userId); + } + + @OnError + public void onError(Session session, Throwable error) { + LOGGER.warn("服务端发生了错误: {}", error.getMessage()); + } + + /** + * 连接关闭 + */ + @OnClose + public void onClose() { + if (!ToolUtil.isBlank(userId) && clients.containsKey(userId)) { + onlineNumber--; + clients.remove(userId); + Map map1 = new HashMap<>(); + map1.put("messageType", 2); + map1.put("onlineUsers", clients.keySet()); + map1.put("userId", userId); + sendMessageAll(JSONUtil.toJsonStr(map1), userId); + LOGGER.info("有连接关闭! 当前在线人数" + onlineNumber); + } + } + + /** + * 收到客户端的消息 + * + * @param message 消息 + * @param session 会话 + */ + @OnMessage + public void onMessage(String message, Session session) { + try { + LOGGER.info("来自客户端消息: {}, 客户端的id是: {}", message, session.getId()); + JSONObject jsonObject = JSONUtil.toBean(message, null); + int type = jsonObject.getInt("type"); + Map map1 = new HashMap<>(); + map1.put("messageType", type); + if (SocketConstants.MessageType.Fourth.getType() == type) {//普通消息 + map1 = SocketConstants.sendOrdinaryMsg(jsonObject); + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + companyTalkGroupDao.insertPersonToPersonMessage(map1); + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if (SocketConstants.MessageType.Fifth.getType() == type) {//系统消息 + + } else if (SocketConstants.MessageType.Sixth.getType() == type) {//全体消息 + map1 = SocketConstants.sendAllPeopleMsg(jsonObject); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if (SocketConstants.MessageType.Seventh.getType() == type) {//群组邀请消息 + map1.put("toId", jsonObject.getStr("to"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if (SocketConstants.MessageType.Eighth.getType() == type) {//隐身消息 + map1.put("userId", jsonObject.getStr("userId")); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if (SocketConstants.MessageType.Ninth.getType() == type) {//隐身上线消息 + map1.put("userId", jsonObject.getStr("userId")); + sendMessageAll(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } else if (SocketConstants.MessageType.Tenth.getType() == type) {//搜索账号入群审核同意后通知用户加载群信息 + map1 = SocketConstants.sendAgreeJoinGroupMsg(jsonObject); + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("to")); + } else if (SocketConstants.MessageType.Eleventh.getType() == type) {//群聊 + map1 = SocketConstants.sendGroupTalkPeopleMsg(jsonObject); + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + Map groupState = companyTalkGroupDao.queryGroupStateById(map1); + if ("1".equals(groupState.get("state").toString())) {//正常 + //插入消息记录 + map1.put("createTime", DateUtil.getTimeAndToString()); + map1.put("dataId", ToolUtil.getSurFaceId()); + companyTalkGroupDao.insertPersonToGroupMessage(map1); + sendMessageToThisGroupMember(map1); + } else { + map1.clear(); + map1.put("messageType", "1301"); + map1.put("groupId", jsonObject.getStr("to"));//收件人id,在此处为群聊id + sendMessageTo(JSONUtil.toJsonStr(map1), jsonObject.getStr("userId")); + } + } else if (SocketConstants.MessageType.Twelfth.getType() == type) {//退出群聊--创建人接收消息 + map1 = SocketConstants.sendOutGroupToCreaterMsg(jsonObject); + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + Map groupMation = companyTalkGroupDao.queryGroupCreateIdById(map1); + map1.put("toId", groupMation.get("createId"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map1), groupMation.get("createId").toString()); + } else if (SocketConstants.MessageType.Thirteenth.getType() == type) {//解散群聊--所有人接收消息 + map1 = SocketConstants.sendDisbandGroupToAllMsg(jsonObject); + sendMessageToThisGroupMember(map1); + } + } catch (Exception e) { + LOGGER.warn("发生了错误了: {}", e); + } + } + + /** + * @param map + * @Title: sendMessageToThisGroupMember + * @Description: 发送消息给当前群的所有人 + * @return: void + */ + private void sendMessageToThisGroupMember(Map map) { + CompanyTalkGroupDao companyTalkGroupDao = SpringUtils.getBean(CompanyTalkGroupDao.class); + List> members = companyTalkGroupDao.queryGroupMemberByGroupIdAndNotThisUser(map); + if (members.size() > 0) { + for (Map member : members) { + map.put("toId", member.get("id"));//收件人id + sendMessageTo(JSONUtil.toJsonStr(map), member.get("id").toString()); + } + } + } + + /** + * 发送给指定用户消息 + * + * @param message + * @param userId + */ + public void sendMessageTo(String message, String userId) { + TalkWebSocket item = clients.get(userId); + if (item != null) { + item.session.getAsyncRemote().sendText(message); + } + } + + /** + * 发送给全部用户消息 + * + * @param message + * @param FromUserName + */ + public void sendMessageAll(String message, String FromUserName) { + for (TalkWebSocket item : clients.values()) { + item.session.getAsyncRemote().sendText(message); + } + } + + /** + * 获取当前在线的用户id + * + * @return + */ + public static Set getOnlineUserId() { + return clients.keySet(); + } + + public static synchronized int getOnlineCount() { + return onlineNumber; + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/WebSocketConfig.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/WebSocketConfig.java new file mode 100644 index 0000000..5382583 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/websocket/WebSocketConfig.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.websocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveDesktopController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveDesktopController.java new file mode 100644 index 0000000..508a2b3 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveDesktopController.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysDesktop; +import com.skyeye.win.service.SysEveDesktopService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveDesktopController + * @Description: 桌面信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:19 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "桌面信息管理", tags = "桌面信息管理", modelName = "基础模块") +public class SysEveDesktopController { + + @Autowired + private SysEveDesktopService sysEveDesktopService; + + @ApiOperation(id = "desktop001", value = "获取桌面列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveDesktopController/querySysDesktopList") + public void querySysDesktopList(InputObject inputObject, OutputObject outputObject) { + sysEveDesktopService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeSysEveDesktopMation", value = "新增/编辑桌面信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysDesktop.class) + @RequestMapping("/post/SysEveDesktopController/writeSysEveDesktopMation") + public void writeSysEveDesktopMation(InputObject inputObject, OutputObject outputObject) { + sysEveDesktopService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "desktop003", value = "删除桌面信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveDesktopController/deleteSysDesktopById") + public void deleteSysDesktopById(InputObject inputObject, OutputObject outputObject) { + sysEveDesktopService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "desktop006", value = "通过id查找对应的桌面", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveDesktopController/selectSysDesktopById") + public void selectSysDesktopById(InputObject inputObject, OutputObject outputObject) { + sysEveDesktopService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "desktop011", value = "获取全部的桌面用于系统菜单", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveDesktopController/queryAllSysDesktopList") + public void queryAllSysDesktopList(InputObject inputObject, OutputObject outputObject) { + sysEveDesktopService.queryAllSysDesktopList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinBgPicController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinBgPicController.java new file mode 100644 index 0000000..2591144 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinBgPicController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysEveWinBgPic; +import com.skyeye.win.service.SysEveWinBgPicService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveWinBgPicController + * @Description: win系统桌面图片控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "win系统桌面图片", tags = "win系统桌面图片", modelName = "win系统桌面图片") +public class SysEveWinBgPicController { + + @Autowired + private SysEveWinBgPicService sysEveWinBgPicService; + + /** + * 获取win系统桌面图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinBgPicList", value = "获取win系统桌面图片列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveWinBgPicController/querySysEveWinBgPicList") + public void querySysEveWinBgPicList(InputObject inputObject, OutputObject outputObject) { + sysEveWinBgPicService.queryPageList(inputObject, outputObject); + } + + /** + * 添加win系统桌面图片信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSysEveWinBgPic", value = "添加win系统桌面图片信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SysEveWinBgPic.class) + @RequestMapping("/post/SysEveWinBgPicController/insertSysEveWinBgPic") + public void insertSysEveWinBgPic(InputObject inputObject, OutputObject outputObject) { + sysEveWinBgPicService.createEntity(inputObject, outputObject); + } + + /** + * 删除win系统桌面图片信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSysEveWinBgPicById", value = "删除win系统桌面图片信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveWinBgPicController/deleteSysEveWinBgPicById") + public void deleteSysEveWinBgPicById(InputObject inputObject, OutputObject outputObject) { + sysEveWinBgPicService.deleteById(inputObject, outputObject); + } + + /** + * 获取用户自定义的win系统桌面图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinBgPicCustomList", value = "获取用户自定义的win系统桌面图片列表", method = "POST", allUse = "2") + @RequestMapping("/post/SysEveWinBgPicController/querySysEveWinBgPicCustomList") + public void querySysEveWinBgPicCustomList(InputObject inputObject, OutputObject outputObject) { + sysEveWinBgPicService.querySysEveWinBgPicCustomList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinController.java new file mode 100644 index 0000000..61f52ff --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysWin; +import com.skyeye.win.service.SysEveWinService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveWinController + * @Description: 服务管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "前台服务管理", tags = "前台服务管理", modelName = "基础模块") +public class SysEveWinController { + + @Autowired + private SysEveWinService sysEveWinService; + + /** + * 获取服务信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysevewin001", value = "获取服务信息列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveWinController/queryWinMationList") + public void queryWinMationList(InputObject inputObject, OutputObject outputObject) { + sysEveWinService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysEveWinMation", value = "新增/编辑服务信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysWin.class) + @RequestMapping("/post/SysEveWinController/insertWinMation") + public void insertWinMation(InputObject inputObject, OutputObject outputObject) { + sysEveWinService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id查询服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysevewin003", value = "根据id查询服务信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveWinController/querySysWinById") + public void querySysWinById(InputObject inputObject, OutputObject outputObject) { + sysEveWinService.selectById(inputObject, outputObject); + } + + /** + * 删除服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sysevewin005", value = "删除桌面信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveWinController/deleteWinMationById") + public void deleteWinMationById(InputObject inputObject, OutputObject outputObject) { + sysEveWinService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有的服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinList", value = "获取所有的服务信息", method = "GET", allUse = "2") + @RequestMapping("/post/SysEveWinController/querySysEveWinList") + public void querySysEveWinList(InputObject inputObject, OutputObject outputObject) { + sysEveWinService.querySysEveWinList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinDragDropController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinDragDropController.java new file mode 100644 index 0000000..9a05dde --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinDragDropController.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.service.SysEveWinDragDropService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SysEveWinDragDropController { + + @Autowired + private SysEveWinDragDropService sysEveWinDragDropService; + + /** + * 用户自定义创建菜单盒子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/insertWinCustomMenuBox") + public void insertWinCustomMenuBox(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.insertWinCustomMenuBox(inputObject, outputObject); + } + + /** + * 用户自定义创建菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/insertWinCustomMenu") + public void insertWinCustomMenu(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.insertWinCustomMenu(inputObject, outputObject); + } + + /** + * 用户删除自定义菜单或文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/deleteWinMenuOrBoxById") + public void deleteWinMenuOrBoxById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.deleteWinMenuOrBoxById(inputObject, outputObject); + } + + /** + * 用户自定义父菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/editMenuParentIdById") + public void editMenuParentIdById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.editMenuParentIdById(inputObject, outputObject); + } + + /** + * 获取菜单类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/queryMenuMationTypeById") + public void queryMenuMationTypeById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.queryMenuMationTypeById(inputObject, outputObject); + } + + /** + * 编辑自定义盒子时回显信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/queryCustomMenuBoxMationEditById") + public void queryCustomMenuBoxMationEditById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.queryCustomMenuBoxMationEditById(inputObject, outputObject); + } + + /** + * 编辑自定义盒子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/editCustomMenuBoxMationById") + public void editCustomMenuBoxMationById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.editCustomMenuBoxMationById(inputObject, outputObject); + } + + /** + * 编辑快捷方式时回显信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/queryCustomMenuMationEditById") + public void queryCustomMenuMationEditById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.queryCustomMenuMationEditById(inputObject, outputObject); + } + + /** + * 编辑快捷方式 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/editCustomMenuMationById") + public void editCustomMenuMationById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.editCustomMenuMationById(inputObject, outputObject); + } + + /** + * 系统菜单发送到桌面快捷方式 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @RequestMapping("/post/SysEveWinDragDropController/editCustomMenuToDeskTopById") + public void editCustomMenuToDeskTopById(InputObject inputObject, OutputObject outputObject) { + sysEveWinDragDropService.editCustomMenuToDeskTopById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinLockBgPicController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinLockBgPicController.java new file mode 100644 index 0000000..a5768f9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinLockBgPicController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysEveWinLockBgPic; +import com.skyeye.win.service.SysEveWinLockBgPicService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveWinLockBgPicController + * @Description: win系统桌面锁屏图片控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/20 21:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "win系统桌面锁屏图片", tags = "win系统桌面锁屏图片", modelName = "win系统桌面锁屏图片") +public class SysEveWinLockBgPicController { + + @Autowired + private SysEveWinLockBgPicService sysEveWinLockBgPicService; + + /** + * 获取win系统锁屏桌面图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinLockBgPicList", value = "获取win系统锁屏桌面图片列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveWinLockBgPicController/querySysEveWinLockBgPicList") + public void querySysEveWinLockBgPicList(InputObject inputObject, OutputObject outputObject) { + sysEveWinLockBgPicService.queryPageList(inputObject, outputObject); + } + + /** + * 添加win系统锁屏桌面图片信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSysEveWinLockBgPic", value = "添加win系统锁屏桌面图片信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SysEveWinLockBgPic.class) + @RequestMapping("/post/SysEveWinLockBgPicController/insertSysEveWinLockBgPic") + public void insertSysEveWinLockBgPic(InputObject inputObject, OutputObject outputObject) { + sysEveWinLockBgPicService.createEntity(inputObject, outputObject); + } + + /** + * 删除win系统锁屏桌面图片信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSysEveWinLockBgPicById", value = "删除win系统锁屏桌面图片信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveWinLockBgPicController/deleteSysEveWinLockBgPicById") + public void deleteSysEveWinLockBgPicById(InputObject inputObject, OutputObject outputObject) { + sysEveWinLockBgPicService.deleteById(inputObject, outputObject); + } + + /** + * 获取用户自定义的win系统桌面锁屏图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinLockBgPicCustomList", value = "获取用户自定义的win系统桌面锁屏图片列表", method = "POST", allUse = "2") + @RequestMapping("/post/SysEveWinLockBgPicController/querySysEveWinLockBgPicCustomList") + public void querySysEveWinLockBgPicCustomList(InputObject inputObject, OutputObject outputObject) { + sysEveWinLockBgPicService.querySysEveWinLockBgPicCustomList(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinThemeColorController.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinThemeColorController.java new file mode 100644 index 0000000..b871a6b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/controller/SysEveWinThemeColorController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysEveWinThemeColor; +import com.skyeye.win.service.SysEveWinThemeColorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SysEveWinThemeColorController + * @Description: win系统主题颜色控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/22 12:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "win系统主题颜色", tags = "win系统主题颜色", modelName = "win系统主题颜色") +public class SysEveWinThemeColorController { + + @Autowired + private SysEveWinThemeColorService sysEveWinThemeColorService; + + /** + * 获取win系统主题颜色列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysEveWinThemeColorList", value = "获取win系统主题颜色列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SysEveWinThemeColorController/querySysEveWinThemeColorList") + public void querySysEveWinThemeColorList(InputObject inputObject, OutputObject outputObject) { + sysEveWinThemeColorService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑win系统主题颜色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSysEveWinThemeColor", value = "添加/编辑win系统主题颜色信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SysEveWinThemeColor.class) + @RequestMapping("/post/SysEveWinThemeColorController/writeSysEveWinThemeColor") + public void writeSysEveWinThemeColor(InputObject inputObject, OutputObject outputObject) { + sysEveWinThemeColorService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除win系统主题颜色信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSysEveWinThemeColorById", value = "删除win系统主题颜色信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SysEveWinThemeColorController/deleteSysEveWinThemeColorById") + public void deleteSysEveWinThemeColorById(InputObject inputObject, OutputObject outputObject) { + sysEveWinThemeColorService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveDesktopDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveDesktopDao.java new file mode 100644 index 0000000..f991214 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveDesktopDao.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.win.entity.SysDesktop; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveDesktopDao + * @Description: 桌面信息管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/22 19:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveDesktopDao extends SkyeyeBaseMapper { + + List> querySysDesktopList(CommonPageInfo commonPageInfo); + + Map querySysDesktopStateAndMenuNumById(@Param("id") String id); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinBgPicDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinBgPicDao.java new file mode 100644 index 0000000..c850f03 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinBgPicDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.win.entity.SysEveWinBgPic; + +/** + * @ClassName: SysEveWinBgPicDao + * @Description: win系统桌面图片管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinBgPicDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDao.java new file mode 100644 index 0000000..74396a9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDao.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.win.entity.SysWin; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveWinDao + * @Description: 服务信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinDao extends SkyeyeBaseMapper { + + List> queryWinMationList(CommonPageInfo commonPageInfo); + + Map queryChildMationById(@Param("id") String id); + + List> querySysEveWinList(); +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDragDropDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDragDropDao.java new file mode 100644 index 0000000..af5ad33 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinDragDropDao.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import java.util.List; +import java.util.Map; + +public interface SysEveWinDragDropDao { + + List> queryMenuBoxNameInByName(Map map); + + Map queryWinCustomMenuBoxNumByUserId(Map map); + + int insertWinCustomMenuBox(Map map); + + List> queryMenuNameInByName(Map map); + + int insertWinCustomMenu(Map map); + + Map queryMenuMationFromSysById(Map map); + + int deleteCustomMenuById(Map map); + + int deleteCustomBoxMenuById(Map map); + + List> queryChildsMenuById(Map map); + + int deleteCustomMenuByIds(Map map); + + int deleteUserSysMenuByIds(List> removeChild); + + int deleteSysBoxMenuById(Map map); + + int delMenuParentIdById(Map map); + + int insertMenuParentId(Map map); + + int deleteCustomMenuParentByIds(Map map); + + Map queryMenuMationTypeById(Map map); + + Map queryCustomMenuBoxMationEditById(Map map); + + int editCustomMenuBoxMationById(Map map); + + Map queryCustomMenuMationEditById(Map map); + + int editCustomMenuMationById(Map map); + + Map queryCustomMenuToDeskTopById(Map map); + + int editCustomMenuToDeskTopById(Map map); + + Map queryMenuToDeskTopById(Map map); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinLockBgPicDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinLockBgPicDao.java new file mode 100644 index 0000000..1f9f94e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinLockBgPicDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.win.entity.SysEveWinLockBgPic; + +/** + * @ClassName: SysEveWinLockBgPicDao + * @Description: win系统桌面锁屏图片数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/20 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinLockBgPicDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinThemeColorDao.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinThemeColorDao.java new file mode 100644 index 0000000..c8c0cf2 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/dao/SysEveWinThemeColorDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.win.entity.SysEveWinThemeColor; + +/** + * @ClassName: SysEveWinThemeColorDao + * @Description: win系统主题颜色数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/22 12:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinThemeColorDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysDesktop.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysDesktop.java new file mode 100644 index 0000000..dd8fdf5 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysDesktop.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysDesktop + * @Description: 桌面管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sys:desktop") +@TableName(value = "sys_eve_desktop") +@ApiModel("桌面管理实体类") +public class SysDesktop extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "桌面名称", required = "required") + private String name; + + @TableField("logo") + @ApiModelProperty(value = "logo", required = "required") + private String logo; + + @TableField("app_page_url") + @ApiModelProperty(value = "手机端页面跳转地址") + private String appPageUrl; + + @TableField("order_by") + @ApiModelProperty(value = "序号", required = "required,num") + private Integer orderBy; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum枚举类", required = "required,num") + private Integer enabled; + + @TableField("code") + @ApiModelProperty(value = "区分桌面的code,唯一", required = "required") + private String desktopCode; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinBgPic.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinBgPic.java new file mode 100644 index 0000000..e942641 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinBgPic.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveWinBgPic + * @Description: win系统桌面图片实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sys:winBgPic", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_eve_win_bg_pic") +@ApiModel("win系统桌面图片实体类") +public class SysEveWinBgPic extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("pic_url") + @ApiModelProperty(value = "系统图片路径", required = "required") + private String picUrl; + + @TableField("pic_type") + @ApiModelProperty(value = "图片类型,参考#PicTypeEnum", required = "required,num") + private Integer picType; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinLockBgPic.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinLockBgPic.java new file mode 100644 index 0000000..57ccb9d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinLockBgPic.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveWinLockBgPic + * @Description: win系统桌面锁屏图片实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "sys:winLockBgPic", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_eve_win_lock_bg_pic") +@ApiModel("win系统桌面锁屏图片实体类") +public class SysEveWinLockBgPic extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("pic_url") + @ApiModelProperty(value = "系统图片路径", required = "required") + private String picUrl; + + @TableField("pic_type") + @ApiModelProperty(value = "图片类型,参考#PicTypeEnum", required = "required,num") + private Integer picType; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinThemeColor.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinThemeColor.java new file mode 100644 index 0000000..8604e6f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysEveWinThemeColor.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysEveWinThemeColor + * @Description: win系统主题颜色实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/22 12:50 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"colorClass"}) +@RedisCacheField(name = "sys:winThemeColor", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "sys_eve_win_theme_color") +@ApiModel("win系统主题颜色实体类") +public class SysEveWinThemeColor extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("color_class") + @ApiModelProperty(value = "颜色属性", required = "required") + private String colorClass; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysWin.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysWin.java new file mode 100644 index 0000000..7a92eb8 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/entity/SysWin.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SysWin + * @Description: 服务管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/30 0:09 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "sys:win") +@TableName(value = "sys_eve_win") +@ApiModel("服务管理实体类") +public class SysWin extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "服务名称", required = "required") + private String name; + + @TableField("content") + @ApiModelProperty(value = "描述") + private String content; + + @TableField("sys_url") + @ApiModelProperty(value = "服务地址") + private String sysUrl; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/enums/PicTypeEnum.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/enums/PicTypeEnum.java new file mode 100644 index 0000000..f956eb6 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/enums/PicTypeEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PicTypeEnum + * @Description: 图片类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:41 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PicTypeEnum implements SkyeyeEnumClass { + + SYSTEM_PUBLISH(1, "为系统发布图片,其他人不能操作", true, true), + USER_UPLOAD(2, "用户自定义上传", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveDesktopService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveDesktopService.java new file mode 100644 index 0000000..ff19463 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveDesktopService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysDesktop; + +/** + * @ClassName: SysEveDesktopService + * @Description: 桌面信息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/22 19:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveDesktopService extends SkyeyeBusinessService { + + void queryAllSysDesktopList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinBgPicService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinBgPicService.java new file mode 100644 index 0000000..6d31403 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinBgPicService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysEveWinBgPic; + +import java.util.List; + +/** + * @ClassName: SysEveWinBgPicService + * @Description: win系统桌面图片服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinBgPicService extends SkyeyeBusinessService { + + void querySysEveWinBgPicCustomList(InputObject inputObject, OutputObject outputObject); + + List querySystemSysEveWinBgPicList(); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinDragDropService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinDragDropService.java new file mode 100644 index 0000000..79cd3cc --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinDragDropService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +public interface SysEveWinDragDropService { + + void insertWinCustomMenuBox(InputObject inputObject, OutputObject outputObject); + + void insertWinCustomMenu(InputObject inputObject, OutputObject outputObject); + + void deleteWinMenuOrBoxById(InputObject inputObject, OutputObject outputObject); + + void editMenuParentIdById(InputObject inputObject, OutputObject outputObject); + + void queryMenuMationTypeById(InputObject inputObject, OutputObject outputObject); + + void queryCustomMenuBoxMationEditById(InputObject inputObject, OutputObject outputObject); + + void editCustomMenuBoxMationById(InputObject inputObject, OutputObject outputObject); + + void queryCustomMenuMationEditById(InputObject inputObject, OutputObject outputObject); + + void editCustomMenuMationById(InputObject inputObject, OutputObject outputObject); + + void editCustomMenuToDeskTopById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinLockBgPicService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinLockBgPicService.java new file mode 100644 index 0000000..a77db4a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinLockBgPicService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysEveWinLockBgPic; + +import java.util.List; + +/** + * @ClassName: SysEveWinLockBgPicService + * @Description: win系统桌面锁屏图片服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/20 21:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinLockBgPicService extends SkyeyeBusinessService { + + void querySysEveWinLockBgPicCustomList(InputObject inputObject, OutputObject outputObject); + + List querySystemSysEveWinLockBgPicList(); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinService.java new file mode 100644 index 0000000..28238dd --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinService.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.win.entity.SysWin; + +public interface SysEveWinService extends SkyeyeBusinessService { + + void querySysEveWinList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinThemeColorService.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinThemeColorService.java new file mode 100644 index 0000000..2c572df --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/SysEveWinThemeColorService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.win.entity.SysEveWinThemeColor; + +import java.util.List; + +/** + * @ClassName: SysEveWinThemeColorService + * @Description: win系统主题颜色服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/22 12:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveWinThemeColorService extends SkyeyeBusinessService { + + List querySysEveWinThemeColorList(); + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveDesktopServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveDesktopServiceImpl.java new file mode 100644 index 0000000..b04f651 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveDesktopServiceImpl.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.win.dao.SysEveDesktopDao; +import com.skyeye.win.entity.SysDesktop; +import com.skyeye.win.service.SysEveDesktopService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SysEveDesktopServiceImpl + * @Description: 桌面信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/22 19:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "桌面信息管理", groupName = "基础模块") +public class SysEveDesktopServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveDesktopService { + + @Autowired + private SysEveDesktopDao sysEveDesktopDao; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + commonPageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = sysEveDesktopDao.querySysDesktopList(commonPageInfo); + return beans; + } + + @Override + public void validatorEntity(SysDesktop entity) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysDesktop::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(SysDesktop::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(SysDesktop::getDesktopCode), entity.getDesktopCode())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SysDesktop checkSysEveDesktop = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkSysEveDesktop)) { + throw new CustomException("该桌面名称已存在,请更换."); + } + } + + @Override + protected void deletePreExecution(String id) { + Map bean = sysEveDesktopDao.querySysDesktopStateAndMenuNumById(id); + if (!"0".equals(bean.get("allNum").toString())) { + throw new CustomException("该桌面下包含有子菜单,无法删除."); + } + } + + /** + * 获取全部的桌面用于系统菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllSysDesktopList(InputObject inputObject, OutputObject outputObject) { + List> beans = queryAllDataForMap(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + @Override + public List> queryAllDataForMap() { + List> desktopList = super.queryAllDataForMap(); + desktopList.forEach(desktop -> { + desktop.put("pId", "0"); + desktop.put("sysName", "基础系统"); + desktop.put("pageType", "桌面"); + desktop.put("type", "page"); + }); + desktopList = desktopList.stream() + .sorted(Comparator.comparing(bean -> Integer.parseInt(bean.get("orderBy").toString()))).collect(Collectors.toList()); + return desktopList; + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinBgPicServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinBgPicServiceImpl.java new file mode 100644 index 0000000..c4a356d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinBgPicServiceImpl.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.win.dao.SysEveWinBgPicDao; +import com.skyeye.win.entity.SysEveWinBgPic; +import com.skyeye.win.enums.PicTypeEnum; +import com.skyeye.win.service.SysEveWinBgPicService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: SysEveWinBgPicServiceImpl + * @Description: win系统桌面图片服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/18 22:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "win系统桌面图片", groupName = "win系统桌面图片") +public class SysEveWinBgPicServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveWinBgPicService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private RedisCache redisCache; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinBgPic::getPicType), PicTypeEnum.SYSTEM_PUBLISH.getKey()); + return queryWrapper; + } + + @Override + public void createPostpose(SysEveWinBgPic entity, String userId) { + jedisClientService.del(Constants.SYS_WIN_BG_PIC_REDIS_KEY); + } + + @Override + public void deletePostpose(SysEveWinBgPic entity) { + String basePath = tPath + entity.getPicUrl().replace("/images/", ""); + FileUtil.deleteFile(basePath); + jedisClientService.del(Constants.SYS_WIN_BG_PIC_REDIS_KEY); + } + + /** + * 获取用户自定义的win系统桌面图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysEveWinBgPicCustomList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinBgPic::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinBgPic::getPicType), PicTypeEnum.USER_UPLOAD.getKey()); + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + @Override + public List querySystemSysEveWinBgPicList() { + return redisCache.getList(Constants.SYS_WIN_BG_PIC_REDIS_KEY, key -> { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinBgPic::getPicType), PicTypeEnum.SYSTEM_PUBLISH.getKey()); + List list = list(queryWrapper); + return list; + }, RedisConstants.THIRTY_DAY_SECONDS, SysEveWinBgPic.class); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinDragDropServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinDragDropServiceImpl.java new file mode 100644 index 0000000..97c7ac3 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinDragDropServiceImpl.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.ObjectConstant; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DataCommonUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.personnel.dao.SysEveUserDao; +import com.skyeye.win.dao.SysEveWinDragDropDao; +import com.skyeye.win.service.SysEveWinDragDropService; +import com.skyeye.jedis.JedisClientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class SysEveWinDragDropServiceImpl implements SysEveWinDragDropService { + + @Autowired + private SysEveWinDragDropDao sysEveWinDragDropDao; + + @Autowired + public SysEveUserDao sysEveUserDao; + + @Autowired + public JedisClientService jedisClient; + + /** + * 用户自定义创建菜单盒子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertWinCustomMenuBox(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + List> menuBoxNameList = sysEveWinDragDropDao.queryMenuBoxNameInByName(map); + if (menuBoxNameList != null && !menuBoxNameList.isEmpty()) { + outputObject.setreturnMessage("该名称已存在,请更换。"); + } else { + // 获取当前用户已经创建的菜单盒子中值最大的排序号 + Map orderNum = sysEveWinDragDropDao.queryWinCustomMenuBoxNumByUserId(map); + int order = 1; + if (orderNum != null && !orderNum.isEmpty()) { + order = Integer.parseInt(orderNum.get("orderNum").toString()) + 1; + } + map.put("order", order); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + sysEveWinDragDropDao.insertWinCustomMenuBox(map); + outputObject.setBean(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } + } + + /** + * 用户自定义创建菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void insertWinCustomMenu(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + List> menuBoxNameList = sysEveWinDragDropDao.queryMenuNameInByName(map); + if (menuBoxNameList != null && !menuBoxNameList.isEmpty()) { + outputObject.setreturnMessage("该名称已存在,请更换。"); + } else { + map.put("menuType", "html"); + map.put("menuParentId", "0"); + map.put("openType", "2"); + DataCommonUtil.setCommonData(map, inputObject.getLogParams().get("id").toString()); + sysEveWinDragDropDao.insertWinCustomMenu(map); + outputObject.setBean(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } + } + + /** + * 用户删除自定义菜单或文件夹 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void deleteWinMenuOrBoxById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + Map bean = sysEveWinDragDropDao.queryMenuMationFromSysById(map);//查询菜单 + if (bean != null && !bean.isEmpty()) { + // 菜单存在 + if ("1".equals(bean.get("type").toString())) { + // 要删除的菜单是系统菜单 + List> childs = sysEveWinDragDropDao.queryChildsMenuById(map); + List> removeChild = new ArrayList<>();//系统子菜单移出自定义删除表 + String delCustomMenu = "";//自定义子菜单直接删除 + for (Map child : childs) { + if ("1".equals(child.get("type").toString())) { + // 系统子菜单 + child.put("rowId", ToolUtil.getSurFaceId()); + child.put("createId", userId); + child.put("createTime", DateUtil.getTimeAndToString()); + removeChild.add(child); + } else if ("2".equals(child.get("type").toString())) { + // 自定义菜单 + delCustomMenu += child.get("id").toString(); + } + } + //删除系统子菜单 + if (!removeChild.isEmpty()) { + sysEveWinDragDropDao.deleteUserSysMenuByIds(removeChild); + } + // 删除自定义菜单 + Map delCustomMenuBean = new HashMap<>(); + delCustomMenuBean.put("ids", delCustomMenu); + sysEveWinDragDropDao.deleteCustomMenuByIds(delCustomMenuBean); + sysEveWinDragDropDao.deleteCustomMenuParentByIds(delCustomMenuBean); + // 删除系统文件夹 + Map delSysBoxMenuBean = new HashMap<>(); + delSysBoxMenuBean.put("menuId", map.get("id")); + DataCommonUtil.setCommonData(delSysBoxMenuBean, userId); + sysEveWinDragDropDao.deleteSysBoxMenuById(delSysBoxMenuBean); + } else if ("2".equals(bean.get("type").toString())) { + // 要删除的菜单是菜单文件夹(菜单盒子) + List> childs = sysEveWinDragDropDao.queryChildsMenuById(map); + List> removeChild = new ArrayList<>();//系统子菜单移出自定义删除表 + String delCustomMenu = "";//自定义子菜单直接删除 + for (Map child : childs) { + if ("1".equals(child.get("type").toString())) { + // 系统子菜单 + child.put("rowId", ToolUtil.getSurFaceId()); + child.put("createId", userId); + child.put("createTime", DateUtil.getTimeAndToString()); + removeChild.add(child); + } else if ("2".equals(child.get("type").toString())) { + // 自定义菜单 + delCustomMenu += child.get("id").toString(); + } + } + //删除系统子菜单 + if (!removeChild.isEmpty()) { + sysEveWinDragDropDao.deleteUserSysMenuByIds(removeChild); + } + //删除自定义菜单 + Map delCustomMenuBean = new HashMap<>(); + delCustomMenuBean.put("ids", delCustomMenu); + sysEveWinDragDropDao.deleteCustomMenuByIds(delCustomMenuBean); + sysEveWinDragDropDao.deleteCustomMenuParentByIds(delCustomMenuBean); + //删除自定义文件夹 + sysEveWinDragDropDao.deleteCustomBoxMenuById(map); + } else if ("3".equals(bean.get("type").toString())) { + // 要删除的菜单是自定义菜单,直接删除 + sysEveWinDragDropDao.deleteCustomMenuById(map); + } + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } else { + outputObject.setreturnMessage("该菜单不存在,请刷新页面"); + } + } + + /** + * 用户自定义父菜单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editMenuParentIdById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + sysEveWinDragDropDao.delMenuParentIdById(map); + map.put("id", ToolUtil.getSurFaceId()); + map.put("createTime", DateUtil.getTimeAndToString()); + if (!ToolUtil.isBlank(map.get("parentId").toString())) { + map.put("parentId", map.get("parentId").toString() + ","); + map.put("menuLevel", "1"); + } else { + map.put("parentId", "0"); + map.put("menuLevel", "0"); + } + sysEveWinDragDropDao.insertMenuParentId(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } + + /** + * 获取菜单类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMenuMationTypeById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map bean = sysEveWinDragDropDao.queryMenuMationTypeById(map); + outputObject.setBean(bean); + } + + /** + * 编辑自定义盒子时回显信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCustomMenuBoxMationEditById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Map bean = sysEveWinDragDropDao.queryCustomMenuBoxMationEditById(map); + outputObject.setBean(bean); + } + + /** + * 编辑自定义盒子 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editCustomMenuBoxMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + sysEveWinDragDropDao.editCustomMenuBoxMationById(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } + + /** + * 编辑快捷方式时回显信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryCustomMenuMationEditById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Map user = inputObject.getLogParams(); + map.put("userId", user.get("id")); + Map bean = sysEveWinDragDropDao.queryCustomMenuMationEditById(map); + outputObject.setBean(bean); + } + + /** + * 编辑快捷方式 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editCustomMenuMationById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + sysEveWinDragDropDao.editCustomMenuMationById(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + } + + /** + * 系统菜单发送到桌面快捷方式 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void editCustomMenuToDeskTopById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + map.put("userId", userId); + Map bean = sysEveWinDragDropDao.queryCustomMenuToDeskTopById(map); + if (bean != null && !bean.isEmpty()) { + sysEveWinDragDropDao.editCustomMenuToDeskTopById(map); + Map item = sysEveWinDragDropDao.queryMenuToDeskTopById(map); + // 桌面菜单列表 + List> deskTops = sysEveUserDao.queryDeskTopsMenuByUserId(userId); + deskTops = ToolUtil.listToTree(deskTops, "id", "parentId", "childs"); + jedisClient.set(ObjectConstant.getDeskTopsCacheKey(userId), JSONUtil.toJsonStr(deskTops)); + outputObject.setBean(item); + } else { + outputObject.setreturnMessage("该菜单在桌面上已存在。"); + } + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinLockBgPicServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinLockBgPicServiceImpl.java new file mode 100644 index 0000000..ad947bf --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinLockBgPicServiceImpl.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.win.dao.SysEveWinLockBgPicDao; +import com.skyeye.win.entity.SysEveWinLockBgPic; +import com.skyeye.win.enums.PicTypeEnum; +import com.skyeye.win.service.SysEveWinLockBgPicService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: SysEveWinLockBgPicServiceImpl + * @Description: win系统桌面锁屏图片服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/20 21:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "win系统桌面锁屏图片", groupName = "win系统桌面锁屏图片") +public class SysEveWinLockBgPicServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveWinLockBgPicService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Autowired + private RedisCache redisCache; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinLockBgPic::getPicType), PicTypeEnum.SYSTEM_PUBLISH.getKey()); + return queryWrapper; + } + + @Override + public void createPostpose(SysEveWinLockBgPic entity, String userId) { + jedisClientService.del(Constants.SYS_WIN_LOCK_BG_PIC_REDIS_KEY); + } + + @Override + public void deletePostpose(SysEveWinLockBgPic entity) { + String basePath = tPath + entity.getPicUrl().replace("/images/", ""); + FileUtil.deleteFile(basePath); + jedisClientService.del(Constants.SYS_WIN_LOCK_BG_PIC_REDIS_KEY); + } + + /** + * 获取用户自定义的win系统桌面锁屏图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysEveWinLockBgPicCustomList(InputObject inputObject, OutputObject outputObject) { + String userId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinLockBgPic::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinLockBgPic::getPicType), PicTypeEnum.USER_UPLOAD.getKey()); + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + @Override + public List querySystemSysEveWinLockBgPicList() { + return redisCache.getList(Constants.SYS_WIN_LOCK_BG_PIC_REDIS_KEY, key -> { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SysEveWinLockBgPic::getPicType), PicTypeEnum.SYSTEM_PUBLISH.getKey()); + List list = list(queryWrapper); + return list; + }, RedisConstants.THIRTY_DAY_SECONDS, SysEveWinLockBgPic.class); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinServiceImpl.java new file mode 100644 index 0000000..47a19da --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinServiceImpl.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.win.dao.SysEveWinDao; +import com.skyeye.win.entity.SysWin; +import com.skyeye.win.service.SysEveWinService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveWinServiceImpl + * @Description: 服务信息管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "前台服务管理", groupName = "基础模块") +public class SysEveWinServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveWinService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryWinMationList(commonPageInfo); + return beans; + } + + @Override + protected void deletePreExecution(String id) { + Map bean = skyeyeBaseMapper.queryChildMationById(id); + if (Integer.parseInt(bean.get("menuNum").toString()) > 0) { + throw new CustomException("该服务存在功能菜单,请先进行菜单移除操作。"); + } + } + + /** + * 获取所有的服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySysEveWinList(InputObject inputObject, OutputObject outputObject) { + List> beans = skyeyeBaseMapper.querySysEveWinList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + +} diff --git a/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinThemeColorServiceImpl.java b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinThemeColorServiceImpl.java new file mode 100644 index 0000000..8239f51 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/java/com/skyeye/win/service/impl/SysEveWinThemeColorServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.win.service.impl; + +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.cache.redis.RedisCache; +import com.skyeye.common.constans.Constants; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.win.dao.SysEveWinThemeColorDao; +import com.skyeye.win.entity.SysEveWinThemeColor; +import com.skyeye.win.service.SysEveWinThemeColorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: SysEveWinThemeColorServiceImpl + * @Description: win系统主题颜色服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/8/22 12:48 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "win系统主题颜色", groupName = "win系统主题颜色") +public class SysEveWinThemeColorServiceImpl extends SkyeyeBusinessServiceImpl implements SysEveWinThemeColorService { + + @Autowired + private RedisCache redisCache; + + @Override + public void writePostpose(SysEveWinThemeColor entity, String userId) { + jedisClientService.del(Constants.SYS_WIN_THEME_COLOR_REDIS_KEY); + } + + @Override + public void deletePostpose(SysEveWinThemeColor entity) { + jedisClientService.del(Constants.SYS_WIN_THEME_COLOR_REDIS_KEY); + } + + @Override + public List querySysEveWinThemeColorList() { + return redisCache.getList(Constants.SYS_WIN_THEME_COLOR_REDIS_KEY, key -> { + return list(); + }, RedisConstants.THIRTY_DAY_SECONDS, SysEveWinThemeColor.class); + } +} diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/authority/AuthorityMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/authority/AuthorityMapper.xml new file mode 100644 index 0000000..5619135 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/authority/AuthorityMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/editor/UploadUEditor.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/editor/UploadUEditor.xml new file mode 100644 index 0000000..f9ce7e4 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/editor/UploadUEditor.xml @@ -0,0 +1,21 @@ + + + + + + insert into ueditor_img + (ID, imgPath, fileOriginalName, createId, createTime, createType) + values(#{id}, #{imgPath}, #{fileOriginalName}, #{createId}, #{createTime}, #{createType}) + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AppWorkPageMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AppWorkPageMapper.xml new file mode 100644 index 0000000..9ef324b --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AppWorkPageMapper.xml @@ -0,0 +1,85 @@ + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AuthPointMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AuthPointMapper.xml new file mode 100644 index 0000000..55dc2a9 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/AuthPointMapper.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/SysEveMenuMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/SysEveMenuMapper.xml new file mode 100644 index 0000000..cc2432e --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/menupc/SysEveMenuMapper.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserMapper.xml new file mode 100644 index 0000000..99bf265 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserMapper.xml @@ -0,0 +1,437 @@ + + + + + + + + + + + + UPDATE sys_eve_user + + role_id = #{roleIds} + + WHERE id = #{id} + + + + + + + + UPDATE sys_eve_user_staff + + user_idcard = #{userIdCard}, + user_sex = #{userSex}, + + user_photo = #{userPhoto}, + + email = #{userEmail}, + phone = #{userPhone}, + home_phone = #{userHomePhone}, + qq = #{userQq}, + user_sign = #{userSign}, + + WHERE user_id = #{userId} + + + + + + + + + + + + + + + + + + + + UPDATE wx_user_mation + + + user_id = #{userId}, + + + binding_time = #{bindTime}, + + + WHERE open_id = #{openId} + + + + INSERT into wx_user_mation + (id, open_id, join_time) + VALUES + (#{id}, #{openId}, #{joinTime}) + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserStaffMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserStaffMapper.xml new file mode 100644 index 0000000..fc8f3fe --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/personnel/SysEveUserStaffMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + INSERT INTO sys_eve_user_staff_time + (staff_id, check_work_time_id) + VALUES + + (#{item.staffId}, #{item.timeId}) + + + + + DELETE + FROM + sys_eve_user_staff_time + WHERE staff_id = #{staffId} + + + + + + + + + + + + UPDATE sys_eve_user_staff + + annual_leave = #{quarterYearHour}, + annual_leave_statis_time = #{annualLeaveStatisTime} + + WHERE id = #{staffId} + + + + UPDATE sys_eve_user_staff + + holiday_number = #{holidayNumber}, + holiday_statis_time = #{holidayStatisTime} + + WHERE id = #{staffId} + + + + UPDATE sys_eve_user_staff + + retired_holiday_number = #{retiredHolidayNumber}, + retired_holiday_statis_time = #{retiredHolidayStatisTime} + + WHERE id = #{staffId} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/role/SysEveRoleMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/role/SysEveRoleMapper.xml new file mode 100644 index 0000000..3bb585a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/role/SysEveRoleMapper.xml @@ -0,0 +1,88 @@ + + + + + + insert into sys_eve_role_menu + (id, role_id, menu_id, creater, create_time) + values + + (#{item.id}, #{item.roleId}, #{item.menuId}, #{item.createId}, #{item.createTime}) + + + + + DELETE + FROM + sys_eve_role_menu + WHERE + role_id = #{roleId} + + + + + + + + + + insert into app_workbench_page_role + (id, role_id, page_id) + values + + (#{item.id}, #{item.roleId}, #{item.menuId}) + + + + + DELETE + FROM + app_workbench_page_role + WHERE + role_id = #{id} + + + + insert into app_workbench_page_auth_role + (id, role_id, auth_id) + values + + (#{item.id}, #{item.roleId}, #{item.pointId}) + + + + + DELETE + FROM + app_workbench_page_auth_role + WHERE role_id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CommonMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CommonMapper.xml new file mode 100644 index 0000000..1b7cf03 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CommonMapper.xml @@ -0,0 +1,16 @@ + + + + + + insert into code_model_history + (id, table_name, group_id, model_id, content, file_path, file_name, file_type, + create_id, create_time) + values + + (#{item.id}, #{item.tableName}, #{item.groupId}, #{item.modelId}, #{item.content}, #{item.filePath}, #{item.fileName}, #{item.fileType}, + #{item.createId}, #{item.createTime}) + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyChatMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyChatMapper.xml new file mode 100644 index 0000000..949c8e8 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyChatMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + UPDATE sys_eve_user_staff + + user_sign = #{userSign}, + + WHERE user_id = #{userId} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyTalkGroupMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyTalkGroupMapper.xml new file mode 100644 index 0000000..3228b4f --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/CompanyTalkGroupMapper.xml @@ -0,0 +1,257 @@ + + + + + + INSERT into sys_talk_group + (id, group_name, group_num, group_img, group_histroy_img, group_user_num, group_desc, state, create_id, create_time) + VALUES + (#{id}, #{groupName}, #{groupNum}, #{groupImg}, #{groupHistroyImg}, #{groupUserNum}, #{groupDesc}, #{state}, #{createId}, #{createTime}) + + + + insert into sys_talk_group_invite_mation + (id, invite_user_id, group_id, state, in_group_type, whether_read, create_id, create_time) + values + + (#{item.id}, #{item.inviteUserId}, #{item.groupId}, #{item.state}, #{item.inGroupType}, '0', #{item.createId}, #{item.createTime}) + + + + + INSERT into sys_talk_group_user + (id, user_id, group_id, create_time) + VALUES + (#{id}, #{userId}, #{groupId}, #{createTime}) + + + + + + + + UPDATE sys_talk_group_invite_mation + + `state` = '1', + operator = #{userId}, + whether_read = '1' + + WHERE id = #{id} + + + + UPDATE sys_talk_group_invite_mation + + `state` = '2', + operator = #{userId}, + whether_read = '1' + + WHERE id = #{id} + + + + + + + + + + + + + + insert into sys_talk_group_invite_mation + (id, invite_user_id, group_id, state, in_group_type, whether_read, create_id, create_time) + values + (#{id}, #{inviteUserId}, #{groupId}, #{state}, #{inGroupType}, '0', #{createId}, #{createTime}) + + + + + + + + INSERT into sys_talk_chat_history + (id, send_id, receive_id, content, chat_type, create_time) + VALUES + (#{dataId}, #{fromId}, #{toId}, #{textMessage}, '1', #{createTime}) + + + + INSERT into sys_talk_chat_history + (id, send_id, receive_id, content, chat_type, create_time) + VALUES + (#{dataId}, #{userId}, #{id}, #{textMessage}, '2', #{createTime}) + + + + + + + + + + DELETE + FROM + sys_talk_group_user + WHERE + user_id = #{userId} + AND group_id = #{groupId} + + + + UPDATE sys_talk_group + + `state` = '3', + + WHERE id = #{groupId} + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/ExExplainDao.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/ExExplainDao.xml new file mode 100644 index 0000000..36a5d98 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/ExExplainDao.xml @@ -0,0 +1,37 @@ + + + + + + + + INSERT into ex_explain + (id, title, content, type, create_id, create_time) + VALUES + (#{id}, #{title}, #{content}, #{type}, #{createId}, #{createTime}) + + + + UPDATE ex_explain + + + title = #{title}, + + + content = #{content}, + + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/StickyNotesMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/StickyNotesMapper.xml new file mode 100644 index 0000000..44857fe --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/StickyNotesMapper.xml @@ -0,0 +1,38 @@ + + + + + + insert into sticky_notes + (id, content, create_id, create_time) + values + (#{id}, #{content}, #{createId}, #{createTime}) + + + + DELETE + FROM + sticky_notes + WHERE + id = #{id} + + + + + + UPDATE sticky_notes + + content = #{content} + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataBaseMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataBaseMapper.xml new file mode 100644 index 0000000..efb7ae8 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataBaseMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataSqlMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataSqlMapper.xml new file mode 100644 index 0000000..512e7b7 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysDataSqlMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + INSERT into sys_data_sql_backups + (id, sql_title, sql_version, sql_path, file_size, mysql_version, create_id, create_time) + VALUES + (#{id}, #{sqlTitle}, #{sqlVersion}, #{filePath}, #{fileSize}, #{mysqlVersion}, #{createId}, #{createTime}) + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysEveUserStaffCapitalMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysEveUserStaffCapitalMapper.xml new file mode 100644 index 0000000..9793ead --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysEveUserStaffCapitalMapper.xml @@ -0,0 +1,45 @@ + + + + + + + INSERT into sys_eve_user_staff_capital + (id, staff_id, company_id, department_id, month_time, money, type, state, create_time) + VALUES + (#{id}, #{staffId}, #{companyId}, #{departmentId}, #{monthTime}, #{money}, #{type}, #{state}, #{createTime}) + + + + UPDATE sys_eve_user_staff_capital + + money = #{money} + + WHERE id = #{id} + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysTAreaMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysTAreaMapper.xml new file mode 100644 index 0000000..8955b80 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/SysTAreaMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/WagesFieldTypeMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/WagesFieldTypeMapper.xml new file mode 100644 index 0000000..0db4a2c --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/userauth/WagesFieldTypeMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + INSERT into wages_field_staff_mation + (staff_id, field_type_key) + VALUES + + (#{item.id}, #{item.key}) + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveDesktopMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveDesktopMapper.xml new file mode 100644 index 0000000..5a1152a --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveDesktopMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinDragDropMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinDragDropMapper.xml new file mode 100644 index 0000000..317d3ea --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinDragDropMapper.xml @@ -0,0 +1,326 @@ + + + + + + + + + + INSERT into sys_eve_user_custom_menubox + (id, menu_box_name, order_num, desktop_id, create_id, create_time) + VALUES + (#{id}, #{menuBoxName}, #{order}, #{deskTopId}, #{createId}, #{createTime}) + + + + + + INSERT into sys_eve_user_custom_menu + (id, menu_name, menu_name_en, menu_url, menu_icon_type, menu_icon_pic, menu_icon, menu_icon_color, menu_icon_bg, menu_type, menu_parent_id, open_type, + light_app_id, desktop_id, create_id, create_time) + VALUES + (#{id}, #{menuName}, #{menuNameEn}, #{menuUrl}, #{menuIconType}, #{menuIconPic}, #{menuIcon}, #{menuIconColor}, #{menuIconBg}, #{menuType}, #{menuParentId}, #{openType}, + #{lightAppId}, #{deskTopId}, #{createId}, #{createTime}) + + + + + + DELETE + FROM + sys_eve_user_custom_menu + WHERE + id = #{id} + + + + DELETE + FROM + sys_eve_user_custom_menubox + WHERE + id = #{id} + + + + + + DELETE + FROM + sys_eve_user_custom_menu + WHERE + INSTR(CONCAT(',', #{ids}, ','), CONCAT(',', id, ',')) + + + + DELETE + FROM + sys_eve_user_custom_parent + WHERE + INSTR(CONCAT(',', #{ids}, ','), CONCAT(',', menu_id, ',')) + + + + insert into sys_eve_user_custom_menu_del + (id, menu_id, create_id, create_time) + values + + (#{item.rowId}, #{item.id}, #{item.createId}, #{item.createTime}) + + + + + INSERT into sys_eve_user_custom_menu_del + (id, menu_id, create_id, create_time) + VALUES + (#{id}, #{menuId}, #{createId}, #{createTime}) + + + + DELETE + FROM + sys_eve_user_custom_parent + WHERE + menu_id = #{menuId} + AND create_id = #{userId} + + + + INSERT into sys_eve_user_custom_parent + (id, menu_id, menu_level, parent_id, create_id, create_time) + VALUES + (#{id}, #{menuId}, #{menuLevel}, #{parentId}, #{userId}, #{createTime}) + + + + + + + + UPDATE sys_eve_user_custom_menubox + + menu_box_name = #{menuBoxName}, + + WHERE id = #{id} + AND create_id = #{userId} + + + + + + UPDATE sys_eve_user_custom_menu + + + menu_name = #{menuName}, + + + menu_name_en = #{menuNameEn}, + + menu_icon = #{menuIcon}, + menu_icon_pic = #{menuIconPic}, + + menu_icon_type = #{menuIconType}, + + + menu_url = #{menuUrl}, + + menu_icon_color = #{menuIconColor}, + menu_icon_bg = #{menuIconBg}, + + WHERE id = #{id} + AND create_id = #{userId} + + + + + + DELETE + FROM + sys_eve_user_custom_menu_del + WHERE + menu_id = #{id} + AND create_id = #{userId} + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinMapper.xml b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinMapper.xml new file mode 100644 index 0000000..8545b9d --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/mapper/win/SysEveWinMapper.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-userauth/src/main/resources/reqmapping/mapping/userauth.xml b/skyeye-promote/skyeye-userauth/src/main/resources/reqmapping/mapping/userauth.xml new file mode 100644 index 0000000..879dae4 --- /dev/null +++ b/skyeye-promote/skyeye-userauth/src/main/resources/reqmapping/mapping/userauth.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-promote/skyeye-web/.gitignore b/skyeye-promote/skyeye-web/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-promote/skyeye-web/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-promote/skyeye-web/.project b/skyeye-promote/skyeye-web/.project new file mode 100644 index 0000000..47dc261 --- /dev/null +++ b/skyeye-promote/skyeye-web/.project @@ -0,0 +1,23 @@ + + + skyeye-web + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/skyeye-promote/skyeye-web/pom.xml b/skyeye-promote/skyeye-web/pom.xml new file mode 100644 index 0000000..ace271d --- /dev/null +++ b/skyeye-promote/skyeye-web/pom.xml @@ -0,0 +1,124 @@ + + + 4.0.0 + + skyeye-promote + com.skyeye + 0.0.1-SNAPSHOT + + + skyeye-web + + skyeye-web + http://www.example.com + + + + + + com.skyeye + skyeye-base-server + 0.0.1-SNAPSHOT + + + + + com.skyeye + skyeye-api + 0.0.1-SNAPSHOT + + + + + com.skyeye + skyeye-organization + 0.0.1-SNAPSHOT + + + + + com.skyeye + skyeye-gateway + 0.0.1-SNAPSHOT + + + + + com.skyeye + skyeye-threed + 0.0.1-SNAPSHOT + + + + + com.skyeye + skyeye-code-doc + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + diff --git a/skyeye-promote/skyeye-web/src/main/java/com/SkyEyeApplication.java b/skyeye-promote/skyeye-web/src/main/java/com/SkyEyeApplication.java new file mode 100644 index 0000000..466cdf9 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/java/com/SkyEyeApplication.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.util.unit.DataSize; + +import javax.servlet.MultipartConfigElement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableScheduling +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class SkyEyeApplication { + + @Value("${IMAGES_PATH}") + private String tPath; + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyEyeApplication.class, args); + } + + /** + * 文件上传配置 + * + * @return + */ + @Bean + public MultipartConfigElement multipartConfigElement() { + MultipartConfigFactory factory = new MultipartConfigFactory(); + factory.setLocation(tPath); + // 单个文件最大,KB,MB 100MB + factory.setMaxFileSize(DataSize.ofMegabytes(100)); + // 设置总上传数据总大小,1000MB + factory.setMaxRequestSize(DataSize.ofMegabytes(1000)); + return factory.createMultipartConfig(); + } + + /** + * 解决同一时间启动的多个个定时任务(都设置了5秒运行一次)只会运行一个的问题 + * + * @return + */ + @Bean + public TaskScheduler taskScheduler() { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setPoolSize(50); + return taskScheduler; + } + +} diff --git a/skyeye-promote/skyeye-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-promote/skyeye-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..da5d6d0 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.github.yulichang.injector.MPJSqlInjector; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.*.dao", + "com.skyeye.eve.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + GlobalConfig globalConfig = new GlobalConfig(); + globalConfig.setSqlInjector(new MPJSqlInjector()); + mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-promote/skyeye-web/src/main/java/com/skyeye/sys/quartz/AnnualLeaveStatisticsQuartz.java b/skyeye-promote/skyeye-web/src/main/java/com/skyeye/sys/quartz/AnnualLeaveStatisticsQuartz.java new file mode 100644 index 0000000..c6aacc3 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/java/com/skyeye/sys/quartz/AnnualLeaveStatisticsQuartz.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.sys.quartz; + +import cn.hutool.json.JSONUtil; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.personnel.dao.SysEveUserStaffDao; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: AnnualLeaveStatisticsQuartz + * @Description: 定时计算员工年假 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 19:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Component +public class AnnualLeaveStatisticsQuartz { + + private static Logger LOGGER = LoggerFactory.getLogger(AnnualLeaveStatisticsQuartz.class); + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Autowired + private SysEveUserStaffDao sysEveUserStaffDao; + + @Getter + @NoArgsConstructor + @AllArgsConstructor + private enum YearLimits { + ONE_YEAR(0, 1, "1", "1年以下"), + ONE_THREE_YEAR(1, 3, "2", "1年 ~ 3年"), + THREE_FIVE_YEAR(3, 5, "3", "3年 ~ 5年"), + FIVE_EIGHT_YEAR(5, 8, "4", "5年 ~ 8年"), + EIGHT_YEAR(8, 100, "5", "8年以上"); + + private int min; + private int max; + private String yearType; + private String title; + } + + /** + * 每个季度的第一天零点开始执行员工年假计算任务 + */ + @XxlJob("annualLeaveStatisticsQuartz") + public void annualLeaveStatistics() { + LOGGER.info("annualLeaveStatistics start."); + try { + // 1.获取年假信息 + List> yearHolidaysMation = getSystemYearHolidaysMation(); + // 2.获取所有在职状态的员工列表, 见习,试用,退休,离职员工不计入计算 + List> userStaff = sysEveUserStaffDao.queryAllSysUserStaffListByState(Arrays.asList(new Integer[]{1})); + // 获取当前年月日 + String nowDate = DateUtil.getYmdTimeAndToString(); + for (Map staff : userStaff) { + String staffId = staff.get("id").toString(); + // 员工当前剩余年假 + String annualLeave = staff.get("annualLeave").toString(); + // 开始工作时间 + String workTime = staff.get("workTime").toString(); + // 获取到相差的天数 + int differDays = DateUtil.getDistanceDay(workTime, nowDate); + String differYear = getDifferYear(differDays); + Map yearMation = getConcertWithYearMation(Integer.parseInt(differYear), yearHolidaysMation); + if (!ObjectUtils.isEmpty(yearMation)) { + String yearHour = yearMation.get("yearHour").toString(); + // 获取每个季度应该相加的年假小时 + String quarterYearHour = CalculationUtil.divide(yearHour, "4", 2); + annualLeave = CalculationUtil.add(annualLeave, quarterYearHour, 2); + LOGGER.info("annualLeaveStatistics calc staffId is: {} quarterYearHour is: {}", staffId, annualLeave); + // 更新员工年假信息 + sysEveUserStaffDao.editSysUserStaffAnnualLeaveById(staffId, annualLeave, DateUtil.getTimeAndToString()); + } + } + } catch (Exception e) { + LOGGER.warn("AnnualLeaveStatisticsQuartz error.", e); + } + LOGGER.info("annualLeaveStatistics end."); + } + + /** + * 筛选已工作年份应该获取的年假信息 + * + * @param differYear 已工作年份 + * @param yearHolidaysMation 年假信息 + * @return + */ + private Map getConcertWithYearMation(int differYear, List> yearHolidaysMation) { + for (YearLimits q : YearLimits.values()) { + if (q.getMin() <= differYear && differYear < q.getMax()) { + List> fillterMation = yearHolidaysMation.stream() + .filter(bean -> bean.get("yearType").toString().equals(q.getYearType())) + .collect(Collectors.toList()); + if (fillterMation == null || fillterMation.isEmpty()) { + return null; + } + return fillterMation.get(0); + } + } + return null; + } + + /** + * 计算多少年,小数点后面的全部舍去 + * + * @param differDays 相差的天数 + * @return + */ + private String getDifferYear(int differDays) { + String year = CalculationUtil.divide(String.valueOf(differDays), "365", 2); + if (ToolUtil.isBlank(year)) { + return "0"; + } + return year.split("\\.")[0]; + } + + /** + * 获取年假信息 + * + * @return + */ + private List> getSystemYearHolidaysMation() { + Map sysSetting = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + String yearHolidaysMationStr = sysSetting.get("yearHolidaysMation").toString(); + return JSONUtil.toList(yearHolidaysMationStr, null); + } + +} diff --git a/skyeye-promote/skyeye-web/src/main/resources/banner.txt b/skyeye-promote/skyeye-web/src/main/resources/banner.txt new file mode 100644 index 0000000..20c3eb7 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev skyeye-web.jar >> /opt/service/project/nohup-pro.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-promote/skyeye-web/src/main/resources/bootstrap.yaml b/skyeye-promote/skyeye-web/src/main/resources/bootstrap.yaml new file mode 100644 index 0000000..b7a9c03 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/resources/bootstrap.yaml @@ -0,0 +1,62 @@ +server: + port: 8081 + +spring: + application: + name: skyeye-pro-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.19.212.203:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.19.212.203:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false + +# 配置打印sql到控制台 +logging: + level: + com.skyeye: debug + +webroot: + # 工作流相关的服务 + skyeye-flowable: skyeye-flowable-${spring.profiles.active} + # 报表 + skyeye-report: skyeye-report-${spring.profiles.active} + # xxl-job + xxl-job: xxl-job-${spring.profiles.active} + +topic: + # 邮件通知的topic + ordinary-mail-delivery-service: ORDINARY_MAIL_DELIVERY_SERVICE + # 消息通知的topic + notice-send-service: NOTICE_SEND_SERVICE + # 短信通知的topic + sms-send-service: SMS_SEND_SERVICE + +skyeye: + sms-code: # 短信验证码相关的配置项 + expire-times: 10m + send-frequency: 1m + send-maximum-quantity-per-day: 10 + begin-code: 1 # 这里配置 9999 的原因是,测试方便。 + end-code: 9999 # 这里配置 9999 的原因是,测试方便。 \ No newline at end of file diff --git a/skyeye-promote/skyeye-web/src/main/resources/jvm调优参数配置 b/skyeye-promote/skyeye-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-promote/skyeye-web/src/main/resources/log4j.properties b/skyeye-promote/skyeye-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..c6470a3 --- /dev/null +++ b/skyeye-promote/skyeye-web/src/main/resources/log4j.properties @@ -0,0 +1,55 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info + + diff --git a/skyeye-report/.gitignore b/skyeye-report/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-report/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-report/pom.xml b/skyeye-report/pom.xml new file mode 100644 index 0000000..e960e9a --- /dev/null +++ b/skyeye-report/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-report + 1.0-SNAPSHOT + pom + + report-web + report-common + report-pro + report-entity + + + \ No newline at end of file diff --git a/skyeye-report/report-common/.gitignore b/skyeye-report/report-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-report/report-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-report/report-common/pom.xml b/skyeye-report/report-common/pom.xml new file mode 100644 index 0000000..72e5fdb --- /dev/null +++ b/skyeye-report/report-common/pom.xml @@ -0,0 +1,36 @@ + + + + skyeye-report + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + report-common + + + 8 + 8 + + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + com.jayway.jsonpath + json-path + 2.8.0 + + + + + \ No newline at end of file diff --git a/skyeye-report/report-common/src/main/java/com/skyeye/common/constans/ReportConstants.java b/skyeye-report/report-common/src/main/java/com/skyeye/common/constans/ReportConstants.java new file mode 100644 index 0000000..a27c4f3 --- /dev/null +++ b/skyeye-report/report-common/src/main/java/com/skyeye/common/constans/ReportConstants.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.common.constans; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportConstants + * @Description: 报表常量类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class ReportConstants { + + /** + * 数据源类型 + */ + public enum DataBaseMation { + MYSQL("MySQL", "com.mysql.jdbc.Driver", "com.skyeye.sql.query.impl.MySqlQueryer"), + SQLSERVER("SQLServer", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "com.skyeye.sql.query.impl.SqlServerQueryer"), + ORACLE("Oracle", "oracle.jdbc.driver.OracleDriver", "com.skyeye.sql.query.impl.OracleQueryer"); + + private String type; + private String driverClass; + private String queryerClass; + + DataBaseMation(String type, String driverClass, String queryerClass) { + this.type = type; + this.driverClass = driverClass; + this.queryerClass = queryerClass; + } + + public static List> getDataBaseMationList() { + List> beans = new ArrayList<>(); + for (DataBaseMation item : DataBaseMation.values()) { + Map bean = new HashMap<>(); + bean.put("id", item.getType()); + bean.put("name", item.getType()); + bean.put("driverClass", item.getDriverClass()); + beans.add(bean); + } + return beans; + } + + public static String getDricerClassByType(String type) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getType().equals(type)) { + return bean.getDriverClass(); + } + } + return null; + } + + public static String getTypeByDricerClass(String driverClass) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getDriverClass().equals(driverClass)) { + return bean.getType(); + } + } + return null; + } + + public static String getQueryerClassByType(String type) { + for (DataBaseMation bean : DataBaseMation.values()) { + if (bean.getType().equals(type)) { + return bean.getQueryerClass(); + } + } + return null; + } + + public String getType() { + return type; + } + + public String getDriverClass() { + return driverClass; + } + + public String getQueryerClass() { + return queryerClass; + } + } + + /** + * 连接池类型 + */ + public enum PoolMation { + C3P0("C3P0", "c3p0", "com.skyeye.sql.dbpool.impl.C3p0DataSourcePool", "{\"initialPoolSize\":3,\"minPoolSize\":1,\"maxPoolSize\":10,\"maxStatements\":50,\"maxIdleTime\":1000,\"acquireIncrement\":3,\"acquireRetryAttempts\":30,\"idleConnectionTestPeriod\":60,\"breakAfterAcquireFailure\":false,\"testConnectionOnCheckout\":false}"), + DBCP2("DBCP2", "dbcp2", "com.skyeye.sql.dbpool.impl.DBCP2DataSourcePool", "{\"initialSize\":3,\"maxIdle\":20,\"minIdle\":1,\"logAbandoned\":true,\"removeAbandoned\":true,\"removeAbandonedTimeout\":180,\"maxWait\":1000}"), + DRUID("DRUID", "druid", "com.skyeye.sql.dbpool.impl.DruidDataSourcePool", "{\"initialSize\":3,\"maxActive\":20,\"minIdle\":1,\"maxWait\":60000,\"timeBetweenEvictionRunsMillis\":60000,\"minEvictableIdleTimeMillis\":300000,\"testWhileIdle\":true,\"testOnBorrow\":false,\"testOnReturn\":false,\"maxOpenPreparedStatements\":20,\"removeAbandoned\":true,\"removeAbandonedTimeout\":1800,\"logAbandoned\":true}"), + NODBPOOL("无连接池", "noDbPool", "com.skyeye.sql.dbpool.impl.NoDataSourcePool", "{}"); + + private String title; + private String type; + private String poolClass; + private String options; + + PoolMation(String title, String type, String poolClass, String options) { + this.title = title; + this.type = type; + this.poolClass = poolClass; + this.options = options; + } + + public static List> getPoolMationList() { + List> beans = new ArrayList<>(); + for (PoolMation item : PoolMation.values()) { + Map bean = new HashMap<>(); + bean.put("id", item.getType()); + bean.put("name", item.getTitle()); + bean.put("options", item.getOptions()); + beans.add(bean); + } + return beans; + } + + public static String getPoolClassByType(String type) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getType().equals(type)) { + return bean.getPoolClass(); + } + } + return null; + } + + public static String getTitleByPoolClass(String poolClass) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getPoolClass().equals(poolClass)) { + return bean.getTitle(); + } + } + return null; + } + + public static String getTypeByPoolClass(String poolClass) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getPoolClass().equals(poolClass)) { + return bean.getType(); + } + } + return null; + } + + public static String getOptionsByType(String type) { + for (PoolMation bean : PoolMation.values()) { + if (bean.getType().equals(type)) { + return bean.getOptions(); + } + } + return null; + } + + public String getType() { + return type; + } + + public String getPoolClass() { + return poolClass; + } + + public String getOptions() { + return options; + } + + public String getTitle() { + return title; + } + } + +} diff --git a/skyeye-report/report-common/src/main/java/com/skyeye/eve/centerrest/base/SystemFoundationSettingsService.java b/skyeye-report/report-common/src/main/java/com/skyeye/eve/centerrest/base/SystemFoundationSettingsService.java new file mode 100644 index 0000000..27ebba8 --- /dev/null +++ b/skyeye-report/report-common/src/main/java/com/skyeye/eve/centerrest/base/SystemFoundationSettingsService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.base; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * @ClassName: SystemFoundationSettingsService + * @Description: 系统基础设置 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 18:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface SystemFoundationSettingsService { + + /** + * 获取系统基础设置 + * + * @return 用户信息 + */ + @GetMapping("/sysfdsettings001") + String querySystemFoundationSettingsList(); + +} diff --git a/skyeye-report/report-entity/.gitignore b/skyeye-report/report-entity/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-report/report-entity/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-report/report-entity/pom.xml b/skyeye-report/report-entity/pom.xml new file mode 100644 index 0000000..b9da5cc --- /dev/null +++ b/skyeye-report/report-entity/pom.xml @@ -0,0 +1,28 @@ + + + + skyeye-report + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + report-entity + + + 8 + 8 + + + + + + com.skyeye + report-common + 1.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/centerrest/common/CommonService.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/centerrest/common/CommonService.java new file mode 100644 index 0000000..d8dd134 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/centerrest/common/CommonService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.centerrest.common; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: CommonService + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2022/6/6 12:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface CommonService { + + /** + * 根据文件类型获取文件的保存地址以及访问地址 + * + * @param fileType 文件类型 + * @return + */ + @GetMapping("/queryFilePathByFileType") + String queryFilePathByFileType(@RequestParam("fileType") Integer fileType); + +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnSortType.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnSortType.java new file mode 100644 index 0000000..5526322 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnSortType.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +/** + * @ClassName: ColumnSortType + * @Description: 报表列排序类型 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public enum ColumnSortType { + + /** + * 默认 + */ + DEFAULT(0), + + /** + * 数字优先升序 + */ + DIGIT_ASCENDING(1), + + /** + * 数字优先降序 + */ + DIGIT_DESCENDING(2), + + /** + * 字符优先升序 + */ + CHAR_ASCENDING(3), + + /** + * 字符优先降序 + */ + CHAR_DESCENDING(4); + + private int value; + + ColumnSortType(int value) { + this.value = value; + } + + public static ColumnSortType valueOf(int arg) { + for (ColumnSortType item : ColumnSortType.values()) { + if (item.getValue() == arg) { + return item; + } + } + return DEFAULT; + } + + public int getValue() { + return this.value; + } +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnType.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnType.java new file mode 100644 index 0000000..7f9de88 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ColumnType.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +/** + * @ClassName: ColumnType + * @Description: 报表列类型 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public enum ColumnType { + /** + * 布局列 + */ + LAYOUT(1), + + /** + * 维度列 + */ + DIMENSION(2), + + /** + * 统计列 + */ + STATISTICAL(3), + + /** + * 计算列 + */ + COMPUTED(4); + + private final int value; + + ColumnType(final int value) { + this.value = value; + } + + public static ColumnType valueOf(final int arg) { + for (ColumnType item : ColumnType.values()) { + if (item.getValue() == arg) { + return item; + } + } + return DIMENSION; + } + + public int getValue() { + return this.value; + } +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/LayoutType.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/LayoutType.java new file mode 100644 index 0000000..830eb7c --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/LayoutType.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +/** + * @ClassName: LayoutType + * @Description: 报表布局类型 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public enum LayoutType { + /** + * 横向布局 + */ + HORIZONTAL(1), + + /** + * 纵向布局; + */ + VERTICAL(2); + + private final int value; + + LayoutType(final int value) { + this.value = value; + } + + public static LayoutType valueOf(final int arg) { + for (LayoutType item : LayoutType.values()) { + if (item.getValue() == arg) { + return item; + } + } + return HORIZONTAL; + } + + public int getValue() { + return this.value; + } +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportDataSource.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportDataSource.java new file mode 100644 index 0000000..db5ad0e --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportDataSource.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: ReportDataSource + * @Description: 报表数据库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportDataSource implements Serializable { + + /** + * 获取数据源唯一标识 + */ + private String uid; + + /** + * 获取报表引擎查询器类名(如:com.easytoolsoft.easyreport.engine.query.MySqlQueryer) + */ + private String queryerClass; + + /** + * 获取报表引擎查询器使用的数据源连接池类名(如:com.skyeye.sql.dbpool.impl.C3p0DataSourcePool) + */ + private String dbPoolClass; + + /** + * 获取数据源驱动类 + */ + private String driverClass; + + /** + * 获取数据源连接字符串(JDBC) + */ + private String jdbcUrl; + + /** + * 获取数据源登录用户名 + */ + private String user; + + /** + * 获取数据源登录密码 + */ + private String password; + + /** + * 获取数据源配置选项,如果没有配置选项则设置为默认选项 + */ + private Map options; + + public ReportDataSource(String uid, String driverClass, String jdbcUrl, String user, + String password, + String queryerClass, String dbPoolClass) { + this(uid, driverClass, jdbcUrl, user, password, queryerClass, dbPoolClass, new HashMap<>(3)); + } + + public ReportDataSource(String uid, String driverClass, String jdbcUrl, String user, + String password, + String queryerClass, String dbPoolClass, + Map options) { + this.uid = uid; + this.driverClass = driverClass; + this.jdbcUrl = jdbcUrl; + this.user = user; + this.password = password; + this.queryerClass = queryerClass; + this.dbPoolClass = dbPoolClass; + this.options = options; + } + +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataCell.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataCell.java new file mode 100644 index 0000000..77290d2 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataCell.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportMetaDataCell + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportMetaDataCell implements Serializable { + private ReportMetaDataColumn column; + private String name; + private Object value; + + public ReportMetaDataCell(ReportMetaDataColumn column, String name, Object value) { + this.column = column; + this.name = name; + this.value = value; + } + +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataColumn.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataColumn.java new file mode 100644 index 0000000..b9ca65a --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataColumn.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportMetaDataColumn + * @Description: 报表元数据列类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportMetaDataColumn implements Serializable { + + /** + * 获取报表元数据列的顺序(从1开始) + */ + private int ordinal; + + /** + * 获取报表元数据列名 + */ + private String name; + + /** + * 获取报表元数据列---数据类型名称 + */ + private String dataType; + + /** + * 获取报表元数据计算列的计算表达式 + */ + private String expression; + + /** + * 获取报表元数据列的格式 .String.format(format,text) + */ + private String format; + + /** + * 获取元数据列备注 + */ + private String comment; + + /** + * 获取报表元数据列宽(单位:像素) + */ + private int width; + + /** + * 获取报表元数据列的精度(即保留多少位小数,默认浮点数为4位,百分比为2位,其他为0) + */ + private int decimals; + + /** + * 获取报表元数据列类型-列类型(1:布局列, 2:维度列,3:统计列, 4:计算列) + */ + private ColumnType type = ColumnType.DIMENSION; + + /** + * 设置列排序类型(0:默认,1:数字优先升序,2:数字优先降序,3:字符优先升序,4:字符优先降序) + */ + private ColumnSortType sortType = ColumnSortType.DEFAULT; + + /** + * 获取元数据列是否支持小计 + */ + private boolean isExtensions; + + /** + * 获取元数据列是否支持条件查询 + */ + private boolean isFootings; + + /** + * 获取元数据列是否支持百分比显示 + */ + private boolean isPercent; + + /** + * 获取配置列是否支持可选择显示 + */ + private boolean isOptional; + + /** + * 获取配置列中的统计列(含计算)是否支持在邮件中显示 + */ + private boolean isDisplayInMail; + + /** + * 获取元数据列是否隐藏 + */ + private boolean isHidden; + + public ReportMetaDataColumn() { + } + + public ReportMetaDataColumn(String name, ColumnType type) { + this.name = name; + this.type = type; + } + + public String getExpression() { + return this.expression == null ? "" : this.expression; + } + + public String getFormat() { + return this.format == null ? "" : this.format; + } + + public String getComment() { + return this.comment == null ? "" : this.comment; + } + + public ReportMetaDataColumn copyToNew(String name) { + return this.copyToNew(name, this.isPercent); + } + + public ReportMetaDataColumn copyToNew(String name, boolean isPercent) { + ReportMetaDataColumn column = new ReportMetaDataColumn(); + column.setName(name); + column.setPercent(isPercent); + column.setDataType(this.dataType); + column.setExtensions(this.isExtensions); + column.setFootings(this.isFootings); + column.setHidden(this.isHidden); + column.setSortType(ColumnSortType.valueOf(this.sortType.getValue())); + column.setType(ColumnType.valueOf(this.type.getValue())); + column.setWidth(this.width); + column.setDecimals(this.decimals); + column.setOptional(this.isOptional); + column.setDisplayInMail(this.isDisplayInMail); + column.setComment(this.comment); + return column; + } +} \ No newline at end of file diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataRow.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataRow.java new file mode 100644 index 0000000..f5c665b --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportMetaDataRow.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportMetaDataRow + * @Description: 报表元数据行类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class ReportMetaDataRow { + private final Map cells = new HashMap<>(); + private final StringBuilder rowKeyBuilder = new StringBuilder(""); + + public ReportMetaDataRow() { + } + + public ReportMetaDataRow add(final ReportMetaDataCell cell) { + this.cells.put(cell.getName(), cell); + if (cell.getColumn().getType() != ColumnType.STATISTICAL) { + final Object cellValue = cell.getValue(); + this.rowKeyBuilder.append((cellValue == null) ? "" : cellValue.toString().trim()); + this.rowKeyBuilder.append("$"); + } + return this; + } + + public ReportMetaDataRow addAll(final List cells) { + cells.forEach(this::add); + return this; + } + + public Map getCells() { + return this.cells; + } + + public ReportMetaDataCell getCell(final String name) { + return this.cells.get(name); + } + + public Object getCellValue(final String name) { + final ReportMetaDataCell cell = this.cells.get(name); + return (cell == null) ? null : cell.getValue(); + } + + public String getRowKey() { + return this.rowKeyBuilder.toString(); + } +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportParameter.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportParameter.java new file mode 100644 index 0000000..4368979 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportParameter.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @ClassName: ReportParameter + * @Description: 报表参数类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportParameter implements Serializable { + + /** + * 获取报表唯一id + */ + private String id; + + /** + * 获取报表名称 + */ + private String name; + + /** + * 获取报表布局形式(1:横向;2:纵向) + */ + private LayoutType layout; + + /** + * 获取报表统计列或计算列布局形式 (1:横向;2:纵向) + */ + private LayoutType statColumnLayout; + + /** + * 获取报表SQL语句 + */ + private String sqlText; + + /** + * 获取报表元数据列集合 + */ + private List metaColumns; + + /** + * 获取报表中启用的统计(含计算)列名集合。如果未设置任何列名,则在报表中启用全部统计统计(含计算)列 + */ + private Set enabledStatColumns; + + /** + * 获取是否生成rowspan(跨行)的表格,默认为true + */ + private boolean isRowSpan = true; + + /** + * 报表参数构造函数 + * + * @param id 报表唯一id + * @param name 报表名称 + * @param layout 报表布局形式 (1:横向;2:纵向) + * @param statColumnLayout 报表统计列或计算列布局形式 (1:横向;2:纵向) + * @param metaColumns 报表元数据列集合 + * @param enabledStatColumns 报表中启用的统计(含计算)列名集合 + * @param isRowSpan 是否生成rowspan(跨行)的表格,默认为true + * @param sqlText 报表sql查询语句 + */ + public ReportParameter(String id, String name, int layout, int statColumnLayout, + List metaColumns, Set enabledStatColumns, + boolean isRowSpan, String sqlText) { + this.id = id; + this.name = name; + this.layout = LayoutType.valueOf(layout); + this.statColumnLayout = LayoutType.valueOf(statColumnLayout); + this.metaColumns = metaColumns; + this.enabledStatColumns = enabledStatColumns; + this.isRowSpan = isRowSpan; + this.sqlText = sqlText; + } + + /** + * 设置报表布局形式(1:横向;2:纵向) + * + * @param layout 报表布局形式(1:横向;2:纵向) + */ + public void setLayout(int layout) { + this.layout = LayoutType.valueOf(layout); + } + + /** + * 获取报表中启用的统计(含计算)列名集合。 + *

+ * 如果未设置任何列名,则在报表中启用全部统计统计(含计算)列 + * + * @return 报表中启用的统计(含计算)列名集合 + */ + public Set getEnabledStatColumns() { + return this.enabledStatColumns == null ? new HashSet<>(0) : this.enabledStatColumns; + } + +} diff --git a/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportQueryParamItem.java b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportQueryParamItem.java new file mode 100644 index 0000000..2389316 --- /dev/null +++ b/skyeye-report/report-entity/src/main/java/com/skyeye/eve/entity/ReportQueryParamItem.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.eve.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: ReportQueryParamItem + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Data +public class ReportQueryParamItem implements Serializable { + + private String name; + private String text; + private boolean selected; + + public ReportQueryParamItem(String name, String text) { + this.name = name; + this.text = text; + } + + public ReportQueryParamItem(String name, String text, boolean selected) { + this(name, text); + this.selected = selected; + } + +} diff --git a/skyeye-report/report-pro/.gitignore b/skyeye-report/report-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-report/report-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-report/report-pro/pom.xml b/skyeye-report/report-pro/pom.xml new file mode 100644 index 0000000..57913a0 --- /dev/null +++ b/skyeye-report/report-pro/pom.xml @@ -0,0 +1,69 @@ + + + + skyeye-report + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + report-pro + + + + 0.9.5.2 + 1.0.25 + + + + + + + com.skyeye + report-entity + 1.0-SNAPSHOT + + + + org.apache.commons + commons-dbcp2 + 2.1.1 + + + + + com.mchange + c3p0 + ${c3p0.version} + + + com.alibaba + druid + ${druid.version} + + + + + dom4j + dom4j + 1.6 + + + + + com.google.code.gson + gson + 2.2.4 + + + + org.json + json + 20210307 + + + + + \ No newline at end of file diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/controller/ReportBgImageController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/controller/ReportBgImageController.java new file mode 100644 index 0000000..95fccb7 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/controller/ReportBgImageController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bgimg.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.bgimg.entity.BgImage; +import com.skyeye.bgimg.service.ReportBgImageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportBgImageController + * @Description: 背景图片管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/3 8:33 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "背景图片管理", tags = "背景图片管理", modelName = "背景图片管理") +public class ReportBgImageController { + + @Autowired + private ReportBgImageService reportBgImageService; + + /** + * 获取背景图片列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportbgimage001", value = "获取背景图片列表信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportBgImageController/queryReportBgImageList") + public void queryReportBgImageList(InputObject inputObject, OutputObject outputObject) { + reportBgImageService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑背景图片 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBgImage", value = "新增/编辑背景图片", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = BgImage.class) + @RequestMapping("/post/ReportBgImageController/writeBgImage") + public void writeBgImage(InputObject inputObject, OutputObject outputObject) { + reportBgImageService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除背景图片信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBgImageById", value = "删除背景图片信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportBgImageController/deleteBgImageById") + public void deleteBgImageById(InputObject inputObject, OutputObject outputObject) { + reportBgImageService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启用的背景图片列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getEnabledBgImageList", value = "获取所有启用的背景图片列表", method = "GET", allUse = "2") + @RequestMapping("/post/ReportBgImageController/getEnabledBgImageList") + public void getEnabledBgImageList(InputObject inputObject, OutputObject outputObject) { + reportBgImageService.getEnabledBgImageList(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/dao/ReportBgImageDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/dao/ReportBgImageDao.java new file mode 100644 index 0000000..43295e2 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/dao/ReportBgImageDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bgimg.dao; + +import com.skyeye.bgimg.entity.BgImage; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportBgImageDao + * @Description: 背景图片管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/3 8:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportBgImageDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/entity/BgImage.java b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/entity/BgImage.java new file mode 100644 index 0000000..91d4813 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/entity/BgImage.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bgimg.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: BgImage + * @Description: 背景图片实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 13:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:bgImg") +@TableName(value = "report_bg_image", autoResultMap = true) +@ApiModel("背景图片实体类") +public class BgImage extends BaseGeneralInfo { + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("img_path") + @ApiModelProperty(value = "图片路径", required = "required") + private String imgPath; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @ApiModelProperty(value = "所属分类名称,数据来自数据字典") + private String typeName; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/ReportBgImageService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/ReportBgImageService.java new file mode 100644 index 0000000..8a20ee2 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/ReportBgImageService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bgimg.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.bgimg.entity.BgImage; + +/** + * @ClassName: ReportBgImageService + * @Description: 背景图片管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/3 8:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportBgImageService extends SkyeyeBusinessService { + + void getEnabledBgImageList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/impl/ReportBgImageServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/impl/ReportBgImageServiceImpl.java new file mode 100644 index 0000000..16fa9e3 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/bgimg/service/impl/ReportBgImageServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.bgimg.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.bgimg.dao.ReportBgImageDao; +import com.skyeye.bgimg.entity.BgImage; +import com.skyeye.bgimg.service.ReportBgImageService; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportBgImageServiceImpl + * @Description: 背景图片管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/3 8:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "背景图片管理", groupName = "背景图片管理") +public class ReportBgImageServiceImpl extends SkyeyeBusinessServiceImpl implements ReportBgImageService { + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public void deletePostpose(BgImage entity) { + String basePath = tPath.replace("images", StrUtil.EMPTY); + FileUtil.deleteFile(basePath + entity.getImgPath()); + } + + /** + * 获取所有背景图片列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void getEnabledBgImageList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BgImage::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List bgImageList = list(queryWrapper); + iSysDictDataService.setName(bgImageList, "typeId", "typeName"); + outputObject.setBeans(bgImageList); + outputObject.settotal(bgImageList.size()); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/common/controller/ReportCommonController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/common/controller/ReportCommonController.java new file mode 100644 index 0000000..56b99f6 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/common/controller/ReportCommonController.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.service.ReportCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportCommonController + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "公共接口", tags = "公共接口", modelName = "公共接口") +public class ReportCommonController { + + @Autowired + private ReportCommonService reportCommonService; + + /** + * 测试数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon001", value = "解析xml格式文本", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "driverClass", name = "driverClass", value = "数据源驱动类", required = "required"), + @ApiImplicitParam(id = "url", name = "url", value = "数据源连接字符串", required = "required"), + @ApiImplicitParam(id = "user", name = "user", value = "用户名", required = "required"), + @ApiImplicitParam(id = "pass", name = "pass", value = "密码")}) + @RequestMapping("/post/ReportCommonController/testConnection") + public void testConnection(InputObject inputObject, OutputObject outputObject) { + reportCommonService.testConnection(inputObject, outputObject); + } + + /** + * 解析Xml格式文本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon002", value = "解析xml格式文本", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "xmlText", name = "xmlText", value = "xml格式文本", required = "required")}) + @RequestMapping("/post/ReportCommonController/parseXmlText") + public void parseXmlText(InputObject inputObject, OutputObject outputObject) { + reportCommonService.parseXmlText(inputObject, outputObject); + } + + /** + * 解析Json格式文本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon003", value = "解析Json格式文本", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "jsonText", name = "jsonText", value = "json格式文本", required = "required")}) + @RequestMapping("/post/ReportCommonController/parseJsonText") + public void parseJsonText(InputObject inputObject, OutputObject outputObject) { + reportCommonService.parseJsonText(inputObject, outputObject); + } + + /** + * 获取数据库类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon006", value = "获取数据库类型", method = "GET", allUse = "2") + @RequestMapping("/post/ReportCommonController/queryDataBaseMationList") + public void queryDataBaseMationList(InputObject inputObject, OutputObject outputObject) { + reportCommonService.queryDataBaseMationList(inputObject, outputObject); + } + + /** + * 获取连接池类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon007", value = "获取连接池类型", method = "GET", allUse = "2") + @RequestMapping("/post/ReportCommonController/queryPoolMationList") + public void queryPoolMationList(InputObject inputObject, OutputObject outputObject) { + reportCommonService.queryPoolMationList(inputObject, outputObject); + } + + /** + * 解析SQL数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon004", value = "解析SQL数据源", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "sqlText", name = "sqlText", value = "sql语句", required = "required"), + @ApiImplicitParam(id = "dataBaseId", name = "dataBaseId", value = "数据源id", required = "required")}) + @RequestMapping("/post/ReportCommonController/parseSQLText") + public void parseSQLText(InputObject inputObject, OutputObject outputObject) { + reportCommonService.parseSQLText(inputObject, outputObject); + } + + /** + * 解析Rest接口 + * todo serviceStr字段目前还无法解析,导致API接口解析会有问题 + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportcommon005", value = "解析Rest接口", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "serviceStr", name = "serviceStr", value = "接口对应的服务", required = "required"), + @ApiImplicitParam(id = "requestUrl", name = "requestUrl", value = "请求路径", required = "required"), + @ApiImplicitParam(id = "requestMethod", name = "requestMethod", value = "请求方式", required = "required"), + @ApiImplicitParam(id = "requestHeader", name = "requestHeader", value = "请求头", required = "required,json"), + @ApiImplicitParam(id = "requestBody", name = "requestBody", value = "请求体", required = "json")}) + @RequestMapping("/post/ReportCommonController/parseRestText") + public void parseRestText(InputObject inputObject, OutputObject outputObject) { + reportCommonService.parseRestText(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/ReportCommonService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/ReportCommonService.java new file mode 100644 index 0000000..dcfbcbb --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/ReportCommonService.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.Map; +import java.util.Set; + +/** + * @ClassName: ReportCommonService + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportCommonService { + + void testConnection(InputObject inputObject, OutputObject outputObject); + + /** + * 连接数据源 + * + * @param driverClass 数据源驱动类 + * @param url 数据源连接字符串 + * @param user 用户名 + * @param password 密码 + * @param outputObject 出参以及提示信息的返回值对象 + * @return + */ + boolean connectionDataBase(final String driverClass, final String url, final String user, + final String password, OutputObject outputObject); + + /** + * 解析Xml格式文本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void parseXmlText(InputObject inputObject, OutputObject outputObject); + + /** + * 解析Json格式文本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void parseJsonText(InputObject inputObject, OutputObject outputObject); + + /** + * 获取数据源类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void queryDataBaseMationList(InputObject inputObject, OutputObject outputObject); + + /** + * 获取连接池类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void queryPoolMationList(InputObject inputObject, OutputObject outputObject); + + /** + * 解析SQL数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void parseSQLText(InputObject inputObject, OutputObject outputObject); + + /** + * 解析Rest接口 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void parseRestText(InputObject inputObject, OutputObject outputObject); + + void parseJsonSubNode(Map paramMap, Set sets, boolean isFirstTime, String name); +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/impl/ReportCommonServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/impl/ReportCommonServiceImpl.java new file mode 100644 index 0000000..5ca81b3 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/common/service/impl/ReportCommonServiceImpl.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.common.service.impl; + +import cn.hutool.json.JSONUtil; +import com.google.gson.Gson; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.common.constans.ReportConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.service.ReportCommonService; +import com.skyeye.common.util.HttpRequestUtil; +import com.skyeye.database.service.ReportDataBaseService; +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.eve.entity.ReportMetaDataColumn; +import com.skyeye.sql.query.factory.QueryerFactory; +import net.sf.json.JSONArray; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.tree.DefaultElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportCommonServiceImpl + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:31 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "公共接口", groupName = "公共接口", manageShow = false) +public class ReportCommonServiceImpl implements ReportCommonService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReportCommonServiceImpl.class); + + @Autowired + private ReportDataBaseService reportDataBaseService; + + /** + * 测试数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void testConnection(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String driverClass = params.get("driverClass").toString(); + String url = params.get("url").toString(); + String user = params.get("user").toString(); + String pass = params.containsKey("pass") ? params.get("pass").toString() : ""; + connectionDataBase(driverClass, url, user, pass, outputObject); + } + + /** + * 连接数据源 + * + * @param driverClass 数据源驱动类 + * @param url 数据源连接字符串 + * @param user 用户名 + * @param password 密码 + * @param outputObject 出参以及提示信息的返回值对象 + * @return + */ + @Override + public boolean connectionDataBase(final String driverClass, final String url, final String user, final String password, OutputObject outputObject) { + Connection conn = null; + try { + Class.forName(driverClass); + conn = DriverManager.getConnection(url, user, password); + return true; + } catch (final Exception e) { + LOGGER.warn("testConnection", e); + if (outputObject != null) { + outputObject.setreturnMessage(e.getMessage()); + } + return false; + } finally { + this.releaseConnection(conn); + } + } + + /** + * 解析Xml格式文本 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void parseXmlText(InputObject inputObject, OutputObject outputObject) { + Element rootElement; + try { + Map inputParams = inputObject.getParams(); + // 获取xml文件 + Document document = DocumentHelper.parseText(inputParams.get("xmlText").toString()); + // 获取根目录 + rootElement = document.getRootElement(); + } catch (Exception ex) { + LOGGER.info("该文本不符合xml文件格式, 故无法解析. ", ex); + outputObject.setreturnMessage("该文本不符合xml文件格式, 故无法解析."); + return; + } + Map resultBean = new HashMap<>(); + List nodeList = new ArrayList<>(); + parseSubNode(rootElement.elements(), nodeList, rootElement.getName()); + resultBean.put("nodeArray", nodeList); + outputObject.setBean(resultBean); + } + + // 解析并拼接节点下所有子节点名称 + private void parseSubNode(List elements, List nodeList, String name) { + elements.forEach(ele -> parseSubNode(ele.elements(), nodeList, name.concat(".").concat(ele.getName()))); + if (elements.size() == 0) { + nodeList.add(name); + } + } + + @Override + public void parseJsonText(InputObject inputObject, OutputObject outputObject) { + Map inputParams = inputObject.getParams(); + Gson gson = new Gson(); + Map map = gson.fromJson(inputParams.get("jsonText").toString(), Map.class); + Set result = new HashSet<>(); + parseJsonSubNode(map, result, true, ""); + Map resultMap = new HashMap<>(); + resultMap.put("nodeArray", result); + outputObject.setBean(resultMap); + } + + /** + * 解析Json并拼接节点下所有子节点名称 + * + * @param paramMap 被解析的map + * @param sets 存放所有解析后的节点名称信息 + * @param isFirstTime 是否首层调用 + * @param name 名称 + */ + @Override + public void parseJsonSubNode(Map paramMap, Set sets, boolean isFirstTime, String name) { + Set> entries = paramMap.entrySet(); + String key; + Object value; + for (Map.Entry obj : entries) { + key = obj.getKey(); + value = obj.getValue(); + if (value instanceof Map) { + parseJsonSubNode((Map) value, sets, false, getNewName(isFirstTime, name, key)); + } else if (value instanceof List) { + List tempList = (List) value; + for (Object object : tempList) { + if (object instanceof Map) { + parseJsonSubNode((Map) object, sets, false, getNewName(isFirstTime, name, key)); + } else { + sets.add(name.concat(".").concat(key)); + } + } + } else { + sets.add(getNewName(isFirstTime, name, key)); + } + } + } + + // 根据是否首个节点后, 依照不同规则进行拼接字符 + private String getNewName(boolean isFirstTime, String name, String key) { + return isFirstTime ? key : name.concat(".").concat(key); + } + + /** + * 释放数据源 + * + * @param conn + */ + private void releaseConnection(final Connection conn) { + if (conn != null) { + try { + conn.close(); + } catch (final SQLException ex) { + LOGGER.warn("测试数据库连接后释放资源失败", ex); + } + } + } + + /** + * 获取数据库类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryDataBaseMationList(InputObject inputObject, OutputObject outputObject) { + List> beans = ReportConstants.DataBaseMation.getDataBaseMationList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 获取连接池类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryPoolMationList(InputObject inputObject, OutputObject outputObject) { + List> beans = ReportConstants.PoolMation.getPoolMationList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 解析SQL数据源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void parseSQLText(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String sqlText = params.get("sqlText").toString(); + String dataBaseId = params.get("dataBaseId").toString(); + LOGGER.info("data base id is {}", dataBaseId); + // 1.获取数据源信息 + ReportDataSource dataBase = reportDataBaseService.getReportDataSource(dataBaseId); + // 2.获取查询的列信息 + List dataColumns = QueryerFactory.create(dataBase).parseMetaDataColumns(sqlText); + outputObject.setBeans(JSONArray.fromObject(dataColumns)); + } + + /** + * 解析Rest接口 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void parseRestText(InputObject inputObject, OutputObject outputObject) { + try { + String requestUrl = inputObject.getParams().get("requestUrl").toString(); + String requestMethod = inputObject.getParams().get("requestMethod").toString(); + String requestHeader = inputObject.getParams().get("requestHeader").toString(); + String requestBody = inputObject.getParams().get("requestBody").toString(); + // 请求头 + List> array = JSONUtil.toList(requestHeader, null); + Map requestHeaderKey2Value = array.stream() + .collect(Collectors.toMap(bean -> bean.get("headerKey").toString(), bean -> bean.get("headerValue").toString())); + // 发送请求 + String responseData = HttpRequestUtil.getDataByRequest(requestUrl, requestMethod, requestHeaderKey2Value, requestBody); + // 存放并解析响应结果 + Set result = new HashSet<>(); + parseJsonSubNode(JSONUtil.toBean(responseData, Map.class), result, true, ""); + Map resultMap = new HashMap<>(); + resultMap.put("nodeArray", result); + outputObject.setBean(resultMap); + } catch (Exception ex) { + LOGGER.info("接口解析失败.", ex); + outputObject.setreturnMessage("接口解析失败."); + } + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/database/controller/ReportDataBaseController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/database/controller/ReportDataBaseController.java new file mode 100644 index 0000000..711c1e9 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/database/controller/ReportDataBaseController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.database.entity.DataBase; +import com.skyeye.database.service.ReportDataBaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportDataBaseController + * @Description: 数据库管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "数据库管理", tags = "数据库管理", modelName = "数据库管理") +public class ReportDataBaseController { + + @Autowired + private ReportDataBaseService reportDataBaseService; + + /** + * 获取数据库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportdatabase001", value = "获取数据库列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportDataBaseController/queryDataBaseList") + public void queryDataBaseList(InputObject inputObject, OutputObject outputObject) { + reportDataBaseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑数据库信 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDataBase", value = "新增/编辑数据库信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DataBase.class) + @RequestMapping("/post/ReportDataBaseController/writeDataBase") + public void writeDataBase(InputObject inputObject, OutputObject outputObject) { + reportDataBaseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除数据库信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDataBaseById", value = "根据id删除数据库信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportDataBaseController/deleteDataBaseById") + public void deleteDataBaseById(InputObject inputObject, OutputObject outputObject) { + reportDataBaseService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询数据库配置信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDataBaseById", value = "根据id查询数据库配置信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportDataBaseController/queryDataBaseById") + public void queryDataBaseById(InputObject inputObject, OutputObject outputObject) { + reportDataBaseService.selectById(inputObject, outputObject); + } + + /** + * 获取所有数据库列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllDataBaseList", value = "获取所有数据库列表", method = "GET", allUse = "2") + @RequestMapping("/post/ReportDataBaseController/queryAllDataBaseList") + public void queryAllDataBaseList(InputObject inputObject, OutputObject outputObject) { + reportDataBaseService.queryAllDataBaseList(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/database/dao/ReportDataBaseDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/database/dao/ReportDataBaseDao.java new file mode 100644 index 0000000..a67d9cb --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/database/dao/ReportDataBaseDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.dao; + +import com.skyeye.database.entity.DataBase; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataBaseDao + * @Description: 数据库数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataBaseDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/database/entity/DataBase.java b/skyeye-report/report-pro/src/main/java/com/skyeye/database/entity/DataBase.java new file mode 100644 index 0000000..21407cc --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/database/entity/DataBase.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.database.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DataBase + * @Description: 数据库实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/28 12:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:database") +@TableName(value = "report_database", autoResultMap = true) +@ApiModel("数据库实体类") +public class DataBase extends BaseGeneralInfo { + + @TableField(value = "jdbc_url") + @ApiModelProperty(value = "数据源连接字符串(JDBC)", required = "required") + private String jdbcUrl; + + @TableField(value = "user") + @ApiModelProperty(value = "数据源登录用户名", required = "required") + private String user; + + @TableField(value = "password") + @ApiModelProperty(value = "数据源登录密码") + private String password; + + @TableField(exist = false) + @ApiModelProperty(value = "数据类型", required = "required") + private String dataType; + + @TableField(value = "queryer_class") + @Property(value = "获取报表引擎查询器类名") + private String queryerClass; + + @TableField(value = "driver_class") + @Property(value = "数据源驱动类") + private String driverClass; + + @TableField(exist = false) + @ApiModelProperty(value = "报表引擎查询器使用的数据源连接池类型", required = "required") + private String poolClassType; + + @TableField(value = "pool_class") + @Property(value = "报表引擎查询器使用的数据源连接池类名") + private String poolClass; + + @TableField(exist = false) + @Property(value = "报表引擎查询器使用的数据源连接池名称") + private String poolClassName; + + @TableField(value = "options", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "数据源配置选项(JSON格式)") + private List> options; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/ReportDataBaseService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/ReportDataBaseService.java new file mode 100644 index 0000000..c7bde21 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/ReportDataBaseService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.database.entity.DataBase; +import com.skyeye.eve.entity.ReportDataSource; + +/** + * @ClassName: ReportDataBaseService + * @Description: 数据库管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataBaseService extends SkyeyeBusinessService { + + /** + * 获取数据库对象 + * + * @param dataBaseId 数据库id + * @return + */ + ReportDataSource getReportDataSource(String dataBaseId); + + void queryAllDataBaseList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/impl/ReportDataBaseServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/impl/ReportDataBaseServiceImpl.java new file mode 100644 index 0000000..ddfd230 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/database/service/impl/ReportDataBaseServiceImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.database.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.ReportConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.database.dao.ReportDataBaseDao; +import com.skyeye.database.entity.DataBase; +import com.skyeye.database.service.ReportDataBaseService; +import com.skyeye.eve.entity.ReportDataSource; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportDataBaseServiceImpl + * @Description: 数据库管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "数据库管理", groupName = "数据库管理") +public class ReportDataBaseServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataBaseService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + beans.forEach(bean -> { + String driverClass = bean.get("driverClass").toString(); + String poolClass = bean.get("poolClass").toString(); + bean.put("dataType", ReportConstants.DataBaseMation.getTypeByDricerClass(driverClass)); + bean.put("poolClassName", ReportConstants.PoolMation.getTitleByPoolClass(poolClass)); + }); + return beans; + } + + @Override + public void validatorEntity(DataBase entity) { + super.validatorEntity(entity); + entity.setDriverClass(ReportConstants.DataBaseMation.getDricerClassByType(entity.getDataType())); + entity.setQueryerClass(ReportConstants.DataBaseMation.getQueryerClassByType(entity.getDataType())); + entity.setPoolClass(ReportConstants.PoolMation.getPoolClassByType(entity.getPoolClassType())); + } + + @Override + public DataBase selectById(String id) { + DataBase dataBase = super.selectById(id); + dataBase.setDataType(ReportConstants.DataBaseMation.getTypeByDricerClass(dataBase.getDriverClass())); + dataBase.setPoolClassType(ReportConstants.PoolMation.getTypeByPoolClass(dataBase.getPoolClass())); + return dataBase; + } + + /** + * 获取数据库对象 + * + * @param dataBaseId 数据库id + * @return + */ + @Override + public ReportDataSource getReportDataSource(String dataBaseId) { + // 获取数据源信息 + DataBase dataBase = selectById(dataBaseId); + Map options = new HashMap<>(); + if (CollectionUtil.isNotEmpty(dataBase.getOptions())) { + dataBase.getOptions().stream().forEach(bean -> { + options.put(bean.get("configKey").toString(), bean.get("configValue").toString()); + }); + } + return new ReportDataSource( + dataBaseId, + dataBase.getDriverClass(), + dataBase.getJdbcUrl(), dataBase.getUser(), dataBase.getPassword(), + dataBase.getQueryerClass(), + dataBase.getPoolClass(), + options); + } + + @Override + public void queryAllDataBaseList(InputObject inputObject, OutputObject outputObject) { + List dataBaseList = queryAllData(); + outputObject.setBeans(dataBaseList); + outputObject.settotal(dataBaseList.size()); + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/classenum/ReportDataFromType.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/classenum/ReportDataFromType.java new file mode 100644 index 0000000..9409baf --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/classenum/ReportDataFromType.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.classenum; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ReportDataFromType + * @Description: 数据来源类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ReportDataFromType implements SkyeyeEnumClass { + + XML(1, "XML数据源", true, true), + JSON(2, "JSON数据源", true, false), + REST(3, "Rest接口数据源", true, false), + SQL(4, "SQL数据源", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getNameByType(Integer type) { + for (ReportDataFromType q : ReportDataFromType.values()) { + if (q.getKey().equals(type)) { + return q.getValue(); + } + } + return StrUtil.EMPTY; + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/controller/ReportDataFromController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/controller/ReportDataFromController.java new file mode 100644 index 0000000..169f392 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/controller/ReportDataFromController.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.datafrom.entity.ReportDataFrom; +import com.skyeye.datafrom.service.ReportDataFromService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportDataFromController + * @Description: 数据来源控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/3 23:17 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "数据来源", tags = "数据来源", modelName = "数据来源") +public class ReportDataFromController { + + @Autowired + private ReportDataFromService reportDataFromService; + + /** + * 获取数据来源列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportDataFromList", value = "获取数据来源列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportDataFromController/queryReportDataFromList") + public void queryReportDataFromList(InputObject inputObject, OutputObject outputObject) { + reportDataFromService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑数据来源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "saveReportDataFrom", value = "新增/编辑数据来源", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReportDataFrom.class) + @RequestMapping("/post/ReportDataFromController/saveReportDataFrom") + public void saveReportDataFrom(InputObject inputObject, OutputObject outputObject) { + reportDataFromService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除数据来源信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "delReportDataFromById", value = "根据id删除数据来源信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportDataFromController/delReportDataFromById") + public void delReportDataFromById(InputObject inputObject, OutputObject outputObject) { + reportDataFromService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询数据来源 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportDataFromById", value = "根据id查询数据来源", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportDataFromController/queryReportDataFromById") + public void queryReportDataFromById(InputObject inputObject, OutputObject outputObject) { + reportDataFromService.selectById(inputObject, outputObject); + } + + /** + * 根据数据来源信息获取要取的数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportDataFromMationById", value = "根据数据来源信息获取要取的数据", method = "POST", allUse = "0") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "needGetDataStr", name = "needGetDataStr", value = "需要获取的数据", required = "required,json"), + @ApiImplicitParam(id = "inputParams", name = "inputParams", value = "入参参数", required = "json")}) + @RequestMapping("/post/ReportDataFromController/queryReportDataFromMationById") + public void queryReportDataFromMationById(InputObject inputObject, OutputObject outputObject) { + reportDataFromService.queryReportDataFromMationById(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromDao.java new file mode 100644 index 0000000..b9c757e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFrom; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromDao + * @Description: 数据来源数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonAnalysisDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonAnalysisDao.java new file mode 100644 index 0000000..2d8e936 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonAnalysisDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromJsonAnalysis; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromJsonAnalysisDao + * @Description: JSON数据对应的解析信息数据管理层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromJsonAnalysisDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonDao.java new file mode 100644 index 0000000..2a227d6 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromJsonDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromJson; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromJsonDao + * @Description: JSON格式的数据来源数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromJsonDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestAnalysisDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestAnalysisDao.java new file mode 100644 index 0000000..e0ec1e9 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestAnalysisDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromRestAnalysis; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromRestAnalysisDao + * @Description: Rest数据对应的解析信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromRestAnalysisDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestDao.java new file mode 100644 index 0000000..dea5dff --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromRestDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromRest; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromRestDao + * @Description: Rest格式的数据来源数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromRestDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLAnalysisDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLAnalysisDao.java new file mode 100644 index 0000000..f5e087a --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLAnalysisDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromSQLAnalysis; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromSQLAnalysisDao + * @Description: SQL数据对应的解析信息数据交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromSQLAnalysisDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLDao.java new file mode 100644 index 0000000..c40772b --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromSQLDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromSQL; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromSQLDao + * @Description: SQL格式的数据来源数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromSQLDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLAnalysisDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLAnalysisDao.java new file mode 100644 index 0000000..1386949 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLAnalysisDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromXMLAnalysis; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromXMLAnalysisDao + * @Description: XML数据对应的解析信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromXMLAnalysisDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLDao.java new file mode 100644 index 0000000..334da51 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/dao/ReportDataFromXMLDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.dao; + +import com.skyeye.datafrom.entity.ReportDataFromXML; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportDataFromXMLDao + * @Description: XML格式的数据来源数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/03 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromXMLDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFrom.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFrom.java new file mode 100644 index 0000000..2c65f04 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFrom.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: ReportDataFrom + * @Description: 数据来源实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"name", "type"}) +@RedisCacheField(name = "report:datafrom") +@TableName(value = "report_data_from", autoResultMap = true) +@ApiModel("数据来源实体类") +public class ReportDataFrom extends BaseGeneralInfo { + + @TableField(value = "type") + @ApiModelProperty(value = "数据来源类型,参考#ReportDataFromType", required = "required,num") + private Integer type; + + @TableField(exist = false) + @ApiModelProperty(value = "JSON数据源") + private ReportDataFromJson jsonEntity; + + @TableField(exist = false) + @ApiModelProperty(value = "Rest数据源") + private ReportDataFromRest restEntity; + + @TableField(exist = false) + @ApiModelProperty(value = "SQL数据源") + private ReportDataFromSQL sqlEntity; + + @TableField(exist = false) + @ApiModelProperty(value = "XML数据源") + private ReportDataFromXML xmlEntity; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJson.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJson.java new file mode 100644 index 0000000..516719a --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJson.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ReportDataFromJson + * @Description: JSON格式的数据来源 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_json", autoResultMap = true) +@ApiModel("JSON格式的数据来源") +public class ReportDataFromJson extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "from_id") + @Property(value = "来源id") + private String fromId; + + @TableField(value = "json_content") + @ApiModelProperty(value = "json串", required = "required") + private String jsonContent; + + @TableField(exist = false) + @ApiModelProperty(value = "解析的数据") + private List analysisList; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJsonAnalysis.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJsonAnalysis.java new file mode 100644 index 0000000..cb6a0f6 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromJsonAnalysis.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportDataFromJsonAnalysis + * @Description: JSON数据对应的解析信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_json_analysis", autoResultMap = true) +@ApiModel("JSON数据对应的解析信息") +public class ReportDataFromJsonAnalysis extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "json_id") + @Property(value = "json数据源的id") + private String jsonId; + + @TableField(value = "`key`") + @ApiModelProperty(value = "json解析后的key", required = "required") + private String key; + + @TableField("`name`") + @ApiModelProperty(value = "名称") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRest.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRest.java new file mode 100644 index 0000000..a107c21 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRest.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportDataFromRest + * @Description: Rest格式的数据来源 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_rest", autoResultMap = true) +@ApiModel("Rest格式的数据来源") +public class ReportDataFromRest extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "from_id") + @Property(value = "来源id") + private String fromId; + + @TableField("service_str") + @ApiModelProperty(value = "接口对应的服务,由前端进行配置,方便前端解析", required = "required") + private String serviceStr; + + @TableField(value = "rest_url") + @ApiModelProperty(value = "接口地址", required = "required") + private String restUrl; + + @TableField(value = "method") + @ApiModelProperty(value = "接口请求类型", required = "required") + private String method; + + @TableField(value = "header", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "header请求头") + private List> header; + + @TableField(value = "request_body") + @ApiModelProperty(value = "请求体") + private String requestBody; + + @TableField(exist = false) + @ApiModelProperty(value = "解析的数据") + private List analysisList; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRestAnalysis.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRestAnalysis.java new file mode 100644 index 0000000..c507875 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromRestAnalysis.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportDataFromRestAnalysis + * @Description: Rest数据对应的解析信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_rest_analysis", autoResultMap = true) +@ApiModel("Rest数据对应的解析信息") +public class ReportDataFromRestAnalysis extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "rest_id") + @Property(value = "接口数据源的id") + private String restId; + + @TableField(value = "`key`") + @ApiModelProperty(value = "接口返回值解析后的key", required = "required") + private String key; + + @TableField("`name`") + @ApiModelProperty(value = "名称") + private String name; + + @TableField("remark") + @ApiModelProperty("相关描述") + private String remark; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQL.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQL.java new file mode 100644 index 0000000..85de0f7 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQL.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ReportDataFromSQL + * @Description: SQL格式的数据来源 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_sql", autoResultMap = true) +@ApiModel("SQL格式的数据来源") +public class ReportDataFromSQL extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "from_id") + @Property(value = "来源id") + private String fromId; + + @TableField(value = "sql_content") + @ApiModelProperty(value = "sql串", required = "required") + private String sqlContent; + + @TableField(value = "data_base_id") + @ApiModelProperty(value = "数据库id", required = "required") + private String dataBaseId; + + @TableField(exist = false) + @ApiModelProperty(value = "解析的数据") + private List analysisList; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQLAnalysis.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQLAnalysis.java new file mode 100644 index 0000000..ef2d778 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromSQLAnalysis.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportDataFromSQLAnalysis + * @Description: SQL数据对应的解析信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_sql_analysis", autoResultMap = true) +@ApiModel("SQL数据对应的解析信息") +public class ReportDataFromSQLAnalysis extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "sql_id") + @Property(value = "sql数据源的id") + private String sqlId; + + @TableField(value = "`key`") + @ApiModelProperty(value = "sql解析后的key", required = "required") + private String key; + + @TableField("`name`") + @ApiModelProperty(value = "名称") + private String name; + + @TableField("data_type") + @ApiModelProperty(value = "字段数据类型") + private String dataType; + + @TableField("data_length") + @Property(value = "字段长度") + private Integer dataLength; + + @TableField("data_precision") + @Property(value = "字段精度") + private Integer dataPrecision; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXML.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXML.java new file mode 100644 index 0000000..16edaec --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXML.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ReportDataFromXML + * @Description: XML格式的数据来源 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_xml", autoResultMap = true) +@ApiModel("XML格式的数据来源") +public class ReportDataFromXML extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "from_id") + @Property(value = "来源id") + private String fromId; + + @TableField(value = "xml_content") + @ApiModelProperty(value = "xml内容", required = "required") + private String xmlContent; + + @TableField(exist = false) + @ApiModelProperty(value = "解析的数据") + private List analysisList; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXMLAnalysis.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXMLAnalysis.java new file mode 100644 index 0000000..7e6acdb --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/entity/ReportDataFromXMLAnalysis.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportDataFromXMLAnalysis + * @Description: XML数据对应的解析信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_data_from_xml_analysis", autoResultMap = true) +@ApiModel("XML数据对应的解析信息") +public class ReportDataFromXMLAnalysis extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "xml_id") + @Property(value = "xml数据源的id") + private String xmlId; + + @TableField(value = "`key`") + @ApiModelProperty(value = "xml解析后的key", required = "required") + private String key; + + @TableField("`name`") + @ApiModelProperty(value = "名称") + private String name; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonAnalysisService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonAnalysisService.java new file mode 100644 index 0000000..734e2a0 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonAnalysisService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromJsonAnalysis; + +import java.util.List; + +/** + * @ClassName: ReportDataFromJsonAnalysisService + * @Description: JSON数据对应的解析信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromJsonAnalysisService extends SkyeyeBusinessService { + + void saveList(String objectId, List beans); + + void deleteByObjectId(String objectId); + + List selectByObjectId(String objectId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonService.java new file mode 100644 index 0000000..5ddc046 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromJsonService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromJson; + +/** + * @ClassName: ReportDataFromJsonService + * @Description: JSON格式的数据来源服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromJsonService extends SkyeyeBusinessService { + + void deleteByFromId(String fromId); + + ReportDataFromJson getByFromId(String fromId); + + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestAnalysisService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestAnalysisService.java new file mode 100644 index 0000000..0975b80 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestAnalysisService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromRestAnalysis; + +import java.util.List; + +/** + * @ClassName: ReportDataFromRestAnalysisService + * @Description: Rest数据对应的解析信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromRestAnalysisService extends SkyeyeBusinessService { + + void saveList(String objectId, List beans); + + void deleteByObjectId(String objectId); + + List selectByObjectId(String objectId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestService.java new file mode 100644 index 0000000..bc8e679 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromRestService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromRest; + +/** + * @ClassName: ReportDataFromRestService + * @Description: Rest格式的数据来源服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromRestService extends SkyeyeBusinessService { + + void deleteByFromId(String fromId); + + ReportDataFromRest getByFromId(String fromId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLAnalysisService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLAnalysisService.java new file mode 100644 index 0000000..314363e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLAnalysisService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromSQLAnalysis; + +import java.util.List; + +/** + * @ClassName: ReportDataFromSQLAnalysisService + * @Description: SQL数据对应的解析信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromSQLAnalysisService extends SkyeyeBusinessService { + + void saveList(String objectId, List beans); + + void deleteByObjectId(String objectId); + + List selectByObjectId(String objectId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLService.java new file mode 100644 index 0000000..5ef0ccd --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromSQLService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromSQL; + +/** + * @ClassName: ReportDataFromSQLService + * @Description: SQL格式的数据来源服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromSQLService extends SkyeyeBusinessService { + + void deleteByFromId(String fromId); + + ReportDataFromSQL getByFromId(String fromId); + + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromService.java new file mode 100644 index 0000000..a850dd4 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromService.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.datafrom.entity.ReportDataFrom; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportDataFromService + * @Description: 数据来源服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportDataFromService extends SkyeyeBusinessService { + + /** + * 根据数据来源id获取该数据来源下的所有数据并组装成map + * + * @param fromId 数据来源id + * @param needGetKeys 需要获取的key + * @param inputParams 入参 + * @return 该数据来源下的所有数据并组装成map + */ + Map getReportDataFromMapByFromId(String fromId, List needGetKeys, String inputParams); + + /** + * 根据数据来源信息获取要取的数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + void queryReportDataFromMationById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLAnalysisService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLAnalysisService.java new file mode 100644 index 0000000..d3c707b --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLAnalysisService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromXMLAnalysis; + +import java.util.List; + +/** + * @ClassName: ReportDataFromXMLAnalysisService + * @Description: XML数据对应的解析信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromXMLAnalysisService extends SkyeyeBusinessService { + + void saveList(String objectId, List beans); + + void deleteByObjectId(String objectId); + + List selectByObjectId(String objectId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLService.java new file mode 100644 index 0000000..353bbd8 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/ReportDataFromXMLService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.datafrom.entity.ReportDataFromXML; + +/** + * @ClassName: ReportDataFromXMLService + * @Description: XML格式的数据来源服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportDataFromXMLService extends SkyeyeBusinessService { + + void deleteByFromId(String fromId); + + ReportDataFromXML getByFromId(String fromId); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonAnalysisServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonAnalysisServiceImpl.java new file mode 100644 index 0000000..f553cd9 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonAnalysisServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromJsonAnalysisDao; +import com.skyeye.datafrom.entity.ReportDataFromJsonAnalysis; +import com.skyeye.datafrom.service.ReportDataFromJsonAnalysisService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromJsonAnalysisServiceImpl + * @Description: JSON数据对应的解析信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "JSON数据对应的解析信息", groupName = "JSON数据对应的解析信息", manageShow = false) +public class ReportDataFromJsonAnalysisServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromJsonAnalysisService { + + @Override + public void saveList(String objectId, List beans) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ReportDataFromJsonAnalysis analysis : beans) { + analysis.setJsonId(objectId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromJsonAnalysis::getJsonId), objectId); + remove(queryWrapper); + } + + @Override + public List selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromJsonAnalysis::getJsonId), objectId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonServiceImpl.java new file mode 100644 index 0000000..70d4b1f --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromJsonServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromJsonDao; +import com.skyeye.datafrom.entity.ReportDataFromJson; +import com.skyeye.datafrom.entity.ReportDataFromJsonAnalysis; +import com.skyeye.datafrom.service.ReportDataFromJsonAnalysisService; +import com.skyeye.datafrom.service.ReportDataFromJsonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromJsonServiceImpl + * @Description: JSON格式的数据来源服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 21:47 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "JSON格式的数据来源", groupName = "JSON格式的数据来源", manageShow = false) +public class ReportDataFromJsonServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromJsonService { + + @Autowired + private ReportDataFromJsonAnalysisService reportDataFromJsonAnalysisService; + + @Override + public void writePostpose(ReportDataFromJson entity, String userId) { + super.writePostpose(entity, userId); + reportDataFromJsonAnalysisService.saveList(entity.getId(), entity.getAnalysisList()); + } + + @Override + public void deletePostpose(String id) { + reportDataFromJsonAnalysisService.deleteByObjectId(id); + } + + @Override + public void deleteByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromJson::getFromId), fromId); + ReportDataFromJson dataFromJson = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromJson)) { + deleteById(dataFromJson.getId()); + } + } + + @Override + public ReportDataFromJson getByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromJson::getFromId), fromId); + ReportDataFromJson dataFromJson = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromJson)) { + List analysisList = reportDataFromJsonAnalysisService.selectByObjectId(dataFromJson.getId()); + dataFromJson.setAnalysisList(analysisList); + } + return dataFromJson; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestAnalysisServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestAnalysisServiceImpl.java new file mode 100644 index 0000000..e42a906 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestAnalysisServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromRestAnalysisDao; +import com.skyeye.datafrom.entity.ReportDataFromRestAnalysis; +import com.skyeye.datafrom.service.ReportDataFromRestAnalysisService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromRestAnalysisServiceImpl + * @Description: Rest数据对应的解析信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:58 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "Rest数据对应的解析信息", groupName = "Rest数据对应的解析信息", manageShow = false) +public class ReportDataFromRestAnalysisServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromRestAnalysisService { + + @Override + public void saveList(String objectId, List beans) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ReportDataFromRestAnalysis analysis : beans) { + analysis.setRestId(objectId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromRestAnalysis::getRestId), objectId); + remove(queryWrapper); + } + + @Override + public List selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromRestAnalysis::getRestId), objectId); + List list = list(queryWrapper); + return list; + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestServiceImpl.java new file mode 100644 index 0000000..c8b6354 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromRestServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromRestDao; +import com.skyeye.datafrom.entity.ReportDataFromRest; +import com.skyeye.datafrom.entity.ReportDataFromRestAnalysis; +import com.skyeye.datafrom.service.ReportDataFromRestAnalysisService; +import com.skyeye.datafrom.service.ReportDataFromRestService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromRestServiceImpl + * @Description: Rest格式的数据来源服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 22:21 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "Rest格式的数据来源", groupName = "Rest格式的数据来源", manageShow = false) +public class ReportDataFromRestServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromRestService { + + @Autowired + private ReportDataFromRestAnalysisService reportDataFromRestAnalysisService; + + @Override + public void writePostpose(ReportDataFromRest entity, String userId) { + super.writePostpose(entity, userId); + reportDataFromRestAnalysisService.saveList(entity.getId(), entity.getAnalysisList()); + } + + @Override + public void deletePostpose(String id) { + reportDataFromRestAnalysisService.deleteByObjectId(id); + } + + @Override + public void deleteByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromRest::getFromId), fromId); + ReportDataFromRest dataFromRest = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromRest)) { + deleteById(dataFromRest.getId()); + } + } + + @Override + public ReportDataFromRest getByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromRest::getFromId), fromId); + ReportDataFromRest dataFromRest = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromRest)) { + List analysisList = reportDataFromRestAnalysisService.selectByObjectId(dataFromRest.getId()); + dataFromRest.setAnalysisList(analysisList); + } + return dataFromRest; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLAnalysisServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLAnalysisServiceImpl.java new file mode 100644 index 0000000..f571c48 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLAnalysisServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromSQLAnalysisDao; +import com.skyeye.datafrom.entity.ReportDataFromSQLAnalysis; +import com.skyeye.datafrom.service.ReportDataFromSQLAnalysisService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromSQLAnalysisServiceImpl + * @Description: SQL数据对应的解析信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "SQL数据对应的解析信息", groupName = "SQL数据对应的解析信息", manageShow = false) +public class ReportDataFromSQLAnalysisServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromSQLAnalysisService { + + @Override + public void saveList(String objectId, List beans) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ReportDataFromSQLAnalysis analysis : beans) { + analysis.setSqlId(objectId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromSQLAnalysis::getSqlId), objectId); + remove(queryWrapper); + } + + @Override + public List selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromSQLAnalysis::getSqlId), objectId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLServiceImpl.java new file mode 100644 index 0000000..f98c380 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromSQLServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromSQLDao; +import com.skyeye.datafrom.entity.ReportDataFromSQL; +import com.skyeye.datafrom.entity.ReportDataFromSQLAnalysis; +import com.skyeye.datafrom.service.ReportDataFromSQLAnalysisService; +import com.skyeye.datafrom.service.ReportDataFromSQLService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromSQLServiceImpl + * @Description: SQL格式的数据来源服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "SQL格式的数据来源", groupName = "SQL格式的数据来源", manageShow = false) +public class ReportDataFromSQLServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromSQLService { + + @Autowired + private ReportDataFromSQLAnalysisService reportDataFromSQLAnalysisService; + + @Override + public void writePostpose(ReportDataFromSQL entity, String userId) { + super.writePostpose(entity, userId); + reportDataFromSQLAnalysisService.saveList(entity.getId(), entity.getAnalysisList()); + } + + @Override + public void deletePostpose(String id) { + reportDataFromSQLAnalysisService.deleteByObjectId(id); + } + + @Override + public void deleteByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromSQL::getFromId), fromId); + ReportDataFromSQL dataFromSQL = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromSQL)) { + deleteById(dataFromSQL.getId()); + } + } + + @Override + public ReportDataFromSQL getByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromSQL::getFromId), fromId); + ReportDataFromSQL dataFromSQL = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromSQL)) { + List analysisList = reportDataFromSQLAnalysisService.selectByObjectId(dataFromSQL.getId()); + dataFromSQL.setAnalysisList(analysisList); + } + return dataFromSQL; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromServiceImpl.java new file mode 100644 index 0000000..73177b3 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromServiceImpl.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.jayway.jsonpath.JsonPath; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.HttpRequestUtil; +import com.skyeye.database.service.ReportDataBaseService; +import com.skyeye.datafrom.classenum.ReportDataFromType; +import com.skyeye.datafrom.dao.ReportDataFromDao; +import com.skyeye.datafrom.entity.ReportDataFrom; +import com.skyeye.datafrom.entity.ReportDataFromRest; +import com.skyeye.datafrom.service.*; +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.eve.entity.ReportMetaDataRow; +import com.skyeye.sql.query.factory.QueryerFactory; +import com.skyeye.util.XmlExercise; +import net.sf.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportDataFromServiceImpl + * @Description: 数据来源服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/3 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "数据来源", groupName = "数据来源") +public class ReportDataFromServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromService { + + @Autowired + private ReportDataFromJsonService reportDataFromJsonService; + + @Autowired + private ReportDataFromRestService reportDataFromRestService; + + @Autowired + private ReportDataFromSQLService reportDataFromSQLService; + + @Autowired + private ReportDataFromXMLService reportDataFromXMLService; + + @Autowired + private ReportDataBaseService reportDataBaseService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + beans.forEach(bean -> { + bean.put("typeName", ReportDataFromType.getNameByType(Integer.parseInt(bean.get("type").toString()))); + }); + return beans; + } + + @Override + public void updatePrepose(ReportDataFrom entity) { + ReportDataFrom oldDataFrom = selectById(entity.getId()); + deletePostpose(oldDataFrom); + } + + @Override + public void writePostpose(ReportDataFrom entity, String userId) { + super.writePostpose(entity, userId); + if (entity.getType() == ReportDataFromType.XML.getKey()) { + entity.getXmlEntity().setFromId(entity.getId()); + reportDataFromXMLService.createEntity(entity.getXmlEntity(), userId); + } else if (entity.getType() == ReportDataFromType.JSON.getKey()) { + entity.getJsonEntity().setFromId(entity.getId()); + reportDataFromJsonService.createEntity(entity.getJsonEntity(), userId); + } else if (entity.getType() == ReportDataFromType.REST.getKey()) { + entity.getRestEntity().setFromId(entity.getId()); + reportDataFromRestService.createEntity(entity.getRestEntity(), userId); + } else if (entity.getType() == ReportDataFromType.SQL.getKey()) { + entity.getSqlEntity().setFromId(entity.getId()); + reportDataFromSQLService.createEntity(entity.getSqlEntity(), userId); + } + } + + @Override + public void deletePostpose(ReportDataFrom entity) { + if (entity.getType() == ReportDataFromType.XML.getKey()) { + reportDataFromXMLService.deleteByFromId(entity.getId()); + } else if (entity.getType() == ReportDataFromType.JSON.getKey()) { + reportDataFromJsonService.deleteByFromId(entity.getId()); + } else if (entity.getType() == ReportDataFromType.REST.getKey()) { + reportDataFromRestService.deleteByFromId(entity.getId()); + } else if (entity.getType() == ReportDataFromType.SQL.getKey()) { + reportDataFromSQLService.deleteByFromId(entity.getId()); + } + } + + @Override + public ReportDataFrom selectById(String id) { + ReportDataFrom reportDataFrom = super.selectById(id); + if (reportDataFrom.getType() == ReportDataFromType.XML.getKey()) { + reportDataFrom.setXmlEntity(reportDataFromXMLService.getByFromId(id)); + } else if (reportDataFrom.getType() == ReportDataFromType.JSON.getKey()) { + reportDataFrom.setJsonEntity(reportDataFromJsonService.getByFromId(id)); + } else if (reportDataFrom.getType() == ReportDataFromType.REST.getKey()) { + reportDataFrom.setRestEntity(reportDataFromRestService.getByFromId(id)); + } else if (reportDataFrom.getType() == ReportDataFromType.SQL.getKey()) { + reportDataFrom.setSqlEntity(reportDataFromSQLService.getByFromId(id)); + } + return reportDataFrom; + } + + /** + * 根据数据来源id获取该数据来源下的所有数据并组装成map + * + * @param fromId 数据来源id + * @param needGetKeys 需要获取的key + * @param inputParams 入参 + * @return 该数据来源下的所有数据并组装成map + */ + @Override + public Map getReportDataFromMapByFromId(String fromId, List needGetKeys, String inputParams) { + String jsonContent = getJsonStrByFromId(fromId, inputParams); + Map result = new HashMap<>(); + needGetKeys.forEach(key -> { + Object value = JsonPath.read(jsonContent, String.format(Locale.ROOT, "$.%s", key)); + result.put(key, value); + }); + result.put("allData", JSONUtil.toBean(jsonContent, null)); + return result; + } + + /** + * 根据数据来源id获取数据并转换成json串 + * + * @param fromId 数据来源id + * @return 获取数据并转换成json串 + */ + private String getJsonStrByFromId(String fromId, String inputParams) { + // 根据dataFromId获取对应type + ReportDataFrom reportDataFrom = selectById(fromId); + if (ObjectUtil.isNotEmpty(reportDataFrom)) { + if (reportDataFrom.getType() == ReportDataFromType.XML.getKey()) { + return XmlExercise.xml2json(reportDataFrom.getXmlEntity().getXmlContent()); + } else if (reportDataFrom.getType() == ReportDataFromType.JSON.getKey()) { + return reportDataFrom.getJsonEntity().getJsonContent(); + } else if (reportDataFrom.getType() == ReportDataFromType.REST.getKey()) { + ReportDataFromRest restEntity = reportDataFrom.getRestEntity(); + Map requestHeaderKey2Value = restEntity.getHeader().stream() + .collect(Collectors.toMap(bean -> bean.get("headerKey").toString(), bean -> bean.get("headerValue").toString())); + + String responseData = HttpRequestUtil.getDataByRequest(restEntity.getRestUrl(), restEntity.getMethod(), requestHeaderKey2Value, inputParams); + return responseData; + } else if (reportDataFrom.getType() == ReportDataFromType.SQL.getKey()) { + // 1.获取数据源信息 + ReportDataSource dataBase = reportDataBaseService.getReportDataSource(reportDataFrom.getSqlEntity().getDataBaseId()); + List metaDataRows = QueryerFactory.create(dataBase).getMetaDataRows(reportDataFrom.getSqlEntity().getSqlContent()); + return JSON.toJSONString(resetSqlResultData(metaDataRows)); + } + } + return "{}"; + } + + private List> resetSqlResultData(List metaDataRows) { + List> result = new ArrayList<>(); + metaDataRows.forEach(cells -> { + Map bean = new HashMap<>(); + cells.getCells().forEach((key, cell) -> { + bean.put(key, cell.getValue()); + }); + result.add(bean); + }); + return result; + } + + /** + * 根据数据来源信息获取要取的数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryReportDataFromMationById(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + // 根据数据来源id获取解析对应的数据 + String fromId = params.get("id").toString(); + // 前台需要获取的数据json + Map needGetData = JSONObject.fromObject(params.get("needGetDataStr").toString()); + List needGetKeys = needGetData.entrySet().stream().map(bean -> bean.getKey()).collect(Collectors.toList()); + // 入参 + String inputParams = params.get("inputParams").toString(); + + Map data = getReportDataFromMapByFromId(fromId, needGetKeys, inputParams); + Map result = new HashMap<>(); + needGetData.forEach((key, value) -> { + if (data.containsKey(key)) { + result.put(key, data.get(key)); + } else { + result.put(key, value); + } + }); + outputObject.setBean(result); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLAnalysisServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLAnalysisServiceImpl.java new file mode 100644 index 0000000..cf17dd4 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLAnalysisServiceImpl.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromXMLAnalysisDao; +import com.skyeye.datafrom.entity.ReportDataFromXMLAnalysis; +import com.skyeye.datafrom.service.ReportDataFromXMLAnalysisService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromXMLAnalysisServiceImpl + * @Description: XML数据对应的解析信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:54 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "XML数据对应的解析信息", groupName = "XML数据对应的解析信息", manageShow = false) +public class ReportDataFromXMLAnalysisServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromXMLAnalysisService { + + @Override + public void saveList(String objectId, List beans) { + deleteByObjectId(objectId); + if (CollectionUtil.isNotEmpty(beans)) { + for (ReportDataFromXMLAnalysis analysis : beans) { + analysis.setXmlId(objectId); + } + createEntity(beans, StrUtil.EMPTY); + } + } + + @Override + public void deleteByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromXMLAnalysis::getXmlId), objectId); + remove(queryWrapper); + } + + @Override + public List selectByObjectId(String objectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromXMLAnalysis::getXmlId), objectId); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLServiceImpl.java new file mode 100644 index 0000000..cc7cf15 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/datafrom/service/impl/ReportDataFromXMLServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.datafrom.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.datafrom.dao.ReportDataFromXMLDao; +import com.skyeye.datafrom.entity.ReportDataFromXML; +import com.skyeye.datafrom.entity.ReportDataFromXMLAnalysis; +import com.skyeye.datafrom.service.ReportDataFromXMLAnalysisService; +import com.skyeye.datafrom.service.ReportDataFromXMLService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportDataFromXMLServiceImpl + * @Description: XML格式的数据来源服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/4 8:48 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "XML格式的数据来源", groupName = "XML格式的数据来源", manageShow = false) +public class ReportDataFromXMLServiceImpl extends SkyeyeBusinessServiceImpl implements ReportDataFromXMLService { + + @Autowired + private ReportDataFromXMLAnalysisService reportDataFromXMLAnalysisService; + + @Override + public void writePostpose(ReportDataFromXML entity, String userId) { + super.writePostpose(entity, userId); + reportDataFromXMLAnalysisService.saveList(entity.getId(), entity.getAnalysisList()); + } + + @Override + public void deletePostpose(String id) { + reportDataFromXMLAnalysisService.deleteByObjectId(id); + } + + @Override + public void deleteByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromXML::getFromId), fromId); + ReportDataFromXML dataFromXML = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromXML)) { + deleteById(dataFromXML.getId()); + } + } + + @Override + public ReportDataFromXML getByFromId(String fromId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportDataFromXML::getFromId), fromId); + ReportDataFromXML dataFromXML = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(dataFromXML)) { + List analysisList = reportDataFromXMLAnalysisService.selectByObjectId(dataFromXML.getId()); + dataFromXML.setAnalysisList(analysisList); + } + return dataFromXML; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/dom/controller/DomModelController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/controller/DomModelController.java new file mode 100644 index 0000000..a82c495 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/controller/DomModelController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dom.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dom.entity.DomModel; +import com.skyeye.dom.service.DomModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: DomModelController + * @Description: DOM模型控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/4 10:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "DOM模型管理", tags = "DOM模型管理", modelName = "DOM模型管理") +public class DomModelController { + + @Autowired + private DomModelService domModelService; + + /** + * 新增/编辑DOM模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDomModel", value = "新增/编辑DOM模型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = DomModel.class) + @RequestMapping("/post/DomModelController/writeDomModel") + public void writeDomModel(InputObject inputObject, OutputObject outputObject) { + domModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取DOM模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDomModelList", value = "获取DOM模型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DomModelController/queryDomModelList") + public void queryDomModelList(InputObject inputObject, OutputObject outputObject) { + domModelService.queryPageList(inputObject, outputObject); + } + + /** + * 根据Id删除DOM模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDomModelById", value = "根据Id删除DOM模型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/DomModelController/deleteDomModelById") + public void deleteDomModelById(InputObject inputObject, OutputObject outputObject) { + domModelService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启动的DOM模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEnabledDomModelList", value = "获取所有启动的DOM模型列表", method = "GET", allUse = "2") + @RequestMapping("/post/DomModelController/queryAllEnabledDomModelList") + public void queryAllEnabledDomModelList(InputObject inputObject, OutputObject outputObject) { + domModelService.queryAllEnabledDomModelList(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/dom/dao/DomModelDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/dao/DomModelDao.java new file mode 100644 index 0000000..f02becf --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/dao/DomModelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dom.dao; + +import com.skyeye.dom.entity.DomModel; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: DomModelDao + * @Description: DOM模型数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/4 10:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DomModelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/dom/entity/DomModel.java b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/entity/DomModel.java new file mode 100644 index 0000000..99ed833 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/entity/DomModel.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dom.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: DomModel + * @Description: DOM模型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/25 16:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:dom") +@TableName(value = "report_dom_model", autoResultMap = true) +@ApiModel("DOM模型实体类") +public class DomModel extends BaseGeneralInfo { + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("img_path") + @ApiModelProperty(value = "图片路径", required = "required") + private String imgPath; + + @TableField("content") + @ApiModelProperty(value = "dom脚本", required = "required") + private String content; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @ApiModelProperty(value = "所属分类名称,数据来自数据字典") + private String typeName; + + @TableField("default_width") + @ApiModelProperty(value = "默认宽度,单位:px", required = "required,num") + private Integer defaultWidth; + + @TableField("default_height") + @ApiModelProperty(value = "默认高度,单位:px", required = "required,num") + private Integer defaultHeight; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/DomModelService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/DomModelService.java new file mode 100644 index 0000000..d94d694 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/DomModelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dom.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.dom.entity.DomModel; + +/** + * @ClassName: DomModelService + * @Description: DOM模型服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/4 10:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface DomModelService extends SkyeyeBusinessService { + + void queryAllEnabledDomModelList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/impl/DomModelServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/impl/DomModelServiceImpl.java new file mode 100644 index 0000000..5698247 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/dom/service/impl/DomModelServiceImpl.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dom.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dom.dao.DomModelDao; +import com.skyeye.dom.entity.DomModel; +import com.skyeye.dom.service.DomModelService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: DomModelServiceImpl + * @Description: DOM模型服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/4 10:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "DOM模型管理", groupName = "DOM模型管理") +public class DomModelServiceImpl extends SkyeyeBusinessServiceImpl implements DomModelService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public void queryAllEnabledDomModelList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(DomModel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List domModelList = list(queryWrapper); + iSysDictDataService.setName(domModelList, "typeId", "typeName"); + outputObject.setBeans(domModelList); + outputObject.settotal(domModelList.size()); + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/classenum/ReportModelState.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/classenum/ReportModelState.java new file mode 100644 index 0000000..7393f73 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/classenum/ReportModelState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ReportModelState + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 10:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ReportModelState implements SkyeyeEnumClass { + + NORMAL(1, "正常", true, false), + ABANDONED(2, "废弃", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportHistoryController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportHistoryController.java new file mode 100644 index 0000000..8d9fef2 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportHistoryController.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.echarts.service.ReportImportHistoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportImportHistoryController + * @Description: Echarts导入历史控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 14:04 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "Echarts导入历史", tags = "Echarts导入历史", modelName = "Echarts导入历史") +public class ReportImportHistoryController { + + @Autowired + private ReportImportHistoryService reportImportHistoryService; + + /** + * 获取模型上传导入历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportImportHistoryList", value = "获取模型上传导入历史列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportImportHistoryController/queryReportImportHistoryList") + public void queryReportImportHistoryList(InputObject inputObject, OutputObject outputObject) { + reportImportHistoryService.queryPageList(inputObject, outputObject); + } + + /** + * 模型上传导入 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "importReportImportModel", value = "模型上传导入", method = "POST", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "modelId", name = "modelId", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportImportHistoryController/importReportImportModel") + public void importReportImportModel(InputObject inputObject, OutputObject outputObject) { + reportImportHistoryService.importReportImportModel(inputObject, outputObject); + } + + /** + * 获取所有版本最大的echarts模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllMaxVersionReportModel", value = "获取所有版本最大的echarts模型信息", method = "GET", allUse = "2") + @RequestMapping("/post/ReportImportHistoryController/queryAllMaxVersionReportModel") + public void queryAllMaxVersionReportModel(InputObject inputObject, OutputObject outputObject) { + reportImportHistoryService.queryAllMaxVersionReportModel(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportModelController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportModelController.java new file mode 100644 index 0000000..829a498 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/controller/ReportImportModelController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.echarts.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.echarts.entity.ImportModel; +import com.skyeye.echarts.service.ReportImportModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportImportModelController + * @Description: Echarts模型管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "Echarts模型管理", tags = "Echarts模型管理", modelName = "Echarts模型管理") +public class ReportImportModelController { + + @Autowired + private ReportImportModelService reportImportModelService; + + /** + * 获取Echarts模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportImportModelList", value = "获取Echarts模型信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportImportModelController/queryReportImportModelList") + public void queryReportImportModelList(InputObject inputObject, OutputObject outputObject) { + reportImportModelService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑Echarts模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeReportImportModel", value = "新增/编辑Echarts模型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ImportModel.class) + @RequestMapping("/post/ReportImportModelController/writeReportImportModel") + public void writeReportImportModel(InputObject inputObject, OutputObject outputObject) { + reportImportModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除Echarts模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "delReportImportModelById", value = "根据id删除Echarts模型信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportImportModelController/delReportImportModelById") + public void delReportImportModelById(InputObject inputObject, OutputObject outputObject) { + reportImportModelService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportHistoryDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportHistoryDao.java new file mode 100644 index 0000000..38a4ed4 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportHistoryDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.dao; + +import com.skyeye.echarts.entity.ImportHistory; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportImportHistoryDao + * @Description: Echarts导入历史数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 14:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportImportHistoryDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportModelDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportModelDao.java new file mode 100644 index 0000000..2430337 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportImportModelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.echarts.dao; + +import com.skyeye.echarts.entity.ImportModel; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportImportModelDao + * @Description: Echarts模型管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportImportModelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelAttrDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelAttrDao.java new file mode 100644 index 0000000..dbaf333 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelAttrDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.dao; + +import com.skyeye.echarts.entity.ReportModelAttr; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportModelAttrDao + * @Description: Echarts报表模型属性数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 15:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportModelAttrDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelDao.java new file mode 100644 index 0000000..26636c8 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/dao/ReportModelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.dao; + +import com.skyeye.echarts.entity.ReportModel; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ReportModelDao + * @Description: 模型版本数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 14:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportModelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportHistory.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportHistory.java new file mode 100644 index 0000000..d0de458 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportHistory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ImportHistory + * @Description: Echarts导入历史 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 9:10 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_import_history", autoResultMap = true) +@ApiModel("Echarts导入历史实体类") +public class ImportHistory extends OperatorUserInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @Property(value = "名称") + private String name; + + @TableField("model_code") + @Property(value = "模型code") + private String modelCode; + + @TableField("size") + @Property(value = "文件大小") + private String size; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportModel.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportModel.java new file mode 100644 index 0000000..4b8a372 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ImportModel.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ImportModel + * @Description: Echarts模型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/2 8:46 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "report:echarts") +@TableName(value = "report_import_model", autoResultMap = true) +@ApiModel("Echarts模型实体类") +public class ImportModel extends BaseGeneralInfo { + + @TableField("model_code") + @ApiModelProperty(value = "模型code", required = "required", fuzzyLike = true) + private String modelCode; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @ApiModelProperty(value = "所属分类名称,数据来自数据字典") + private String typeName; + + @TableField(exist = false) + @Property(value = "属性的map") + private Map attr; + + @TableField(exist = false) + @Property(value = "最新的模型信息") + private ReportModel reportModel; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符1") + private String placeholder1; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符2") + private String placeholder2; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符3") + private String placeholder3; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符4") + private String placeholder4; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符5") + private String placeholder5; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符6") + private String placeholder6; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符7") + private String placeholder7; + + @TableField(exist = false) + @ApiModelProperty(value = "占位符8") + private String placeholder8; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModel.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModel.java new file mode 100644 index 0000000..a6b9037 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModel.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.entity; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportModel + * @Description: 模型版本实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/3 9:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_model", autoResultMap = true) +@ApiModel("Echarts模型实体类") +@ExcelTarget("ReportModel") +public class ReportModel extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("history_id") + @Property(value = "历史导入关联id") + private String historyId; + + @TableField("model_code") + @Property(value = "模型code") + private String modelCode; + + @TableField("default_width") + @Property(value = "默认宽度") + @Excel(name = "默认宽度", width = 10, isImportField = "true_st", orderNum = "2") + private String defaultWidth; + + @TableField("default_height") + @Property(value = "默认高度") + @Excel(name = "默认高度", width = 10, isImportField = "true_st", orderNum = "3") + private String defaultHeight; + + @TableField("min_width") + @Property(value = "最小宽度") + @Excel(name = "最小宽度", width = 10, isImportField = "true_st", orderNum = "4") + private String minWidth; + + @TableField("min_height") + @Property(value = "最小高度") + @Excel(name = "最小高度", width = 10, isImportField = "true_st", orderNum = "5") + private String minHeight; + + @TableField("default_bg_color") + @Property(value = "默认背景色") + @Excel(name = "默认背景色", width = 10, isImportField = "true_st", orderNum = "6") + private String defaultBgColor; + + @TableField("bg_transparency") + @Property(value = "透明度") + @Excel(name = "透明度", width = 10, isImportField = "true_st", orderNum = "7") + private String bgTransparency; + + @TableField("logo_path") + @Property(value = "logo地址") + @Excel(name = "LOGO", type = 2, width = 10, isImportField = "true_st", imageType = 1) + private String logoPath; + + @TableField("software_version") + @Property(value = "版本") + private Integer softwareVersion; + + @TableField("state") + @Property(value = "状态,参考#ReportModelState") + private Integer state; + + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModelAttr.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModelAttr.java new file mode 100644 index 0000000..4a0d0b0 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/entity/ReportModelAttr.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.entity; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: ReportModelAttr + * @Description: Echarts报表模型属性 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 16:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "report_model_attr", autoResultMap = true) +@ApiModel("Echarts报表模型属性实体类") +@ExcelTarget("ReportModelAttr") +public class ReportModelAttr extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("report_model_id") + @Property(value = "模型id") + private String reportModelId; + + @TableField("attr_code") + @Property(value = "属性id,也是属性code") + @Excel(name = "属性id", width = 10, isImportField = "true_st", orderNum = "1") + private String attrCode; + + @TableField("type_name") + @Property(value = "属性分类名称") + @Excel(name = "属性分类", width = 10, isImportField = "true_st", orderNum = "2") + private String typeName; + + @TableField("name") + @Property(value = "属性名称") + @Excel(name = "属性名称", width = 10, isImportField = "true_st", orderNum = "3") + private String name; + + @TableField("remark") + @Property(value = "介绍") + @Excel(name = "介绍", width = 10, isImportField = "true_st", orderNum = "4") + private String remark; + + @TableField("default_value") + @Property(value = "默认值") + @Excel(name = "默认值", width = 10, isImportField = "true_st", orderNum = "5") + private String defaultValue; + + @TableField("edit") + @Property(value = "是否可编辑") + @Excel(name = "是否可编辑", width = 10, isImportField = "true_st", replace = {"是_1", "否_2"}, orderNum = "6") + private String edit; + + @TableField("editor_type") + @Property(value = "编辑器") + @Excel(name = "编辑器", width = 10, isImportField = "true_st", replace = {"单选框_1", "输入框_2", "颜色选择器_3", + "数字输入框_4", "多行颜色选择器_5", "下拉框_6", "多选框_7", "滑块_8", "动态数据_9", + "只读的输入框_98", "数据源选择_99"}, orderNum = "7") + private String editorType; + + @TableField("optional_value") + @Property(value = "可选值") + @Excel(name = "可选值", width = 10, isImportField = "true_st", orderNum = "8") + private String optionalValue; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportHistoryService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportHistoryService.java new file mode 100644 index 0000000..792d3e5 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportHistoryService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.echarts.entity.ImportHistory; + +import java.util.Map; + +/** + * @ClassName: ReportImportHistoryService + * @Description: Echarts导入历史服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 14:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportImportHistoryService extends SkyeyeBusinessService { + + void importReportImportModel(InputObject inputObject, OutputObject outputObject); + + void queryAllMaxVersionReportModel(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportModelService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportModelService.java new file mode 100644 index 0000000..42d01c5 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportImportModelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.echarts.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.echarts.entity.ImportModel; + +import java.util.List; + +/** + * @ClassName: ReportImportModelService + * @Description: Echarts模型管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportImportModelService extends SkyeyeBusinessService { + + List queryImportModelList(List modelCodes); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelAttrService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelAttrService.java new file mode 100644 index 0000000..985045e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelAttrService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.echarts.entity.ReportModelAttr; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportModelAttrService + * @Description: Echarts报表模型属性服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 15:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportModelAttrService extends SkyeyeBusinessService { + + Map> queryReportModelAttrMapByModelIds(List reportModelIds); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelService.java new file mode 100644 index 0000000..cbbdaad --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/ReportModelService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.echarts.entity.ReportModel; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportModelService + * @Description: 模型版本服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 15:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportModelService extends SkyeyeBusinessService { + + Integer queryNewMaxVersionByModelCode(String modelCode); + + List queryAllMaxVersionReportModel(); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportHistoryServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportHistoryServiceImpl.java new file mode 100644 index 0000000..d147592 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportHistoryServiceImpl.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service.impl; + +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.FileConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.echarts.classenum.ReportModelState; +import com.skyeye.echarts.dao.ReportImportHistoryDao; +import com.skyeye.echarts.entity.ImportHistory; +import com.skyeye.echarts.entity.ImportModel; +import com.skyeye.echarts.entity.ReportModel; +import com.skyeye.echarts.entity.ReportModelAttr; +import com.skyeye.echarts.service.ReportImportHistoryService; +import com.skyeye.echarts.service.ReportImportModelService; +import com.skyeye.echarts.service.ReportModelAttrService; +import com.skyeye.echarts.service.ReportModelService; +import com.skyeye.eve.centerrest.common.CommonService; +import com.skyeye.exception.CustomException; +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.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportImportHistoryServiceImpl + * @Description: Echarts导入历史服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 14:05 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "Echarts导入历史", groupName = "Echarts导入历史") +public class ReportImportHistoryServiceImpl extends SkyeyeBusinessServiceImpl implements ReportImportHistoryService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReportImportHistoryServiceImpl.class); + + @Autowired + private ReportModelService reportModelService; + + @Autowired + private ReportImportModelService reportImportModelService; + + @Autowired + private ReportModelAttrService reportModelAttrService; + + @Autowired + private CommonService commonService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(ImportHistory::getModelCode), commonPageInfo.getObjectId()); + return queryWrapper; + } + + /** + * 插入模型上传导入历史 + * + * @param name 文件名称 + * @param size 文件大小 + * @param modelCode 模版编码 + * @param userId 用户id + * @return 模型上传导入历史对象 + */ + private String insertReportImportHistory(String name, Long size, String modelCode, String userId) { + ImportHistory importHistory = new ImportHistory(); + importHistory.setName(name); + importHistory.setSize(String.valueOf(size)); + importHistory.setModelCode(modelCode); + return createEntity(importHistory, userId); + } + + /** + * 模型上传导入 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = "transactionManager", rollbackFor = Exception.class) + public void importReportImportModel(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String modelId = map.get("modelId").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + // 将当前上下文初始化给 CommonsMutipartResolver (多部分解析器) + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(PutObject.getRequest().getSession().getServletContext()); + // 检查form中是否有enctype="multipart/form-data" + if (multipartResolver.isMultipart(PutObject.getRequest())) { + // 将request变成多部分request + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) PutObject.getRequest(); + // 获取multiRequest 中所有的文件名 + Iterator iter = multiRequest.getFileNames(); + while (iter.hasNext()) { + MultipartFile file = multiRequest.getFile(iter.next().toString()); + // 读取基本信息 + String reportModelId = saveModelMation(file, modelId, userId); + // 模型属性信息 + saveModelAttrMation(file, reportModelId); + } + } + } + + /** + * 解析并保存模型信息 + * + * @param file 文件 + * @param modelId 模型id + * @param userId 用户id + * @return 模型id + */ + private String saveModelMation(MultipartFile file, String modelId, String userId) { + ImportParams reportModelParams = new ImportParams(); + reportModelParams.setStartSheetIndex(0); + List reportModelList; + try { + reportModelList = ExcelImportUtil.importExcel(file.getInputStream(), ReportModel.class, reportModelParams); + } catch (Exception ee) { + throw new CustomException(ee); + } + if (CollectionUtil.isNotEmpty(reportModelList)) { + ReportModel reportModel = reportModelList.get(0); + Map filePath = ExecuteFeignClient.get(() -> + commonService.queryFilePathByFileType(FileConstants.FileUploadPath.REPORT_IMPORT_HISTORY.getType()[0])).getBean(); + String savePath = filePath.get("savePath").toString(); + String visitPath = filePath.get("visitPath").toString(); + // 设置logo图片 + String newFileName = System.currentTimeMillis() + ".png"; + // 保存 + ToolUtil.NIOCopyFile(reportModel.getLogoPath(), savePath + "/" + newFileName); + FileUtil.deleteFile(reportModel.getLogoPath()); + // 设置可访问路径 + reportModel.setLogoPath(visitPath + newFileName); + ImportModel importModel = reportImportModelService.selectById(modelId); + reportModel.setModelCode(importModel.getModelCode()); + // 插入模型上传导入历史 + String historyId = insertReportImportHistory(file.getOriginalFilename(), file.getSize(), importModel.getModelCode(), userId); + reportModel.setHistoryId(historyId); + + Integer softwareVersion = reportModelService.queryNewMaxVersionByModelCode(importModel.getModelCode()); + reportModel.setSoftwareVersion(softwareVersion); + reportModel.setState(ReportModelState.NORMAL.getKey()); + return reportModelService.createEntity(reportModel, userId); + } + return StrUtil.EMPTY; + } + + /** + * 解析并保存模型属性信息 + * + * @param file 文件 + * @param reportModelId 模型id + */ + private void saveModelAttrMation(MultipartFile file, String reportModelId) { + ImportParams reportModelAttrParams = new ImportParams(); + reportModelAttrParams.setStartSheetIndex(1); + List reportModelAttrList; + try { + reportModelAttrList = ExcelImportUtil.importExcel(file.getInputStream(), ReportModelAttr.class, reportModelAttrParams); + } catch (Exception ee) { + throw new CustomException(ee); + } + reportModelAttrList.forEach(bean -> { + bean.setReportModelId(reportModelId); + }); + reportModelAttrService.createEntity(reportModelAttrList, StrUtil.EMPTY); + } + + /** + * 获取所有版本最大的echarts模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllMaxVersionReportModel(InputObject inputObject, OutputObject outputObject) { + List reportModelList = reportModelService.queryAllMaxVersionReportModel(); + Map reportModelMap = reportModelList.stream().collect(Collectors.toMap(ReportModel::getModelCode, item -> item)); + Map reportModelIdMap = reportModelList.stream().collect(Collectors.toMap(ReportModel::getModelCode, ReportModel::getId)); + + List models = reportImportModelService.queryImportModelList(new ArrayList<>(reportModelIdMap.keySet())); + Map> modelAttrsMap = reportModelAttrService.queryReportModelAttrMapByModelIds(reportModelIdMap.values().stream() + .collect(Collectors.toList())); + models.forEach(model -> { + try { + model.setReportModel(reportModelMap.get(model.getModelCode())); + String reportModelId = reportModelIdMap.get(model.getModelCode()); + List attrs = modelAttrsMap.get(reportModelId); + Map attrsMap = attrs.stream().collect(Collectors.toMap(ReportModelAttr::getAttrCode, item -> item)); + model.setAttr(attrsMap); + } catch (Exception ee) { + LOGGER.warn("queryAllMaxVersionReportModel -> reportModelAttrDao.getReportModelAttrToEditorByModelId failed.", ee); + } + }); + outputObject.setBeans(models); + outputObject.settotal(models.size()); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportModelServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportModelServiceImpl.java new file mode 100644 index 0000000..9df3887 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportImportModelServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.echarts.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.echarts.dao.ReportImportModelDao; +import com.skyeye.echarts.entity.ImportModel; +import com.skyeye.echarts.entity.ReportModel; +import com.skyeye.echarts.service.ReportImportModelService; +import com.skyeye.echarts.service.ReportModelService; +import com.skyeye.exception.CustomException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportImportModelServiceImpl + * @Description: Echarts模型管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "Echarts模型管理", groupName = "Echarts模型管理") +public class ReportImportModelServiceImpl extends SkyeyeBusinessServiceImpl implements ReportImportModelService { + + @Autowired + private ReportModelService reportModelService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + + // 获取最新版本的报表模型 + List reportModelList = reportModelService.queryAllMaxVersionReportModel(); + Map reportModelMap = reportModelList.stream().collect(Collectors.toMap(ReportModel::getModelCode, item -> item)); + beans.forEach(bean -> { + bean.put("reportModel", reportModelMap.get(bean.get("modelCode").toString())); + }); + return beans; + } + + @Override + public void validatorEntity(ImportModel entity) { + super.validatorEntity(entity); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrapper -> + wrapper.eq(MybatisPlusUtil.toColumns(ImportModel::getName), entity.getName()) + .or().eq(MybatisPlusUtil.toColumns(ImportModel::getModelCode), entity.getModelCode())); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + ImportModel checkModel = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(checkModel)) { + throw new CustomException("this `name` OR `modelCode` is exist."); + } + } + + @Override + public List queryImportModelList(List modelCodes) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ImportModel::getModelCode), modelCodes); + List importModels = list(queryWrapper); + iSysDictDataService.setName(importModels, "typeId", "typeName"); + return importModels; + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelAttrServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelAttrServiceImpl.java new file mode 100644 index 0000000..3d58c7e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelAttrServiceImpl.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service.impl; + +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.AnalysisDataToMapUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.echarts.dao.ReportModelAttrDao; +import com.skyeye.echarts.entity.ReportModelAttr; +import com.skyeye.echarts.service.ReportModelAttrService; +import net.sf.json.JSONArray; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportModelAttrServiceImpl + * @Description: Echarts报表模型属性服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 15:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "Echarts报表模型属性", groupName = "Echarts报表模型属性", manageShow = false) +public class ReportModelAttrServiceImpl extends SkyeyeBusinessServiceImpl implements ReportModelAttrService { + + @Override + public Map> queryReportModelAttrMapByModelIds(List reportModelIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ReportModelAttr::getReportModelId), reportModelIds); + queryWrapper.last(String.format("ORDER BY LENGTH(%s) ASC", MybatisPlusUtil.toColumns(ReportModelAttr::getAttrCode))); + List reportModelAttrList = list(queryWrapper); + reportModelAttrList.forEach(reportModelAttr -> { + if (AnalysisDataToMapUtil.isJsonStringArray(reportModelAttr.getDefaultValue())) { + reportModelAttr.setDefaultValue(JSONUtil.toJsonStr(JSONArray.fromObject(reportModelAttr.getDefaultValue()))); + } + }); + return reportModelAttrList.stream().collect(Collectors.groupingBy(ReportModelAttr::getReportModelId)); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelServiceImpl.java new file mode 100644 index 0000000..3e9cf7e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/echarts/service/impl/ReportModelServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.echarts.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.echarts.classenum.ReportModelState; +import com.skyeye.echarts.dao.ReportModelDao; +import com.skyeye.echarts.entity.ReportModel; +import com.skyeye.echarts.service.ReportModelService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ReportModelServiceImpl + * @Description: 模型版本服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/20 15:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "模型版本", groupName = "模型版本", manageShow = false) +public class ReportModelServiceImpl extends SkyeyeBusinessServiceImpl implements ReportModelService { + + @Override + public void createPrepose(ReportModel entity) { + // 将之前的修改为废弃状态 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(ReportModel::getModelCode), entity.getModelCode()); + updateWrapper.set(MybatisPlusUtil.toColumns(ReportModel::getState), ReportModelState.ABANDONED.getKey()); + update(updateWrapper); + } + + /** + * 根据模型code获取一个最新的版本号 + * + * @param modelCode 模型code + * @return 最新的版本号 + */ + @Override + public Integer queryNewMaxVersionByModelCode(String modelCode) { + Integer version = 1; + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportModel::getModelCode), modelCode); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(ReportModel::getSoftwareVersion)); + List list = list(queryWrapper); + if (CollectionUtil.isNotEmpty(list)) { + version = list.get(0).getSoftwareVersion() + 1; + } + return version; + } + + @Override + public List queryAllMaxVersionReportModel() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ReportModel::getState), ReportModelState.NORMAL.getKey()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(ReportModel::getSoftwareVersion)); + List list = list(queryWrapper); + return list; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/img/controller/ReportImgModelController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/img/controller/ReportImgModelController.java new file mode 100644 index 0000000..f03fc5c --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/img/controller/ReportImgModelController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.img.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.img.entity.ImgModel; +import com.skyeye.img.service.ReportImgModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportImgModelController + * @Description: 图片模型控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "图片模型管理", tags = "图片模型管理", modelName = "图片模型管理") +public class ReportImgModelController { + + @Autowired + private ReportImgModelService reportImgModelService; + + /** + * 新增/编辑图片模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeImgModel", value = "新增/编辑图片模型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ImgModel.class) + @RequestMapping("/post/ReportImgModelController/writeImgModel") + public void writeImgModel(InputObject inputObject, OutputObject outputObject) { + reportImgModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 获取图片模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryImgModelList", value = "获取图片模型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportImgModelController/queryImgModelList") + public void queryImgModelList(InputObject inputObject, OutputObject outputObject) { + reportImgModelService.queryPageList(inputObject, outputObject); + } + + /** + * 根据Id删除图片模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteImgModelById", value = "根据Id删除图片模型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportImgModelController/deleteImgModelById") + public void deleteImgModelById(InputObject inputObject, OutputObject outputObject) { + reportImgModelService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有启动的图片模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEnabledImgModelList", value = "获取所有启动的图片模型列表", method = "GET", allUse = "2") + @RequestMapping("/post/ReportImgModelController/queryAllEnabledImgModelList") + public void queryAllEnabledImgModelList(InputObject inputObject, OutputObject outputObject) { + reportImgModelService.queryAllEnabledImgModelList(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/img/dao/ReportImgModelDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/img/dao/ReportImgModelDao.java new file mode 100644 index 0000000..161dc2b --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/img/dao/ReportImgModelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.img.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.img.entity.ImgModel; + +/** + * @ClassName: ReportImgModelDao + * @Description: 图片模型数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/10/21 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportImgModelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/img/entity/ImgModel.java b/skyeye-report/report-pro/src/main/java/com/skyeye/img/entity/ImgModel.java new file mode 100644 index 0000000..36f1761 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/img/entity/ImgModel.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.img.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: ImgModel + * @Description: 图片模型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/25 16:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:img") +@TableName(value = "report_img_model", autoResultMap = true) +@ApiModel("图片模型实体类") +public class ImgModel extends BaseGeneralInfo { + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("img_path") + @ApiModelProperty(value = "图片路径", required = "required") + private String imgPath; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @ApiModelProperty(value = "所属分类名称,数据来自数据字典") + private String typeName; + + @TableField("default_width") + @ApiModelProperty(value = "默认宽度,单位:px", required = "required,num") + private Integer defaultWidth; + + @TableField("default_height") + @ApiModelProperty(value = "默认高度,单位:px", required = "required,num") + private Integer defaultHeight; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/ReportImgModelService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/ReportImgModelService.java new file mode 100644 index 0000000..dee581c --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/ReportImgModelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.img.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.img.entity.ImgModel; + +/** + * @ClassName: ReportImgModelService + * @Description: 图片模型服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportImgModelService extends SkyeyeBusinessService { + + void queryAllEnabledImgModelList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/impl/ReportImgModelServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/impl/ReportImgModelServiceImpl.java new file mode 100644 index 0000000..f75ec4a --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/img/service/impl/ReportImgModelServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.img.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.img.dao.ReportImgModelDao; +import com.skyeye.img.entity.ImgModel; +import com.skyeye.img.service.ReportImgModelService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportImgModelServiceImpl + * @Description: 图片模型服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "图片模型管理", groupName = "图片模型管理") +public class ReportImgModelServiceImpl extends SkyeyeBusinessServiceImpl implements ReportImgModelService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public void queryAllEnabledImgModelList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ImgModel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List imgModels = list(queryWrapper); + iSysDictDataService.setName(imgModels, "typeId", "typeName"); + outputObject.setBeans(imgModels); + outputObject.settotal(imgModels.size()); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/page/controller/ReportPageController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/page/controller/ReportPageController.java new file mode 100644 index 0000000..b133f63 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/page/controller/ReportPageController.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.page.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.page.entity.ReportPage; +import com.skyeye.page.service.ReportPageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportPageController + * @Description: 报表页面信息控制类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/26 17:40 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@RestController +@Api(value = "报表页面", tags = "报表页面", modelName = "报表页面") +public class ReportPageController { + + @Autowired + private ReportPageService reportPageService; + + /** + * 获取报表页面信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportPageList", value = "获取报表页面信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportPageController/queryReportPageList") + public void queryReportPageList(InputObject inputObject, OutputObject outputObject) { + reportPageService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑报表页面 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeReportPage", value = "新增/编辑报表页面", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ReportPage.class) + @RequestMapping("/post/ReportPageController/writeReportPage") + public void writeReportPage(InputObject inputObject, OutputObject outputObject) { + reportPageService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除报表页面信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteReportPageById", value = "删除报表页面信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportPageController/deleteReportPageById") + public void deleteReportPageById(InputObject inputObject, OutputObject outputObject) { + reportPageService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询报表页面信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryReportPageById", value = "根据id查询报表页面信息", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportPageController/queryReportPageById") + public void queryReportPageById(InputObject inputObject, OutputObject outputObject) { + reportPageService.selectById(inputObject, outputObject); + } + + /** + * 编辑报表页面包含的模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editReportPageContentById", value = "编辑报表页面包含的模型信息", method = "POST", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "content", name = "content", value = "报表页面模型对象", required = "json")}) + @RequestMapping("/post/ReportPageController/editReportPageContentById") + public void editReportPageContentById(InputObject inputObject, OutputObject outputObject) { + reportPageService.editReportPageContentById(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/page/dao/ReportPageDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/page/dao/ReportPageDao.java new file mode 100644 index 0000000..b5ffc13 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/page/dao/ReportPageDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.page.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.page.entity.ReportPage; + +/** + * @ClassName: ReportPageDao + * @Description: 报表页面信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/26 17:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportPageDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/page/entity/ReportPage.java b/skyeye-report/report-pro/src/main/java/com/skyeye/page/entity/ReportPage.java new file mode 100644 index 0000000..80e1dac --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/page/entity/ReportPage.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.page.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: ReportPage + * @Description: 报表页面实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/5 10:50 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.REPORT_PAGE_CACHE_KEY) +@TableName(value = "report_page", autoResultMap = true) +@ApiModel("报表页面实体类") +public class ReportPage extends BaseGeneralInfo { + + @TableField(value = "content") + @ApiModelProperty(value = "页面报表json串") + private String content; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/ReportPageService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/ReportPageService.java new file mode 100644 index 0000000..2e83560 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/ReportPageService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.page.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.page.entity.ReportPage; + +/** + * @ClassName: ReportPageService + * @Description: 报表页面信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/26 17:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface ReportPageService extends SkyeyeBusinessService { + + void editReportPageContentById(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/impl/ReportPageServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/impl/ReportPageServiceImpl.java new file mode 100644 index 0000000..6b3cadc --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/page/service/impl/ReportPageServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.page.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.page.dao.ReportPageDao; +import com.skyeye.page.entity.ReportPage; +import com.skyeye.page.service.ReportPageService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +/** + * @ClassName: ReportPageServiceImpl + * @Description: 报表页面信息服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/26 17:44 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "报表页面", groupName = "报表页面") +public class ReportPageServiceImpl extends SkyeyeBusinessServiceImpl implements ReportPageService { + + @Override + protected void updatePrepose(ReportPage entity) { + ReportPage reportPage = selectById(entity.getId()); + entity.setContent(reportPage.getContent()); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editReportPageContentById(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String content = params.get("content").toString(); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(ReportPage::getContent), content); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + updateWrapper.set(MybatisPlusUtil.toColumns(ReportPage::getLastUpdateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(ReportPage::getLastUpdateTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/controller/ReportPropertyController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/controller/ReportPropertyController.java new file mode 100644 index 0000000..f0faadf --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/controller/ReportPropertyController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.property.entity.Property; +import com.skyeye.property.service.ReportPropertyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportPropertyController + * @Description: 模型---样式属性管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:15 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "样式属性管理", tags = "样式属性管理", modelName = "样式属性管理") +public class ReportPropertyController { + + @Autowired + private ReportPropertyService reportPropertyService; + + /** + * 获取模型属性列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportproperty001", value = "获取模型属性列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportPropertyController/queryPropertyList") + public void queryPropertyList(InputObject inputObject, OutputObject outputObject) { + reportPropertyService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑模型属性 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeProperty", value = "新增/编辑模型属性", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Property.class) + @RequestMapping("/post/ReportPropertyController/writeProperty") + public void writeProperty(InputObject inputObject, OutputObject outputObject) { + reportPropertyService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除模型属性 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePropertyById", value = "删除模型属性", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportPropertyController/deletePropertyById") + public void deletePropertyById(InputObject inputObject, OutputObject outputObject) { + reportPropertyService.deleteById(inputObject, outputObject); + } + + /** + * 根据id获取模型属性 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPropertyById", value = "根据id获取模型属性", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportPropertyController/queryPropertyById") + public void queryPropertyById(InputObject inputObject, OutputObject outputObject) { + reportPropertyService.selectById(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyDao.java new file mode 100644 index 0000000..7c38836 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.property.entity.Property; + +/** + * @ClassName: ReportPropertyDao + * @Description: 模型---样式属性管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportPropertyDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyValueDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyValueDao.java new file mode 100644 index 0000000..24d250e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/dao/ReportPropertyValueDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.property.entity.PropertyValue; + +/** + * @ClassName: ReportPropertyValueDao + * @Description: 模型---样式属性值数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportPropertyValueDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/Property.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/Property.java new file mode 100644 index 0000000..dc26550 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/Property.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Property + * @Description: 样式属性实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 20:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:property") +@TableName(value = "report_property", autoResultMap = true) +@ApiModel("样式属性实体类") +public class Property extends BaseGeneralInfo { + + @TableField(value = "attr_code") + @ApiModelProperty(value = "样式属性", required = "required", fuzzyLike = true) + private String attrCode; + + @TableField("editor_type") + @ApiModelProperty(value = "展示类型,参考echarts的展示类型", required = "required,num") + private Integer editorType; + + @TableField(value = "optional") + @ApiModelProperty(value = "属性值是否可选,参考#WhetherEnum", required = "required,num") + private Integer optional; + + @TableField(value = "default_value") + @ApiModelProperty(value = "optional=0时,填写的默认值") + private String defaultValue; + + @TableField(exist = false) + @ApiModelProperty(value = "样式属性值", required = "json") + private List propertyValueList; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/PropertyValue.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/PropertyValue.java new file mode 100644 index 0000000..6d47540 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/entity/PropertyValue.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: PropertyValue + * @Description: 样式属性值实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 20:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "report_property_value", autoResultMap = true) +@ApiModel("样式属性值实体类") +public class PropertyValue extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("property_id") + @com.skyeye.annotation.api.Property(value = "属性id") + private String propertyId; + + @TableField(value = "`name`") + @ApiModelProperty(value = "属性值标题") + private String name; + + @TableField(value = "value") + @ApiModelProperty(value = "属性值", required = "required") + private String value; + + @TableField("default_choose") + @ApiModelProperty(value = "是否是默认值,参考#WhetherEnum", required = "required,num") + private Integer defaultChoose; + + @TableField(value = "order_by") + @com.skyeye.annotation.api.Property(value = "排序") + private Integer orderBy; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyService.java new file mode 100644 index 0000000..38b12ca --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.property.entity.Property; + +/** + * @ClassName: ReportPropertyService + * @Description: 模型---样式属性管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportPropertyService extends SkyeyeBusinessService { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyValueService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyValueService.java new file mode 100644 index 0000000..f570f95 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/ReportPropertyValueService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.property.entity.PropertyValue; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportPropertyValueService + * @Description: 模型---样式属性值服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 20:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ReportPropertyValueService extends SkyeyeBusinessService { + + void deleteByPropertyId(String propertyId); + + void save(String propertyId, List propertyValueList); + + List queryByPropertyId(String propertyId); + + Map> queryByPropertyId(List propertyIds); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyServiceImpl.java new file mode 100644 index 0000000..c694e6d --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyServiceImpl.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.exception.CustomException; +import com.skyeye.property.dao.ReportPropertyDao; +import com.skyeye.property.entity.Property; +import com.skyeye.property.entity.PropertyValue; +import com.skyeye.property.service.ReportPropertyService; +import com.skyeye.property.service.ReportPropertyValueService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportPropertyServiceImpl + * @Description: 模型---样式属性管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "样式属性管理", groupName = "样式属性管理") +public class ReportPropertyServiceImpl extends SkyeyeBusinessServiceImpl implements ReportPropertyService { + + @Autowired + private ReportPropertyValueService reportPropertyValueService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + // 设置属性值 + List ids = beans.stream().filter(property -> Integer.parseInt(property.get("optional").toString()) == WhetherEnum.ENABLE_USING.getKey()) + .map(property -> property.get("id").toString()).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ids)) { + Map> map = reportPropertyValueService.queryByPropertyId(ids); + beans.forEach(property -> { + if (Integer.parseInt(property.get("optional").toString()) == WhetherEnum.ENABLE_USING.getKey()) { + List propertyValueList = map.get(property.get("id").toString()); + PropertyValue defaultProVal = propertyValueList.stream().filter(propertyValue -> propertyValue.getDefaultChoose().equals(WhetherEnum.ENABLE_USING.getKey())) + .findFirst().orElse(new PropertyValue()); + property.put("defaultValue", defaultProVal.getValue()); + } + }); + } + return beans; + } + + @Override + public void validatorEntity(Property entity) { + super.validatorEntity(entity); + // 当optional=1时, 需要解析 propertyValueList. 当optional=0时, defaultValue为必填 + if (entity.getOptional().equals(WhetherEnum.DISABLE_USING.getKey())) { + if (StrUtil.isEmpty(entity.getDefaultValue())) { + throw new CustomException("标识属性值为不可选时, 属性默认值必填"); + } + } + } + + @Override + public void writePostpose(Property entity, String userId) { + super.writePostpose(entity, userId); + // 当optional=1时, 需要解析 propertyValueList. 当optional=0时, defaultValue为必填 + if (entity.getOptional().equals(WhetherEnum.ENABLE_USING.getKey())) { + reportPropertyValueService.save(entity.getId(), entity.getPropertyValueList()); + } + } + + @Override + public Property getDataFromDb(String id) { + Property property = super.getDataFromDb(id); + if (property.getOptional().equals(WhetherEnum.ENABLE_USING.getKey())) { + List propertyValueList = reportPropertyValueService.queryByPropertyId(id); + PropertyValue defaultProVal = propertyValueList.stream().filter(propertyValue -> propertyValue.getDefaultChoose().equals(WhetherEnum.ENABLE_USING.getKey())) + .findFirst().orElse(new PropertyValue()); + property.setPropertyValueList(propertyValueList); + property.setDefaultValue(defaultProVal.getValue()); + } + return property; + } + + @Override + public List getDataFromDb(List idList) { + List propertyList = super.getDataFromDb(idList); + + // 设置属性值 + List ids = propertyList.stream().filter(property -> property.getOptional().equals(WhetherEnum.ENABLE_USING.getKey())) + .map(Property::getId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ids)) { + Map> map = reportPropertyValueService.queryByPropertyId(ids); + propertyList.forEach(property -> { + if (property.getOptional().equals(WhetherEnum.ENABLE_USING.getKey())) { + List propertyValueList = map.get(property.getId()); + PropertyValue defaultProVal = propertyValueList.stream().filter(propertyValue -> propertyValue.getDefaultChoose().equals(WhetherEnum.ENABLE_USING.getKey())) + .findFirst().orElse(new PropertyValue()); + property.setPropertyValueList(propertyValueList); + property.setDefaultValue(defaultProVal.getValue()); + } + }); + } + + return propertyList; + } + + @Override + public void deletePostpose(Property entity) { + if (entity.getOptional().equals(WhetherEnum.ENABLE_USING.getKey())) { + reportPropertyValueService.deleteByPropertyId(entity.getId()); + } + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyValueServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyValueServiceImpl.java new file mode 100644 index 0000000..747bb00 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/property/service/impl/ReportPropertyValueServiceImpl.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.property.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.property.dao.ReportPropertyValueDao; +import com.skyeye.property.entity.PropertyValue; +import com.skyeye.property.service.ReportPropertyValueService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportPropertyValueServiceImpl + * @Description: 模型---样式属性值服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 20:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "样式属性值管理", groupName = "样式属性管理", manageShow = false) +public class ReportPropertyValueServiceImpl extends SkyeyeBusinessServiceImpl implements ReportPropertyValueService { + + @Override + public void deleteByPropertyId(String propertyId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PropertyValue::getPropertyId), propertyId); + remove(queryWrapper); + } + + @Override + public void save(String propertyId, List propertyValueList) { + deleteByPropertyId(propertyId); + if (CollectionUtil.isNotEmpty(propertyValueList)) { + Boolean hasChooseFlag = false; + Integer orderBy = 1; + for (PropertyValue propertyValue : propertyValueList) { + propertyValue.setPropertyId(propertyId); + if (!hasChooseFlag) { + // 还没有设置默认值 + if (WhetherEnum.ENABLE_USING.getKey().equals(propertyValue.getDefaultChoose())) { + // 是默认值 + hasChooseFlag = true; + } + } else { + propertyValue.setDefaultChoose(WhetherEnum.DISABLE_USING.getKey()); + } + propertyValue.setOrderBy(orderBy); + orderBy++; + } + createEntity(propertyValueList, StrUtil.EMPTY); + } + } + + @Override + public List queryByPropertyId(String propertyId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PropertyValue::getPropertyId), propertyId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(PropertyValue::getOrderBy)); + List propertyValueList = list(queryWrapper); + return propertyValueList; + } + + @Override + public Map> queryByPropertyId(List propertyIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(PropertyValue::getPropertyId), propertyIds); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(PropertyValue::getOrderBy)); + List propertyValueList = list(queryWrapper); + return propertyValueList.stream().collect(Collectors.groupingBy(PropertyValue::getPropertyId)); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java new file mode 100644 index 0000000..0a5edb8 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolFactory.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool; + +/** + * @ClassName: DataSourcePoolFactory + * @Description: 数据源连接池工厂 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DataSourcePoolFactory { + public static DataSourcePoolWrapper create(final String className) { + try { + return (DataSourcePoolWrapper) Class.forName(className).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + throw new RuntimeException("DataSourcePoolFactory Load Class Error", e); + } + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java new file mode 100644 index 0000000..ece3448 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/DataSourcePoolWrapper.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool; + +import com.skyeye.eve.entity.ReportDataSource; + +import javax.sql.DataSource; + +/** + * @ClassName: DataSourcePoolWrapper + * @Description: 数据源连接包装器 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface DataSourcePoolWrapper { + + DataSource wrap(ReportDataSource rptDs); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java new file mode 100644 index 0000000..d0457cb --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/C3p0DataSourcePool.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.mchange.v2.c3p0.ComboPooledDataSource; +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import org.apache.commons.collections4.MapUtils; + +import javax.sql.DataSource; + +/** + * @ClassName: C3p0DataSourcePool + * @Description: c3p0数据源连接池包装类--参考http://www.mchange.com/projects/c3p0/#quickstart + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class C3p0DataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(ReportDataSource rptDs) { + try { + ComboPooledDataSource dataSource = new ComboPooledDataSource(); + dataSource.setDriverClass(rptDs.getDriverClass()); + dataSource.setJdbcUrl(rptDs.getJdbcUrl()); + dataSource.setUser(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialPoolSize(MapUtils.getInteger(rptDs.getOptions(), "initialPoolSize", 3)); + dataSource.setMinPoolSize(MapUtils.getInteger(rptDs.getOptions(), "minPoolSize", 1)); + dataSource.setMaxPoolSize(MapUtils.getInteger(rptDs.getOptions(), "maxPoolSize", 20)); + dataSource.setMaxStatements(MapUtils.getInteger(rptDs.getOptions(), "maxStatements", 50)); + dataSource.setMaxIdleTime(MapUtils.getInteger(rptDs.getOptions(), "maxIdleTime", 1800)); + dataSource.setAcquireIncrement(MapUtils.getInteger(rptDs.getOptions(), "acquireIncrement", 3)); + dataSource.setAcquireRetryAttempts(MapUtils.getInteger(rptDs.getOptions(), "acquireRetryAttempts", 30)); + dataSource.setIdleConnectionTestPeriod( + MapUtils.getInteger(rptDs.getOptions(), "idleConnectionTestPeriod", 60)); + dataSource.setBreakAfterAcquireFailure( + MapUtils.getBoolean(rptDs.getOptions(), "breakAfterAcquireFailure", false)); + dataSource.setTestConnectionOnCheckout( + MapUtils.getBoolean(rptDs.getOptions(), "testConnectionOnCheckout", false)); + return dataSource; + } catch (Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java new file mode 100644 index 0000000..b59c307 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DBCP2DataSourcePool.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.dbcp2.BasicDataSource; + +import javax.sql.DataSource; + +/** + * @ClassName: DBCP2DataSourcePool + * @Description: c3p0数据源连接池包装类---参考http://www.mchange.com/projects/c3p0/#quickstart + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DBCP2DataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(ReportDataSource rptDs) { + try { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(rptDs.getDriverClass()); + dataSource.setUrl(rptDs.getJdbcUrl()); + dataSource.setUsername(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialSize(MapUtils.getInteger(rptDs.getOptions(), "initialSize", 3)); + dataSource.setMaxIdle(MapUtils.getInteger(rptDs.getOptions(), "maxIdle", 20)); + dataSource.setMinIdle(MapUtils.getInteger(rptDs.getOptions(), "minIdle", 1)); + dataSource.setLogAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "logAbandoned", true)); + dataSource.setRemoveAbandonedTimeout( + MapUtils.getInteger(rptDs.getOptions(), "removeAbandonedTimeout", 180)); + dataSource.setMaxWaitMillis(MapUtils.getInteger(rptDs.getOptions(), "maxWait", 1000)); + return dataSource; + } catch (final Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java new file mode 100644 index 0000000..b892497 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/DruidDataSourcePool.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.alibaba.druid.pool.DruidDataSource; +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; +import org.apache.commons.collections4.MapUtils; + +import javax.sql.DataSource; + +/** + * @ClassName: DruidDataSourcePool + * @Description: Druid数据源连接池包装类--参考https://github.com/alibaba/druid/wiki + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:08 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class DruidDataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(ReportDataSource rptDs) { + try { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setDriverClassName(rptDs.getDriverClass()); + dataSource.setUrl(rptDs.getJdbcUrl()); + dataSource.setUsername(rptDs.getUser()); + dataSource.setPassword(rptDs.getPassword()); + dataSource.setInitialSize(MapUtils.getInteger(rptDs.getOptions(), "initialSize", 3)); + dataSource.setMaxActive(MapUtils.getInteger(rptDs.getOptions(), "maxActive", 20)); + dataSource.setMinIdle(MapUtils.getInteger(rptDs.getOptions(), "minIdle", 1)); + dataSource.setMaxWait(MapUtils.getInteger(rptDs.getOptions(), "maxWait", 60000)); + dataSource.setTimeBetweenEvictionRunsMillis( + MapUtils.getInteger(rptDs.getOptions(), "timeBetweenEvictionRunsMillis", 60000)); + dataSource.setMinEvictableIdleTimeMillis( + MapUtils.getInteger(rptDs.getOptions(), "minEvictableIdleTimeMillis", 300000)); + dataSource.setTestWhileIdle(MapUtils.getBoolean(rptDs.getOptions(), "testWhileIdle", true)); + dataSource.setTestOnBorrow(MapUtils.getBoolean(rptDs.getOptions(), "testOnBorrow", false)); + dataSource.setTestOnReturn(MapUtils.getBoolean(rptDs.getOptions(), "testOnReturn", false)); + dataSource.setMaxOpenPreparedStatements( + MapUtils.getInteger(rptDs.getOptions(), "maxOpenPreparedStatements", 20)); + dataSource.setRemoveAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "removeAbandoned", true)); + dataSource.setRemoveAbandonedTimeout( + MapUtils.getInteger(rptDs.getOptions(), "removeAbandonedTimeout", 1800)); + dataSource.setLogAbandoned(MapUtils.getBoolean(rptDs.getOptions(), "logAbandoned", true)); + return dataSource; + } catch (final Exception ex) { + throw new RuntimeException("C3p0DataSourcePool Create Error", ex); + } + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java new file mode 100644 index 0000000..84ea355 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/dbpool/impl/NoDataSourcePool.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.dbpool.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolWrapper; + +import javax.sql.DataSource; +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; + +/** + * @ClassName: NoDataSourcePool + * @Description: 无数据源连接池, 直接使用jdbc连接 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:09 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class NoDataSourcePool implements DataSourcePoolWrapper { + + @Override + public DataSource wrap(ReportDataSource rptDs) { + return new NoDataSource(rptDs); + } + + private static class NoDataSource implements DataSource { + private ReportDataSource reportDataSource; + + public NoDataSource(ReportDataSource reportDataSource) { + this.reportDataSource = reportDataSource; + } + + @Override + public Connection getConnection() throws SQLException { + return DriverManager.getConnection( + this.reportDataSource.getJdbcUrl(), + this.reportDataSource.getUser(), + this.reportDataSource.getPassword()); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return null; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + @Override + public PrintWriter getLogWriter() throws SQLException { + return null; + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + + } + + @Override + public int getLoginTimeout() throws SQLException { + return 0; + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java new file mode 100644 index 0000000..d7af526 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/AbstractQueryer.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query; + +import com.skyeye.eve.entity.*; +import com.skyeye.exception.CustomException; +import com.skyeye.util.JdbcUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: AbstractQueryer + * @Description: 数据库查询父类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/30 0:29 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public abstract class AbstractQueryer { + protected Logger logger = LoggerFactory.getLogger(this.getClass()); + protected ReportDataSource dataSource; + + protected AbstractQueryer(ReportDataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * 获取sql查询出来的所有列 + * + * @param sqlText sql语句 + * @return + */ + public List parseMetaDataColumns(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + try { + this.logger.debug("Parse Report MetaDataColumns SQL:{},", sqlText); + // 创建连接 + conn = this.getJdbcConnection(); + // 创建通讯 + stmt = conn.createStatement(); + // 执行sql + rs = stmt.executeQuery(this.preprocessSqlText(sqlText)); + // 获取列 + List columns = getReportMetaDataColumns(rs); + return columns; + } catch (SQLException ex) { + throw new CustomException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + } + + private List getReportMetaDataColumns(ResultSet rs) throws SQLException { + // 获取结果 + ResultSetMetaData rsMataData = rs.getMetaData(); + int count = rsMataData.getColumnCount(); + List columns = new ArrayList<>(count); + for (int i = 1; i <= count; i++) { + ReportMetaDataColumn column = new ReportMetaDataColumn(); + column.setName(rsMataData.getColumnLabel(i)); + column.setDataType(rsMataData.getColumnTypeName(i)); + column.setWidth(rsMataData.getColumnDisplaySize(i)); + columns.add(column); + } + return columns; + } + + public List parseQueryParamItems(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + HashSet set = new HashSet<>(); + List rows = new ArrayList<>(); + + try { + this.logger.debug(sqlText); + conn = this.getJdbcConnection(); + stmt = conn.createStatement(); + rs = stmt.executeQuery(sqlText); + while (rs.next()) { + String name = rs.getString("name"); + String text = rs.getString("text"); + name = (name == null) ? "" : name.trim(); + text = (text == null) ? "" : text.trim(); + if (!set.contains(name)) { + set.add(name); + } + rows.add(new ReportQueryParamItem(name, text)); + } + } catch (SQLException ex) { + throw new RuntimeException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + set.clear(); + return rows; + } + + public List getMetaDataRows(String sqlText) { + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + try { + // 创建连接 + conn = this.getJdbcConnection(); + // 创建通讯 + stmt = conn.createStatement(); + // 执行sql + rs = stmt.executeQuery(sqlText); + return this.getMetaDataRows(rs, this.getSqlColumns(this.getReportMetaDataColumns(rs))); + } catch (Exception ex) { + logger.warn(String.format("SqlText:{},Msg is: ", sqlText, ex)); + throw new CustomException(ex); + } finally { + JdbcUtils.releaseJdbcResource(conn, stmt, rs); + } + } + + protected List getMetaDataRows(ResultSet rs, List sqlColumns) + throws SQLException { + List rows = new ArrayList<>(); + + while (rs.next()) { + ReportMetaDataRow row = new ReportMetaDataRow(); + for (ReportMetaDataColumn column : sqlColumns) { + Object value = rs.getObject(column.getName()); + if (column.getDataType().contains("BINARY")) { + value = new String((byte[]) value); + } + row.add(new ReportMetaDataCell(column, column.getName(), value)); + } + rows.add(row); + } + return rows; + } + + protected List getSqlColumns(List metaDataColumns) { + return metaDataColumns.stream() + .filter(x -> x.getType() != ColumnType.COMPUTED) + .collect(Collectors.toList()); + } + + /** + * 预处理获取报表列集合的sql语句, + * 在这里可以拦截全表查询等sql, 因为如果表的数据量很大,将会产生过多的内存消耗,甚至性能问题 + * + * @param sqlText 原sql语句 + * @return 预处理后的sql语句 + */ + protected String preprocessSqlText(String sqlText) { + return sqlText; + } + + /** + * 获取当前报表查询器的JDBC Connection对象 + * + * @return Connection + */ + protected Connection getJdbcConnection() { + try { + Class.forName(this.dataSource.getDriverClass()); + return JdbcUtils.getDataSource(this.dataSource).getConnection(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/Queryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/Queryer.java new file mode 100644 index 0000000..4fef630 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/Queryer.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query; + +import com.skyeye.eve.entity.ReportMetaDataColumn; +import com.skyeye.eve.entity.ReportMetaDataRow; +import com.skyeye.eve.entity.ReportQueryParamItem; + +import java.util.List; + +/** + * @ClassName: Queryer + * @Description: 报表查询器接口 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface Queryer { + /** + * 从sql语句中解析出报表元数据列集合 + * + * @param sqlText sql语句 + * @return List[ReportMetaDataColumn] + */ + List parseMetaDataColumns(String sqlText); + + /** + * 从sql语句中解析出报表查询参数(如下拉列表参数)的列表项集合 + * + * @param sqlText sql语句 + * @return List[ReportQueryParamItem] + */ + List parseQueryParamItems(String sqlText); + + /** + * 获取报表原始数据行集合 + * + * @param sqlText sql语句 + * @return + */ + List getMetaDataRows(String sqlText); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java new file mode 100644 index 0000000..ba7d3af --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/factory/QueryerFactory.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.factory; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.Queryer; + +import java.lang.reflect.Constructor; + +/** + * @ClassName: QueryerFactory + * @Description: 报表查询器工厂方法类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:24 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class QueryerFactory { + + public static Queryer create(ReportDataSource dataSource) { + if (dataSource != null) { + try { + Class clazz = Class.forName(dataSource.getQueryerClass()); + Constructor constructor = clazz.getConstructor(ReportDataSource.class); + return (Queryer) constructor.newInstance(dataSource); + } catch (final Exception ex) { + throw new RuntimeException("create report engine queryer error", ex); + } + } + return null; + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java new file mode 100644 index 0000000..5d81a42 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/MySqlQueryer.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @ClassName: MySqlQueryer + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class MySqlQueryer extends AbstractQueryer implements Queryer { + + public MySqlQueryer(ReportDataSource dataSource) { + super(dataSource); + } + + @Override + protected String preprocessSqlText(String sqlText) { + sqlText = StringUtils.stripEnd(sqlText.trim(), ";"); + Pattern pattern = Pattern.compile("limit.*?$", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(sqlText); + if (matcher.find()) { + sqlText = matcher.replaceFirst(""); + } + return sqlText + " limit 1"; + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java new file mode 100644 index 0000000..7d71355 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/OracleQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: OracleQueryer + * @Description: Oracle数据库查询器类。 + * 在使用该查询器时,请先参考:http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html + * 获取与相应版本的Oracle jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class OracleQueryer extends AbstractQueryer implements Queryer { + + public OracleQueryer(ReportDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java new file mode 100644 index 0000000..102883e --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/PostgresqlQueryer.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: PostgresqlQueryer + * @Description: Postgresql数据库查询器类。 + * 在使用该查询器时,请先参考:https://jdbc.postgresql.org/download.html + * 获取与相应版本的Postgresql jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class PostgresqlQueryer extends AbstractQueryer implements Queryer { + public PostgresqlQueryer(ReportDataSource dataSource) { + super(dataSource); + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java new file mode 100644 index 0000000..6c93e36 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SQLiteQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: SQLiteQueryer + * @Description: SQLite3数据库查询器类。 + * 在使用该查询器时,请先参考:https://bitbucket.org/xerial/sqlite-jdbc + * 获取jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class SQLiteQueryer extends AbstractQueryer implements Queryer { + + public SQLiteQueryer(ReportDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java new file mode 100644 index 0000000..68c31ca --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/sql/query/impl/SqlServerQueryer.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.sql.query.impl; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.query.AbstractQueryer; +import com.skyeye.sql.query.Queryer; + +/** + * @ClassName: SqlServerQueryer + * @Description: MS SQLServer 数据库查询器类。 + * 在使用该查询器时,请先参考:https://msdn.microsoft.com/library/mt484311.aspx + * 获取sqlserver jdbc driver,然后把相关jdbc driver的jar包加入该系统的类路径下(如WEB-INF/lib) + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class SqlServerQueryer extends AbstractQueryer implements Queryer { + + public SqlServerQueryer(ReportDataSource dataSource) { + super(dataSource); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/util/JdbcUtils.java b/skyeye-report/report-pro/src/main/java/com/skyeye/util/JdbcUtils.java new file mode 100644 index 0000000..87fa122 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/util/JdbcUtils.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye-report + ******************************************************************************/ + +package com.skyeye.util; + +import com.skyeye.eve.entity.ReportDataSource; +import com.skyeye.sql.dbpool.DataSourcePoolFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @ClassName: JdbcUtils + * @Description: Jdbc工具类 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/17 21:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public class JdbcUtils { + private static Logger logger = LoggerFactory.getLogger(JdbcUtils.class); + private static Map dataSourceMap = new ConcurrentHashMap<>(100); + + public static DataSource getDataSource(ReportDataSource rptDs) { + // 用数据源用户名,密码,jdbcUrl做为key + String key = String.format("%s|%s|%s", rptDs.getUser(), rptDs.getPassword(), rptDs.getJdbcUrl()) + .toLowerCase(); + DataSource dataSource = dataSourceMap.get(key); + if (dataSource == null) { + dataSource = DataSourcePoolFactory.create(rptDs.getDbPoolClass()).wrap(rptDs); + dataSourceMap.put(key, dataSource); + } + return dataSource; + } + + public static void releaseJdbcResource(Connection conn, Statement stmt, ResultSet rs) { + try { + if (stmt != null) { + stmt.close(); + } + if (rs != null) { + rs.close(); + } + if (conn != null) { + conn.close(); + } + } catch (final SQLException ex) { + logger.error("数据库资源释放异常", ex); + throw new RuntimeException("数据库资源释放异常", ex); + } + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/util/XmlExercise.java b/skyeye-report/report-pro/src/main/java/com/skyeye/util/XmlExercise.java new file mode 100644 index 0000000..1458d61 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/util/XmlExercise.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.util; + +import org.json.JSONObject; +import org.json.XML; + +/** + * @ClassName: XmlExercise + * @Description: Xml、json之间的相互转换工具类 + * @author: skyeye云系列--卫志强 + * @date: 2021/6/26 11:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class XmlExercise { + + /** + * 将xml字符串转换为JSON字符串 + * + * @param xmlString xml字符串 + * @return JSON对象 + */ + public static String xml2json(String xmlString) { + JSONObject xmlJSONObj = XML.toJSONObject(xmlString); + return xmlJSONObj.toString(); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/controller/ReportWordModelController.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/controller/ReportWordModelController.java new file mode 100644 index 0000000..0c19cae --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/controller/ReportWordModelController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.word.entity.WordModel; +import com.skyeye.word.service.ReportWordModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ReportWordModelController + * @Description: 文字模型管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "文字模型管理", tags = "文字模型管理", modelName = "文字模型管理") +public class ReportWordModelController { + + @Autowired + private ReportWordModelService reportWordModelService; + + /** + * 获取文字模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reportwordmodel001", value = "获取文字模型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ReportWordModelController/getReportWordModelList") + public void getReportWordModelList(InputObject inputObject, OutputObject outputObject) { + reportWordModelService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑文字模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWordModel", value = "新增/编辑文字模型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WordModel.class) + @RequestMapping("/post/ReportWordModelController/writeWordModel") + public void writeWordModel(InputObject inputObject, OutputObject outputObject) { + reportWordModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据Id删除文字模型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWordModelById", value = "根据Id删除文字模型", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportWordModelController/deleteWordModelById") + public void deleteWordModelById(InputObject inputObject, OutputObject outputObject) { + reportWordModelService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询文字模型信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryWordModelById", value = "根据id查询文字模型信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ReportWordModelController/queryWordModelById") + public void queryWordModelById(InputObject inputObject, OutputObject outputObject) { + reportWordModelService.selectById(inputObject, outputObject); + } + + /** + * 获取所有启用的文字模型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "getEnabledWordModelList", value = "获取所有启用的文字模型列表", method = "GET", allUse = "2") + @RequestMapping("/post/ReportWordModelController/getEnabledWordModelList") + public void getEnabledWordModelList(InputObject inputObject, OutputObject outputObject) { + reportWordModelService.getEnabledWordModelList(inputObject, outputObject); + } + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelAttrDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelAttrDao.java new file mode 100644 index 0000000..88d7bf2 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelAttrDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.word.entity.WordModelAttr; + +/** + * @ClassName: ReportWordModelAttrDao + * @Description: 文字模型属性管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportWordModelAttrDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelDao.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelDao.java new file mode 100644 index 0000000..2116509 --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/dao/ReportWordModelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.word.entity.WordModel; + +/** + * @ClassName: ReportWordModelDao + * @Description: 文字模型管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportWordModelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModel.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModel.java new file mode 100644 index 0000000..b194e1c --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModel.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WordModel + * @Description: 文字模型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/25 16:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "report:word") +@TableName(value = "report_word_model", autoResultMap = true) +@ApiModel("文字模型实体类") +public class WordModel extends BaseGeneralInfo { + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("img_path") + @ApiModelProperty(value = "图片路径", required = "required") + private String imgPath; + + @TableField(value = "type_id") + @ApiModelProperty(value = "所属分类ID,数据来自数据字典", required = "required") + private String typeId; + + @TableField(exist = false) + @ApiModelProperty(value = "所属分类名称,数据来自数据字典") + private String typeName; + + @TableField("default_width") + @ApiModelProperty(value = "默认宽度,单位:px", required = "required,num") + private Integer defaultWidth; + + @TableField("default_height") + @ApiModelProperty(value = "默认高度,单位:px", required = "required,num") + private Integer defaultHeight; + + @TableField(exist = false) + @ApiModelProperty(value = "文字模型属性", required = "required,json") + private List wordModelAttrList; + + @TableField(exist = false) + @Property("自定义属性") + private Map customAttr; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModelAttr.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModelAttr.java new file mode 100644 index 0000000..8dd08dd --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/entity/WordModelAttr.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: WordModelAttr + * @Description: 文字模型属性实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 15:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "report_word_model_attr", autoResultMap = true) +@ApiModel("文字模型属性实体类") +public class WordModelAttr extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("word_id") + @Property(value = "文字模型id") + private String wordId; + + @TableField("property_id") + @ApiModelProperty(value = "属性id", required = "required") + private String propertyId; + + @TableField(exist = false) + @Property(value = "属性信息") + private com.skyeye.property.entity.Property propertyMation; + + @TableField("editor") + @ApiModelProperty(value = "是否可编辑,参考#WhetherEnum", required = "required,num") + private Integer editor; + + @TableField("show_to_editor") + @ApiModelProperty(value = "是否显示在编辑框,参考#WhetherEnum", required = "required,num") + private Integer showToEditor; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelAttrService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelAttrService.java new file mode 100644 index 0000000..06bcd4b --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelAttrService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.word.entity.WordModelAttr; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ReportWordModelAttrService + * @Description: 文字模型属性管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 15:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ReportWordModelAttrService extends SkyeyeBusinessService { + + void deleteByWordId(String wordId); + + void save(String wordId, List wordModelAttrList); + + List queryByWordId(String wordId); + + Map> queryByWordId(List wordIds); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelService.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelService.java new file mode 100644 index 0000000..79e06ab --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/ReportWordModelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.word.entity.WordModel; + +/** + * @ClassName: ReportWordModelService + * @Description: 文字模型管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ReportWordModelService extends SkyeyeBusinessService { + + void getEnabledWordModelList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelAttrServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelAttrServiceImpl.java new file mode 100644 index 0000000..094a7fe --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelAttrServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.word.dao.ReportWordModelAttrDao; +import com.skyeye.word.entity.WordModelAttr; +import com.skyeye.word.service.ReportWordModelAttrService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportWordModelAttrServiceImpl + * @Description: 文字模型属性管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/2/26 15:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "文字模型属性管理", groupName = "文字模型管理", manageShow = false) +public class ReportWordModelAttrServiceImpl extends SkyeyeBusinessServiceImpl implements ReportWordModelAttrService { + + @Override + public void deleteByWordId(String wordId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WordModelAttr::getWordId), wordId); + remove(queryWrapper); + } + + @Override + public void save(String wordId, List wordModelAttrList) { + deleteByWordId(wordId); + if (CollectionUtil.isNotEmpty(wordModelAttrList)) { + wordModelAttrList.forEach(wordModelAttr -> { + wordModelAttr.setWordId(wordId); + }); + createEntity(wordModelAttrList, StrUtil.EMPTY); + } + } + + @Override + public List queryByWordId(String wordId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WordModelAttr::getWordId), wordId); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(WordModelAttr::getOrderBy)); + List wordModelAttrList = list(queryWrapper); + return wordModelAttrList; + } + + @Override + public Map> queryByWordId(List wordIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(WordModelAttr::getWordId), wordIds); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(WordModelAttr::getOrderBy)); + List wordModelAttrList = list(queryWrapper); + return wordModelAttrList.stream().collect(Collectors.groupingBy(WordModelAttr::getWordId)); + } +} diff --git a/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelServiceImpl.java b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelServiceImpl.java new file mode 100644 index 0000000..7858add --- /dev/null +++ b/skyeye-report/report-pro/src/main/java/com/skyeye/word/service/impl/ReportWordModelServiceImpl.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.word.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.FileUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.property.service.ReportPropertyService; +import com.skyeye.word.dao.ReportWordModelDao; +import com.skyeye.word.entity.WordModel; +import com.skyeye.word.entity.WordModelAttr; +import com.skyeye.word.service.ReportWordModelAttrService; +import com.skyeye.word.service.ReportWordModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ReportWordModelServiceImpl + * @Description: 文字模型管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/9/5 16:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "文字模型管理", groupName = "文字模型管理") +public class ReportWordModelServiceImpl extends SkyeyeBusinessServiceImpl implements ReportWordModelService { + + @Autowired + private ReportWordModelAttrService reportWordModelAttrService; + + @Autowired + private ReportPropertyService reportPropertyService; + + @Value("${IMAGES_PATH}") + private String tPath; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "typeId", "typeName"); + return beans; + } + + @Override + public void writePostpose(WordModel entity, String userId) { + super.writePostpose(entity, userId); + reportWordModelAttrService.save(entity.getId(), entity.getWordModelAttrList()); + } + + @Override + public void deletePostpose(WordModel entity) { + String basePath = tPath.replace("images", StrUtil.EMPTY); + FileUtil.deleteFile(basePath + entity.getImgPath()); + // 删除属性 + reportWordModelAttrService.deleteByWordId(entity.getId()); + } + + @Override + public WordModel getDataFromDb(String id) { + WordModel wordModel = super.getDataFromDb(id); + // 设置模型属性 + wordModel.setWordModelAttrList(reportWordModelAttrService.queryByWordId(id)); + return wordModel; + } + + @Override + public WordModel selectById(String id) { + WordModel wordModel = super.selectById(id); + reportPropertyService.setDataMation(wordModel.getWordModelAttrList(), WordModelAttr::getPropertyId); + wordModel.setCustomAttr(getEditFontTextAttr(id)); + return wordModel; + } + + private Map getEditFontTextAttr(String modelId) { + Map item = new HashMap<>(); + item.put("editorType", 2); + item.put("attrCode", "custom.textContent"); + item.put("modelId", modelId); + item.put("edit", 1); + item.put("typeName", "Style属性"); + item.put("name", "文字"); + item.put("defaultValue", "Hello, Skyeye."); + // 是否显示在编辑框 + item.put("remark", "显示内容"); + return item; + } + + @Override + public List getDataFromDb(List idList) { + List wordModelList = super.getDataFromDb(idList); + // 设置模型属性 + Map> wordModelAttrMap = reportWordModelAttrService.queryByWordId(idList); + wordModelList.forEach(wordModel -> { + wordModel.setWordModelAttrList(wordModelAttrMap.get(wordModel.getId())); + }); + return wordModelList; + } + + @Override + public List selectByIds(String... ids) { + List wordModelList = super.selectByIds(ids); + wordModelList.forEach(wordModel -> { + reportPropertyService.setDataMation(wordModel.getWordModelAttrList(), WordModelAttr::getPropertyId); + wordModel.setCustomAttr(getEditFontTextAttr(wordModel.getId())); + }); + return wordModelList; + } + + @Override + public void getEnabledWordModelList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WordModel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.select(CommonConstants.ID); + List wordModelList = list(queryWrapper); + + List ids = wordModelList.stream().map(WordModel::getId).collect(Collectors.toList()); + List wordModels = selectByIds(ids.toArray(new String[]{})); + iSysDictDataService.setName(wordModels, "typeId", "typeName"); + outputObject.setBeans(wordModels); + outputObject.settotal(wordModels.size()); + } + +} diff --git a/skyeye-report/report-web/.gitignore b/skyeye-report/report-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-report/report-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-report/report-web/pom.xml b/skyeye-report/report-web/pom.xml new file mode 100644 index 0000000..aa79a8d --- /dev/null +++ b/skyeye-report/report-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-report + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + report-web + + + 8 + 8 + + + + + + + com.skyeye + report-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-report/report-web/src/main/java/com/SkyReportApplication.java b/skyeye-report/report-web/src/main/java/com/SkyReportApplication.java new file mode 100644 index 0000000..d8d6057 --- /dev/null +++ b/skyeye-report/report-web/src/main/java/com/SkyReportApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class SkyReportApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyReportApplication.class, args); + } + +} diff --git a/skyeye-report/report-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-report/report-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..a3d20f1 --- /dev/null +++ b/skyeye-report/report-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-report/report-web/src/main/resources/banner.txt b/skyeye-report/report-web/src/main/resources/banner.txt new file mode 100644 index 0000000..e1b7251 --- /dev/null +++ b/skyeye-report/report-web/src/main/resources/banner.txt @@ -0,0 +1,34 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 +*/ \ No newline at end of file diff --git a/skyeye-report/report-web/src/main/resources/bootstrap.yml b/skyeye-report/report-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..15ad734 --- /dev/null +++ b/skyeye-report/report-web/src/main/resources/bootstrap.yml @@ -0,0 +1,47 @@ +server: + port: 8085 + +spring: + application: + name: skyeye-report-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + +webroot: + # 总工程服务 + skyeye-pro: skyeye-pro-${spring.profiles.active} diff --git a/skyeye-report/report-web/src/main/resources/jvm调优参数配置 b/skyeye-report/report-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-report/report-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-report/report-web/src/main/resources/log4j.properties b/skyeye-report/report-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-report/report-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-seal-service/.gitignore b/skyeye-seal-service/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-seal-service/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-seal-service/pom.xml b/skyeye-seal-service/pom.xml new file mode 100644 index 0000000..2d6ccc8 --- /dev/null +++ b/skyeye-seal-service/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + seal-service-web + seal-service-common + seal-service-pro + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-seal-service + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-common/.gitignore b/skyeye-seal-service/seal-service-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-seal-service/seal-service-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-common/pom.xml b/skyeye-seal-service/seal-service-common/pom.xml new file mode 100644 index 0000000..7111f06 --- /dev/null +++ b/skyeye-seal-service/seal-service-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-seal-service + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + seal-service-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-common/src/main/java/com/skyeye/constants/SealConstants.java b/skyeye-seal-service/seal-service-common/src/main/java/com/skyeye/constants/SealConstants.java new file mode 100644 index 0000000..16e024a --- /dev/null +++ b/skyeye-seal-service/seal-service-common/src/main/java/com/skyeye/constants/SealConstants.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.constants; + +/** + * @ClassName: SealConstants + * @Description: 常量类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 16:29 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public class SealConstants { + + /** + * @param orderNum 获取工单派工内容字符串 + * @param userName 接收人 + * @return + */ + public static String getNoticeServiceUserContent(String orderNum, String userName) { + return "尊敬的" + userName + ",您好:
" + "您有一份待接单工单,工单号为:" + orderNum + ",请及时接单。"; + } + + // 协助人 + public static String getNoticeCooperationUserContent(String orderNum, String userName) { + return "尊敬的" + userName + ",您好:
" + "您有一份协助工单,工单号为:" + orderNum + ",请配合工单接收人完成该售后服务。"; + } + +} diff --git a/skyeye-seal-service/seal-service-pro/.gitignore b/skyeye-seal-service/seal-service-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/pom.xml b/skyeye-seal-service/seal-service-pro/pom.xml new file mode 100644 index 0000000..de9f272 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-seal-service + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + seal-service-pro + + + + + com.skyeye + seal-service-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/classenum/UserStockPutOutType.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/classenum/UserStockPutOutType.java new file mode 100644 index 0000000..16224f3 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/classenum/UserStockPutOutType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: UserStockPutOutType + * @Description: 个人配件信息的出入库类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/13 16:30 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserStockPutOutType implements SkyeyeEnumClass { + + PUT(1, "入库", true, true), + OUT(2, "出库", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/SealApplyController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/SealApplyController.java new file mode 100644 index 0000000..00e1279 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/SealApplyController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.controller; + +import com.skyeye.accessory.entity.SealApply; +import com.skyeye.accessory.entity.SealApplyChangeStock; +import com.skyeye.accessory.service.SealApplyService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealApplyController + * @Description: 配件申领单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/11 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "配件申领单管理", tags = "配件申领单管理", modelName = "配件申领单管理") +public class SealApplyController { + + @Autowired + private SealApplyService sealApplyService; + + /** + * 查询我的配件申领单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice023", value = "查询我的配件申领单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealApplyController/querySealApplyList") + public void querySealApplyList(InputObject inputObject, OutputObject outputObject) { + sealApplyService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑配件申领单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealApply", value = "新增/编辑配件申领单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SealApply.class) + @RequestMapping("/post/SealApplyController/writeSealApply") + public void writeSealApply(InputObject inputObject, OutputObject outputObject) { + sealApplyService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除配件申领单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSealApplyById", value = "删除配件申领单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealApplyController/deleteSealApplyById") + public void deleteSealApplyById(InputObject inputObject, OutputObject outputObject) { + sealApplyService.deleteById(inputObject, outputObject); + } + + /** + * 配件申领单申请提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitSealApplyToApproval", value = "配件申领单申请提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/SealApplyController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + sealApplyService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销配件申领单申请 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeSealApply", value = "撤销配件申领单申请", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/SealApplyController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + sealApplyService.revoke(inputObject, outputObject); + } + + /** + * 修改配件申领单出库状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editSealApplyOtherState", value = "修改配件申领单出库状态", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "otherState", name = "otherState", value = "出库状态", required = "required,num")}) + @RequestMapping("/post/SealApplyController/editSealApplyOtherState") + public void editSealApplyOtherState(InputObject inputObject, OutputObject outputObject) { + sealApplyService.editSealApplyOtherState(inputObject, outputObject); + } + + /** + * 修改配件申领单已出库的数量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editSealApplyOutNum", value = "修改配件申领单已出库的数量", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SealApplyChangeStock.class) + @RequestMapping("/post/SealApplyController/editSealApplyOutNum") + public void editSealApplyOutNum(InputObject inputObject, OutputObject outputObject) { + sealApplyService.editSealApplyOutNum(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/ServiceUserStockController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/ServiceUserStockController.java new file mode 100644 index 0000000..cc4b2d7 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/controller/ServiceUserStockController.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.controller; + +import com.skyeye.accessory.service.ServiceUserStockService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ServiceUserStockController + * @Description: 用户配件申领单审核通过后的库存信息控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/9/26 22:03 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "我的配件", tags = "我的配件", modelName = "售后服务模块") +public class ServiceUserStockController { + + @Autowired + private ServiceUserStockService serviceUserStockService; + + /** + * 获取我申领的配件库存信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice031", value = "获取我申领的配件库存信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ServiceUserStockController/queryServiceUserStockList") + public void queryServiceUserStockList(InputObject inputObject, OutputObject outputObject) { + serviceUserStockService.queryPageList(inputObject, outputObject); + } + + /** + * 根据规格id获取我的库存 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyPartsNumByNormsId", value = "根据规格id获取我的库存", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "normsId", name = "normsId", value = "规格id", required = "required")}) + @RequestMapping("/post/ServiceUserStockController/queryMyPartsNumByNormsId") + public void queryMyPartsNumByNormsId(InputObject inputObject, OutputObject outputObject) { + serviceUserStockService.queryMyPartsNumByNormsId(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ApplyLinkDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ApplyLinkDao.java new file mode 100644 index 0000000..72022b9 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ApplyLinkDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.dao; + +import com.skyeye.accessory.entity.ApplyLink; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ApplyLinkDao + * @Description: 配件申请单配件信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/17 16:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ApplyLinkDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyCodeDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyCodeDao.java new file mode 100644 index 0000000..f841840 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyCodeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.dao; + +import com.skyeye.accessory.entity.SealApplyCode; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SealApplyCodeDao + * @Description: 单据关联的条形码编号数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 10:42 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyCodeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyDao.java new file mode 100644 index 0000000..e17a9d4 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/SealApplyDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.dao; + +import com.skyeye.accessory.entity.SealApply; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SealSeServiceApplyDao + * @Description: 配件申领单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/11 22:41 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ServiceUserStockDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ServiceUserStockDao.java new file mode 100644 index 0000000..3de7853 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/dao/ServiceUserStockDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.dao; + +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ServiceUserStockDao + * @Description: 用户配件申领单审核通过后的库存信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 11:06 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ServiceUserStockDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ApplyLink.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ApplyLink.java new file mode 100644 index 0000000..ec1c5d4 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ApplyLink.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ApplyLink + * @Description: 配件申请单配件信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/5/3 18:16 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "crm_service_apply_material") +@ApiModel("配件申请单配件信息实体类") +public class ApplyLink extends SkyeyeLinkData { + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Map materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField("oper_number") + @ApiModelProperty(value = "申领数量", required = "required,num") + private Integer operNumber; + + @TableField("unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField("all_price") + @ApiModelProperty(value = "总金额", required = "double", defaultValue = "0") + private String allPrice; + + @TableField(value = "depot_id") + @ApiModelProperty(value = "仓库id", required = "required") + private String depotId; + + @TableField(exist = false) + @Property(value = "仓库信息") + private Map depotMation; + + @TableField(exist = false) + @ApiModelProperty(value = "产品条形码编号集合", required = "json") + private List normsCodeList; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApply.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApply.java new file mode 100644 index 0000000..c2fca48 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApply.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SealApply + * @Description: 配件申请单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/17 17:13 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:apply", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_service_apply") +@ApiModel("配件申请单实体类") +public class SealApply extends SkyeyeFlowable { + + @TableField(value = "object_id") + @ApiModelProperty(value = "工单id") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "工单的key") + private String objectKey; + + @TableField(value = "apply_time") + @ApiModelProperty(value = "申领日期", required = "required") + private String applyTime; + + @TableField("remark") + @ApiModelProperty(value = "描述") + private String remark; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总金额") + private String allPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "配件申领明细", required = "required,json") + private List applyLinkList; + + @TableField("other_state") + @Property("出入库状态,参考ERP仓库的出入库状态#DepotOutState") + private Integer otherState; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyChangeStock.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyChangeStock.java new file mode 100644 index 0000000..a47a1cf --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyChangeStock.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SealApplyChangeStock + * @Description: 配件申请单修改数量实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 10:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("配件申请单修改数量实体类") +public class SealApplyChangeStock extends CommonInfo { + + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑", required = "required") + private String id; + + @ApiModelProperty(value = "创建人id", required = "required") + private String createId; + + @ApiModelProperty(value = "配件申领明细", required = "required,json") + private List applyLinkList; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyCode.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyCode.java new file mode 100644 index 0000000..2e74ae9 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/SealApplyCode.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: SealApplyCode + * @Description: 单据关联的条形码编号实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/23 16:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "crm_service_apply_code") +@ApiModel("单据关联的条形码编号实体类") +public class SealApplyCode extends CommonInfo { + + @TableId("id") + private String id; + + @TableField("parent_id") + @Property(value = "订单id") + private String parentId; + + @TableField("material_id") + @Property(value = "产品id") + private String materialId; + + @TableField("norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField("norms_code") + @Property(value = "条形码编号") + private String normsCode; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ServiceUserStock.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ServiceUserStock.java new file mode 100644 index 0000000..b61ee6e --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/entity/ServiceUserStock.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ServiceUserStock + * @Description: 用户配件申领单审核通过后的库存信息 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 11:06 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "crm_service_apply_user_stock") +@ApiModel("用户配件申领单审核通过后的库存信息") +public class ServiceUserStock extends CommonInfo { + + @TableField(value = "user_id") + @Property(value = "用户id") + private String userId; + + @TableField(value = "material_id") + @Property(value = "商品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Map materialMation; + + @TableField(value = "norms_id") + @Property(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "stock") + @Property(value = "数量") + private Integer stock; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ApplyLinkService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ApplyLinkService.java new file mode 100644 index 0000000..8d37e0d --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ApplyLinkService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service; + +import com.skyeye.accessory.entity.ApplyLink; +import com.skyeye.base.business.service.SkyeyeLinkDataService; + +import java.util.List; + +/** + * @ClassName: ApplyLinkService + * @Description: 配件申请单配件信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/17 17:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ApplyLinkService extends SkyeyeLinkDataService { + + /** + * 计算单据信息的总价 + * + * @param applyLinkList + * @return + */ + String calcOrderAllTotalPrice(List applyLinkList); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyCodeService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyCodeService.java new file mode 100644 index 0000000..de5d3a6 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyCodeService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service; + +import com.skyeye.accessory.entity.SealApplyCode; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +import java.util.List; + +/** + * @ClassName: SealApplyCodeService + * @Description: 单据关联的条形码编号服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 10:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyCodeService extends SkyeyeBusinessService { + + void saveList(String parentId, List beans); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyService.java new file mode 100644 index 0000000..f74cf6c --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/SealApplyService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service; + +import com.skyeye.accessory.entity.SealApply; +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: SealSeServiceApplyService + * @Description: 配件申领单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/11 22:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealApplyService extends SkyeyeFlowableService { + + void editSealApplyOtherState(InputObject inputObject, OutputObject outputObject); + + void editSealApplyOutNum(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ServiceUserStockService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ServiceUserStockService.java new file mode 100644 index 0000000..26d6c9a --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/ServiceUserStockService.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service; + +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ServiceUserStockService + * @Description: 用户配件申领单审核通过后的库存信息服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/13 22:26 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ServiceUserStockService extends SkyeyeBusinessService { + + /** + * 修改用户拥有的商品规格库存 + * + * @param userId 用户id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 参考#UserStockPutOutType枚举类 + */ + void editMaterialNormsUserStock(String userId, String materialId, String normsId, Integer operNumber, int type); + + void queryMyPartsNumByNormsId(InputObject inputObject, OutputObject outputObject); + + ServiceUserStock queryUserStock(String userId, String normsId); + + Map queryUserStock(String userId, List normsIds); + + void updateStock(String userId, String normsId, Integer stock); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ApplyLinkServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ApplyLinkServiceImpl.java new file mode 100644 index 0000000..03a54b5 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ApplyLinkServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.google.common.base.Joiner; +import com.skyeye.accessory.dao.ApplyLinkDao; +import com.skyeye.accessory.entity.ApplyLink; +import com.skyeye.accessory.service.ApplyLinkService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ApplyLinkServiceImpl + * @Description: 配件申请单配件信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/17 17:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "配件申请单配件信息", groupName = "配件申领单管理", manageShow = false) +public class ApplyLinkServiceImpl extends SkyeyeLinkDataServiceImpl implements ApplyLinkService { + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Override + public void checkLinkList(String pId, List beans) { + List checkIds = beans.stream().map(bean -> String.format(Locale.ROOT, "%s_%s", bean.getNormsId(), bean.getDepotId())).distinct().collect(Collectors.toList()); + if (checkIds.size() != beans.size()) { + throw new CustomException("存在来源为相同仓库配件规格信息."); + } + } + + @Override + public String calcOrderAllTotalPrice(List applyLinkList) { + List normsIds = applyLinkList.stream().map(ApplyLink::getNormsId).collect(Collectors.toList()); + Map> normsMap = iMaterialNormsService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIds)); + String allPrice = "0"; + for (ApplyLink applyLink : applyLinkList) { + // 子单据总价:使用数量 * 零售价 + Map norms = normsMap.get(applyLink.getNormsId()); + if (CollectionUtil.isEmpty(norms)) { + throw new CustomException("数据中包含不存在的配件规格信息."); + } + applyLink.setUnitPrice(norms.get("retailPrice").toString()); + applyLink.setAllPrice( + CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(applyLink.getOperNumber()), applyLink.getUnitPrice())); + // 计算主单总价 + allPrice = CalculationUtil.add(applyLink.getAllPrice(), allPrice); + } + return allPrice; + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyCodeServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyCodeServiceImpl.java new file mode 100644 index 0000000..49dd5cc --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyCodeServiceImpl.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.accessory.dao.SealApplyCodeDao; +import com.skyeye.accessory.entity.SealApplyCode; +import com.skyeye.accessory.service.SealApplyCodeService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: SealApplyCodeServiceImpl + * @Description: 单据关联的条形码编号服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/20 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "单据关联的条形码编号", groupName = "配件申领单管理") +public class SealApplyCodeServiceImpl extends SkyeyeBusinessServiceImpl implements SealApplyCodeService { + + @Override + public void saveList(String parentId, List beans) { + if (CollectionUtil.isNotEmpty(beans)) { + for (SealApplyCode sealApplyCode : beans) { + sealApplyCode.setParentId(parentId); + } + createEntity(beans, StrUtil.EMPTY); + } + } +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyServiceImpl.java new file mode 100644 index 0000000..415e9f4 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/SealApplyServiceImpl.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.accessory.classenum.UserStockPutOutType; +import com.skyeye.accessory.dao.SealApplyDao; +import com.skyeye.accessory.entity.ApplyLink; +import com.skyeye.accessory.entity.SealApply; +import com.skyeye.accessory.entity.SealApplyChangeStock; +import com.skyeye.accessory.entity.SealApplyCode; +import com.skyeye.accessory.service.ApplyLinkService; +import com.skyeye.accessory.service.SealApplyCodeService; +import com.skyeye.accessory.service.SealApplyService; +import com.skyeye.accessory.service.ServiceUserStockService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableChildStateEnum; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.depot.rest.IERPOrderRest; +import com.skyeye.rest.depot.service.IDepotService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealSeServiceApplyServiceImpl + * @Description: 配件申领单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/11 22:42 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "配件申领单", groupName = "配件申领单管理", flowable = true) +public class SealApplyServiceImpl extends SkyeyeFlowableServiceImpl implements SealApplyService { + + @Autowired + private ApplyLinkService applyLinkService; + + @Autowired + private ServiceUserStockService sealSeServiceMyPartsService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private IDepotService iDepotService; + + @Autowired + private IERPOrderRest ierpOrderRest; + + @Autowired + private SealApplyCodeService sealApplyCodeService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SealApply::getCreateId), userId); + return queryWrapper; + } + + @Override + public void validatorEntity(SealApply entity) { + String allPrice = applyLinkService.calcOrderAllTotalPrice(entity.getApplyLinkList()); + entity.setAllPrice(allPrice); + entity.setOtherState(CommonNumConstants.NUM_TWO); + } + + @Override + public void writeChild(SealApply entity, String userId) { + applyLinkService.saveLinkList(entity.getId(), entity.getApplyLinkList()); + super.writeChild(entity, userId); + } + + @Override + protected void deletePreExecution(SealApply entity) { + Boolean subType = checkState(entity); + if (!subType) { + throw new CustomException("该数据状态已改变,删除失败."); + } + } + + @Override + public void submitToApprovalPostpose(String id, String processInstanceId) { + super.submitToApprovalPostpose(id, processInstanceId); + applyLinkService.editStateByPId(id, FlowableChildStateEnum.IN_EXAMINE.getKey()); + } + + @Override + public SealApply getDataFromDb(String id) { + SealApply sealApply = super.getDataFromDb(id); + List applyLinkList = applyLinkService.selectByPId(sealApply.getId()); + sealApply.setApplyLinkList(applyLinkList); + return sealApply; + } + + @Override + public SealApply selectById(String id) { + SealApply sealApply = super.selectById(id); + // 产品信息 + List materialIds = sealApply.getApplyLinkList().stream().map(ApplyLink::getMaterialId).collect(Collectors.toList()); + Map> materialMap = iMaterialService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(materialIds)); + // 产品规格信息 + List normsIds = sealApply.getApplyLinkList().stream().map(ApplyLink::getNormsId).collect(Collectors.toList()); + Map> normsMap = iMaterialNormsService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIds)); + // 仓库信息 + List depotIds = sealApply.getApplyLinkList().stream().map(ApplyLink::getDepotId).collect(Collectors.toList()); + Map> depotMap = iDepotService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(depotIds)); + sealApply.getApplyLinkList().forEach(bean -> { + bean.setMaterialMation(materialMap.get(bean.getMaterialId())); + bean.setNormsMation(normsMap.get(bean.getNormsId())); + bean.setDepotMation(depotMap.get(bean.getDepotId())); + }); + return sealApply; + } + + @Override + public void revokePostpose(SealApply entity) { + super.revokePostpose(entity); + applyLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.DRAFT.getKey()); + } + + @Override + public void approvalEndIsSuccess(SealApply entity) { + SealApply sealApply = selectById(entity.getId()); + // 修改子单据状态 + applyLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.ADEQUATE.getKey()); + // 保存订单到erp + saveOrderToErp(sealApply); + } + + private void saveOrderToErp(SealApply sealApply) { + Map params = BeanUtil.beanToMap(sealApply); + params.put("state", FlowableStateEnum.PASS.getKey()); + params.put("type", CommonNumConstants.NUM_TWO); + params.put("idKey", getServiceClassName()); + params.put("operTime", sealApply.getApplyTime()); + params.put("discount", CommonNumConstants.NUM_ZERO); + params.put("discountMoney", CommonNumConstants.NUM_ZERO); + params.put("totalPrice", sealApply.getAllPrice()); + params.put("operTime", sealApply.getApplyTime()); + List> erpOrderItemList = new ArrayList<>(); + sealApply.getApplyLinkList().forEach(applyLink -> { + Map erpOrderItem = BeanUtil.beanToMap(applyLink); + erpOrderItem.put("taxMoney", CommonNumConstants.NUM_ZERO); + erpOrderItem.put("taxUnitPrice", CommonNumConstants.NUM_ZERO); + erpOrderItem.put("taxLastMoney", CommonNumConstants.NUM_ZERO); // 规格单位 + erpOrderItem.put("mType", CommonNumConstants.NUM_ZERO); + erpOrderItem.put("state", FlowableChildStateEnum.ADEQUATE.getKey()); + erpOrderItemList.add(erpOrderItem); + }); + params.put("erpOrderItemList", JSONUtil.toJsonStr(erpOrderItemList)); + ExecuteFeignClient.get(() -> ierpOrderRest.createApprovelSuccessOrder(params)); + } + + @Override + public void approvalEndIsFailed(SealApply entity) { + applyLinkService.editStateByPId(entity.getId(), FlowableChildStateEnum.REJECT.getKey()); + } + + @Override + public void editSealApplyOtherState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String otherState = params.get("otherState").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(SealApply::getOtherState), otherState); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void editSealApplyOutNum(InputObject inputObject, OutputObject outputObject) { + SealApplyChangeStock sealApplyChangeStock = inputObject.getParams(SealApplyChangeStock.class); + List sealApplyCodeList = new ArrayList<>(); + // 修改我的库存数量 + sealApplyChangeStock.getApplyLinkList().forEach(applyLink -> { + sealSeServiceMyPartsService.editMaterialNormsUserStock(sealApplyChangeStock.getCreateId(), applyLink.getMaterialId(), applyLink.getNormsId(), + applyLink.getOperNumber(), UserStockPutOutType.PUT.getKey()); + applyLink.getNormsCodeList().forEach(normsCode -> { + SealApplyCode sealApplyCode = new SealApplyCode(); + sealApplyCode.setNormsCode(normsCode); + sealApplyCode.setMaterialId(applyLink.getMaterialId()); + sealApplyCode.setNormsId(applyLink.getNormsId()); + sealApplyCodeList.add(sealApplyCode); + }); + }); + // 保存配件码信息 + sealApplyCodeService.saveList(sealApplyChangeStock.getId(), sealApplyCodeList); + } +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ServiceUserStockServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ServiceUserStockServiceImpl.java new file mode 100644 index 0000000..708f1fb --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/accessory/service/impl/ServiceUserStockServiceImpl.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.accessory.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.accessory.classenum.UserStockPutOutType; +import com.skyeye.accessory.dao.ServiceUserStockDao; +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.accessory.service.ServiceUserStockService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.jedis.util.RedisLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ServiceUserStockServiceImpl + * @Description: 用户配件申领单审核通过后的库存信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/1/13 22:25 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ServiceUserStockServiceImpl extends SkyeyeBusinessServiceImpl implements ServiceUserStockService { + + private static Logger LOGGER = LoggerFactory.getLogger(ServiceUserStockServiceImpl.class); + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private IMaterialService iMaterialService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getUserId), userId); + return queryWrapper; + } + + @Override + protected List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iMaterialService.setMationForMap(beans, "materialId", "materialMation"); + iMaterialNormsService.setMationForMap(beans, "normsId", "normsMation"); + return beans; + } + + /** + * 修改用户拥有的商品规格库存 + * + * @param userId 仓库id + * @param materialId 商品id + * @param normsId 规格id + * @param operNumber 变化数量 + * @param type 参考#UserStockPutOutType枚举类 + */ + @Override + public void editMaterialNormsUserStock(String userId, String materialId, String normsId, Integer operNumber, int type) { + String lockKey = String.format("userStock_%s_%s", userId, normsId); + RedisLock lock = new RedisLock(lockKey); + try { + if (!lock.lock()) { + // 加锁失败 + throw new CustomException("增减库存失败,当前并发量较大,请稍后再次尝试."); + } + LOGGER.info("get lock success, lockKey is {}.", lockKey); + // 变化的数量 + ServiceUserStock serviceUserStock = queryUserStock(userId, normsId); + // 如果该规格在指定仓库中已经有存储数据,则直接做修改 + if (ObjectUtil.isNotEmpty(serviceUserStock)) { + int stockNum = serviceUserStock.getStock(); + LOGGER.info("update user stock normsId【{}】 Stock. type is {}, old stockNum is {}, change stockNum is {}", normsId, type, stockNum, operNumber); + stockNum = getNewStockNum(type, operNumber, stockNum); + updateStock(userId, normsId, stockNum); + } else { + int stockNum = 0; + LOGGER.info("insert user stock normsId【{}】 Stock. type is {}, change stockNum is {}", normsId, type, operNumber); + stockNum = getNewStockNum(type, operNumber, stockNum); + saveStock(userId, materialId, normsId, stockNum); + } + LOGGER.info("editMaterialNormsUserStock is success."); + } catch (Exception ee) { + LOGGER.warn("editMaterialNormsUserStock error, because {}", ee); + if (ee instanceof CustomException) { + throw new CustomException(ee.getMessage()); + } + throw new RuntimeException(ee.getMessage()); + } finally { + lock.unlock(); + } + } + + private int getNewStockNum(int type, int changeNumber, int stockNum) { + if (type == UserStockPutOutType.PUT.getKey()) { + // 入库 + stockNum = stockNum + changeNumber; + } else if (type == UserStockPutOutType.OUT.getKey()) { + // 出库 + stockNum = stockNum - changeNumber; + } else { + throw new CustomException("状态错误"); + } + if (stockNum < 0) { + throw new CustomException("库存不足,无法操作."); + } + return stockNum; + } + + /** + * 根据配件规格id获取我的库存 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyPartsNumByNormsId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String userId = inputObject.getLogParams().get("id").toString(); + String normsId = map.get("normsId").toString(); + ServiceUserStock serviceUserStock = queryUserStock(userId, normsId); + outputObject.setBean(serviceUserStock); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public ServiceUserStock queryUserStock(String userId, String normsId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getUserId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getNormsId), normsId); + return getOne(queryWrapper); + } + + @Override + public Map queryUserStock(String userId, List normsIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getUserId), userId); + queryWrapper.in(MybatisPlusUtil.toColumns(ServiceUserStock::getNormsId), normsIds); + List userStocks = list(queryWrapper); + if (CollectionUtil.isEmpty(userStocks)) { + return MapUtil.newHashMap(); + } + return userStocks.stream().collect(Collectors.toMap(ServiceUserStock::getNormsId, bean -> bean)); + } + + @Override + public void updateStock(String userId, String normsId, Integer stock) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getUserId), userId); + updateWrapper.eq(MybatisPlusUtil.toColumns(ServiceUserStock::getNormsId), normsId); + updateWrapper.set(MybatisPlusUtil.toColumns(ServiceUserStock::getStock), stock); + update(updateWrapper); + } + + private void saveStock(String userId, String materialId, String normsId, Integer stock) { + ServiceUserStock serviceUserStock = new ServiceUserStock(); + serviceUserStock.setUserId(userId); + serviceUserStock.setMaterialId(materialId); + serviceUserStock.setNormsId(normsId); + serviceUserStock.setStock(stock); + createEntity(serviceUserStock, userId); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/AfterSealState.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/AfterSealState.java new file mode 100644 index 0000000..2eb4639 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/AfterSealState.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: AfterSealState + * @Description: 售后工单状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AfterSealState implements SkyeyeEnumClass { + + BE_DISPATCHED("beDispatched", "待派工", true, true), + PENDING_ORDERS("pendingOrders", "待接单", true, false), + BE_SIGNED("beSigned", "待签到", true, false), + BE_COMPLETED("beCompleted", "待完工", true, false), + BE_EVALUATED("beEvaluated", "待评价", true, false), + AUDIT("audit", "待审核", true, false), + COMPLATE("complate", "已完工", true, false); + + private String key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/ProductWarrantyType.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/ProductWarrantyType.java new file mode 100644 index 0000000..57ee6a6 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/ProductWarrantyType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ProductWarrantyType + * @Description: 质保类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ProductWarrantyType implements SkyeyeEnumClass { + + WITHIN_THE_WARRANTY_PERIOD(1, "保内", true, true), + ON_BAIL(2, "保外", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/SealOrderType.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/SealOrderType.java new file mode 100644 index 0000000..9e2c72d --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/classenum/SealOrderType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: SealOrderType + * @Description: 工单类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SealOrderType implements SkyeyeEnumClass { + + WECHAR_USER(1, "微信用户报单", true, true), + SYS_USER(2, "系统用户报单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/AfterSealController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/AfterSealController.java new file mode 100644 index 0000000..43280d1 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/AfterSealController.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.controller; + +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.afterseal.service.AfterSealService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AfterSealController + * @Description: 售后工单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "售后工单管理", tags = "售后工单管理", modelName = "售后工单") +public class AfterSealController { + + @Autowired + private AfterSealService afterSealService; + + /** + * 获取工单列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealServiceOrderList", value = "获取工单列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AfterSealController/querySealServiceOrderList") + public void querySealServiceOrderList(InputObject inputObject, OutputObject outputObject) { + afterSealService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑售后服务工单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealServiceOrder", value = "新增/编辑售后服务工单信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = AfterSeal.class) + @RequestMapping("/post/AfterSealController/writeSealServiceOrder") + public void writeSealServiceOrder(InputObject inputObject, OutputObject outputObject) { + afterSealService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 派工 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice014", value = "派工", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "serviceUserId", name = "serviceUserId", value = "接收人", required = "required"), + @ApiImplicitParam(id = "cooperationUserId", name = "cooperationUserId", value = "协助人", required = "json")}) + @RequestMapping("/post/AfterSealController/editSealSeServiceWaitToWorkMation") + public void editSealSeServiceWaitToWorkMation(InputObject inputObject, OutputObject outputObject) { + afterSealService.editSealSeServiceWaitToWorkMation(inputObject, outputObject); + } + + /** + * 接单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice017", value = "接单", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AfterSealController/receivingSealSeServiceOrderById") + public void receivingSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + afterSealService.receivingSealSeServiceOrderById(inputObject, outputObject); + } + + /** + * 根据id查询售后服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealServiceOrderById", value = "根据id查询售后服务信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AfterSealController/querySealServiceOrderById") + public void querySealServiceOrderById(InputObject inputObject, OutputObject outputObject) { + afterSealService.selectById(inputObject, outputObject); + } + + /** + * 删除售后服务信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSealServiceOrderById", value = "删除售后服务信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AfterSealController/deleteSealSeServiceMationById") + public void deleteSealSeServiceMationById(InputObject inputObject, OutputObject outputObject) { + afterSealService.deleteById(inputObject, outputObject); + } + + /** + * 查询我的待完工状态的工单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice022", value = "查询我的待完工状态的工单", method = "GET", allUse = "2") + @RequestMapping("/post/AfterSealController/querySealSeServiceSignon") + public void querySealSeServiceSignon(InputObject inputObject, OutputObject outputObject) { + afterSealService.querySealSeServiceSignon(inputObject, outputObject); + } + + /** + * 完工操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice035", value = "完工操作", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AfterSealController/auditSealSeServiceOrderById") + public void auditSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + afterSealService.auditSealSeServiceOrderById(inputObject, outputObject); + } + + /** + * 完工审核操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseservice038", value = "完工审核操作", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AfterSealController/finishSealSeServiceOrderById") + public void finishSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + afterSealService.finishSealSeServiceOrderById(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealEvaluateController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealEvaluateController.java new file mode 100644 index 0000000..fa04661 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealEvaluateController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.controller; + +import com.skyeye.afterseal.entity.SealEvaluate; +import com.skyeye.afterseal.service.SealEvaluateService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealEvaluateController + * @Description: 工单服务评价控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 18:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "工单服务评价", tags = "工单服务评价", modelName = "售后工单") +public class SealEvaluateController { + + @Autowired + private SealEvaluateService sealEvaluateService; + + /** + * 获取工单服务评价列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealEvaluateList", value = "获取工单服务评价列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealEvaluateController/querySealEvaluateList") + public void querySealEvaluateList(InputObject inputObject, OutputObject outputObject) { + sealEvaluateService.queryPageList(inputObject, outputObject); + } + + /** + * 新增工单服务评价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSealEvaluate", value = "新增工单服务评价", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SealEvaluate.class) + @RequestMapping("/post/SealEvaluateController/insertSealEvaluate") + public void insertSealEvaluate(InputObject inputObject, OutputObject outputObject) { + sealEvaluateService.createEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFaultController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFaultController.java new file mode 100644 index 0000000..85076ff --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFaultController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.controller; + +import com.skyeye.afterseal.entity.SealFault; +import com.skyeye.afterseal.service.SealFaultService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealFaultController + * @Description: 售后服务故障信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "售后服务故障信息", tags = "售后服务故障信息", modelName = "售后工单") +public class SealFaultController { + + @Autowired + private SealFaultService sealFaultService; + + /** + * 获取故障信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealFaultList", value = "获取故障信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealFaultController/querySealFaultList") + public void querySealFaultList(InputObject inputObject, OutputObject outputObject) { + sealFaultService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑故障信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealFault", value = "新增/编辑故障信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SealFault.class) + @RequestMapping("/post/SealFaultController/writeSealFault") + public void writeSealFault(InputObject inputObject, OutputObject outputObject) { + sealFaultService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除故障信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSealFaultById", value = "删除故障信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealFaultController/deleteSealFaultById") + public void deleteSealFaultById(InputObject inputObject, OutputObject outputObject) { + sealFaultService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFeedBackController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFeedBackController.java new file mode 100644 index 0000000..e6ef107 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealFeedBackController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.controller; + +import com.skyeye.afterseal.entity.SealFeedBack; +import com.skyeye.afterseal.service.SealFeedBackService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealFeedBackController + * @Description: 工单情况反馈信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "工单情况反馈信息", tags = "工单情况反馈信息", modelName = "售后工单") +public class SealFeedBackController { + + @Autowired + private SealFeedBackService sealFeedBackService; + + /** + * 获取情况反馈列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryFeedBackList", value = "获取情况反馈列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealFeedBackController/queryFeedBackList") + public void queryFeedBackList(InputObject inputObject, OutputObject outputObject) { + sealFeedBackService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑情况反馈信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeFeedBack", value = "新增/编辑情况反馈信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SealFeedBack.class) + @RequestMapping("/post/SealFeedBackController/writeFeedBack") + public void writeFeedBack(InputObject inputObject, OutputObject outputObject) { + sealFeedBackService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除情况反馈 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteFeedBackById", value = "删除情况反馈", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealFeedBackController/deleteFeedBackById") + public void deleteFeedBackById(InputObject inputObject, OutputObject outputObject) { + sealFeedBackService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealSignController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealSignController.java new file mode 100644 index 0000000..a7edb57 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/controller/SealSignController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.controller; + +import com.skyeye.afterseal.entity.SealSign; +import com.skyeye.afterseal.service.SealSignService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealSignController + * @Description: 售后服务故障信息控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:14 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "工人签到信息", tags = "工人签到信息", modelName = "售后工单") +public class SealSignController { + + @Autowired + private SealSignService sealSignService; + + /** + * 获取工人签到信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySealSignList", value = "获取工人签到信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealSignController/querySealSignList") + public void querySealSignList(InputObject inputObject, OutputObject outputObject) { + sealSignService.queryPageList(inputObject, outputObject); + } + + /** + * 新增工人签到信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertSealSign", value = "新增工人签到信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = SealSign.class) + @RequestMapping("/post/SealSignController/insertSealSign") + public void insertSealSign(InputObject inputObject, OutputObject outputObject) { + sealSignService.createEntity(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/AfterSealDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/AfterSealDao.java new file mode 100644 index 0000000..4dcc680 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/AfterSealDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealSeServiceDao + * @Description: 售后工单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 22:43 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AfterSealDao extends SkyeyeBaseMapper { + + List> querySealServiceOrderList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealEvaluateDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealEvaluateDao.java new file mode 100644 index 0000000..6f22ee5 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealEvaluateDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.SealEvaluate; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealEvaluateDao + * @Description: 工单服务评价数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 18:18 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealEvaluateDao extends SkyeyeBaseMapper { + + List> querySealEvaluateList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultDao.java new file mode 100644 index 0000000..199c3d1 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.SealFault; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealFaultDao + * @Description: 售后服务故障信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 17:38 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFaultDao extends SkyeyeBaseMapper { + + List> querySealFaultList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultUseMaterialDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultUseMaterialDao.java new file mode 100644 index 0000000..ef11bbe --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFaultUseMaterialDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.SealFaultUseMaterial; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: SealFaultUseMaterialDao + * @Description: 售后服务故障配件使用信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 21:36 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFaultUseMaterialDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFeedBackDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFeedBackDao.java new file mode 100644 index 0000000..2582967 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealFeedBackDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.SealFeedBack; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealFeedBackDao + * @Description: 工单情况反馈信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 15:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFeedBackDao extends SkyeyeBaseMapper { + + List> queryFeedBackList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealSignDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealSignDao.java new file mode 100644 index 0000000..7e05142 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/dao/SealSignDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.dao; + +import com.skyeye.afterseal.entity.SealSign; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealSignDao + * @Description: 工人签到信息数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 13:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealSignDao extends SkyeyeBaseMapper { + + List> querySealSignList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/AfterSeal.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/AfterSeal.java new file mode 100644 index 0000000..3bbd713 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/AfterSeal.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.worker.entity.SealWorker; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AfterSeal + * @Description: 售后工单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:server:order", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "crm_service", autoResultMap = true) +@ApiModel("售后工单实体类") +public class AfterSeal extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property("单据编号") + private String oddNumber; + + @TableField(value = "declaration_time") + @ApiModelProperty(value = "报单时间", required = "required") + private String declarationTime; + + @TableField(value = "declaration_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "用户报单人的id") + private String declarationId; + + @TableField(exist = false) + @Property(value = "用户报单人信息") + private Map declarationMation; + + @TableField(value = "declaration_open_id") + @ApiModelProperty(value = "微信报单人的open_id") + private String declarationOpenId; + + @TableField(exist = false) + @Property(value = "微信报单人信息") + private Map declarationOpenMation; + + @TableField("holder_id") + @ApiModelProperty(value = "关联的客户/会员id") + private String holderId; + + @TableField(exist = false) + @Property(value = "关联的客户/会员的className") + private Map holderMation; + + @TableField("holder_key") + @ApiModelProperty(value = "关联的客户/会员的className") + private String holderKey; + + @TableField(value = "contacts") + @ApiModelProperty(value = "联系人姓名", required = "required") + private String contacts; + + @TableField(value = "phone") + @ApiModelProperty(value = "联系电话", required = "required") + private String phone; + + @TableField(value = "type_id") + @ApiModelProperty(value = "服务类型,参考数据字典", required = "required") + private String typeId; + + @TableField(value = "product_id") + @ApiModelProperty(value = "产品id", required = "required") + private String productId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Map productMation; + + @TableField(value = "product_warranty") + @ApiModelProperty(value = "质保类型,参考#ProductWarrantyType枚举", required = "required,num") + private Integer productWarranty; + + @TableField(value = "mode_id") + @ApiModelProperty(value = "服务处理方式,参考数据字典", required = "required") + private String modeId; + + @TableField(value = "content") + @ApiModelProperty(value = "服务内容", required = "required") + private String content; + + @TableField(value = "urgency_id") + @ApiModelProperty(value = "紧急程度,参考数据字典", required = "required") + private String urgencyId; + + @TableField(value = "service_user_id") + @ApiModelProperty(value = "服务人员id") + private String serviceUserId; + + @TableField(exist = false) + @Property(value = "服务人员信息") + private SealWorker serviceUserMation; + + @TableField(value = "service_time") + @Property(value = "派工时间") + private String serviceTime; + + @TableField(value = "cooperation_user_id", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "协作人员id", required = "json") + private List cooperationUserId; + + @TableField(exist = false) + @Property(value = "协作人员信息") + private List> cooperationUserMation; + + @TableField(value = "sheet_picture") + @ApiModelProperty(value = "工单图片") + private String sheetPicture; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(value = "state") + @Property(value = "状态") + private String state; + + @TableField(value = "type", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "工单类型,参考#SealOrderType枚举", required = "required,num", defaultValue = "2") + private Integer type; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealEvaluate.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealEvaluate.java new file mode 100644 index 0000000..2aa4fd4 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealEvaluate.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SealEvaluate + * @Description: 工单服务评价实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 14:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:server:evaluate", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_service_evaluate") +@ApiModel("工单服务评价实体类") +public class SealEvaluate extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "type_id") + @ApiModelProperty(value = "评价类型,参考数据字典", required = "required") + private String typeId; + + @TableField(value = "object_id") + @ApiModelProperty(value = "工单id", required = "required") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "工单的key", required = "required") + private String objectKey; + + @TableField(value = "content") + @ApiModelProperty(value = "评价内容", required = "required") + private String content; + + @TableField(value = "type") + @ApiModelProperty(value = "类型 1.系统自动好评 2.人工评价", required = "num", defaultValue = "2") + private Integer type; + + @TableField(value = "open_id") + @ApiModelProperty(value = "微信用户的id") + private String openId; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFault.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFault.java new file mode 100644 index 0000000..6c630bb --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFault.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SealFault + * @Description: 售后服务故障信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 17:23 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:server:fault", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_service_fault") +@ApiModel("售后服务故障信息实体类") +public class SealFault extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property("单据编号") + private String oddNumber; + + @TableField(value = "type_id") + @ApiModelProperty(value = "故障类型,参考数据字典", required = "required") + private String typeId; + + @TableField(value = "object_id") + @ApiModelProperty(value = "工单id", required = "required") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "工单的key", required = "required") + private String objectKey; + + @TableField(value = "com_execution") + @ApiModelProperty(value = "完成情况", required = "required") + private String comExecution; + + @TableField(value = "com_pic") + @ApiModelProperty(value = "完工拍照") + private String comPic; + + @TableField(exist = false) + @ApiModelProperty(value = "完工附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(value = "com_start_time") + @ApiModelProperty(value = "实际开工时间") + private String comStartTime; + + @TableField(value = "com_end_time") + @ApiModelProperty(value = "实际完工时间") + private String comEndTime; + + @TableField(value = "com_work_time") + @ApiModelProperty(value = "工时") + private String comWorkTime; + + @TableField(value = "material_cost") + @ApiModelProperty(value = "材料费") + private String materialCost; + + @TableField(value = "cover_cost") + @ApiModelProperty(value = "服务费", required = "double", defaultValue = "0") + private String coverCost; + + @TableField(value = "other_cost") + @ApiModelProperty(value = "其他费用", required = "double", defaultValue = "0") + private String otherCost; + + @TableField(value = "all_price") + @ApiModelProperty(value = "总费用") + private String allPrice; + + @TableField(value = "fault_key_parts_id") + @ApiModelProperty(value = "故障关键组件id") + private String faultKeyPartsId; + + @TableField(value = "actual_failure") + @ApiModelProperty(value = "实际故障") + private String actualFailure; + + @TableField(value = "solution") + @ApiModelProperty(value = "解决方案") + private String solution; + + @TableField("remark") + @ApiModelProperty(value = "完工备注") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "售后服务故障配件使用信息", required = "json") + private List sealFaultUseMaterialList; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFaultUseMaterial.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFaultUseMaterial.java new file mode 100644 index 0000000..7330fbd --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFaultUseMaterial.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.SkyeyeLinkData; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: SealFaultUseMaterial + * @Description: 售后服务故障配件使用信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 17:44 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@TableName(value = "crm_service_fault_use_material") +@ApiModel("售后服务故障配件使用信息实体类") +public class SealFaultUseMaterial extends SkyeyeLinkData { + + @TableField("material_id") + @ApiModelProperty(value = "产品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "产品信息") + private Map materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "商品规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField("oper_number") + @ApiModelProperty(value = "使用数量", required = "required,num") + private Integer operNumber; + + @TableField("unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField("all_price") + @ApiModelProperty(value = "总金额", required = "double", defaultValue = "0") + private String allPrice; + + @TableField(exist = false) + @Property(value = "我的库存信息") + private ServiceUserStock serviceUserStock; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFeedBack.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFeedBack.java new file mode 100644 index 0000000..edd8743 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealFeedBack.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: SealFeedBack + * @Description: 工单情况反馈信息实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 14:58 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:server:feedback", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_service_feedback") +@ApiModel("工单情况反馈信息实体类") +public class SealFeedBack extends OperatorUserInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "type_id") + @ApiModelProperty(value = "反馈类型,参考数据字典", required = "required") + private String typeId; + + @TableField(value = "object_id") + @ApiModelProperty(value = "工单id", required = "required") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "工单的key", required = "required") + private String objectKey; + + @TableField(value = "content") + @ApiModelProperty(value = "反馈内容", required = "required") + private String content; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealSign.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealSign.java new file mode 100644 index 0000000..b1438be --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/entity/SealSign.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: SealSign + * @Description: 工人签到信息 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 13:15 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:server:sign", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "crm_service_sign") +@ApiModel("工人签到信息实体类") +public class SealSign extends CommonInfo { + + @TableId("id") + @Property(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "object_id") + @ApiModelProperty(value = "工单id", required = "required") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "工单的key", required = "required") + private String objectKey; + + @TableField(value = "longitude") + @ApiModelProperty(value = "经度") + private String longitude; + + @TableField(value = "latitude") + @ApiModelProperty(value = "纬度") + private String latitude; + + @TableField(value = "address") + @ApiModelProperty(value = "签到地址") + private String address; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "sign_id") + @Property(value = "签到人id") + private String signId; + + @TableField(value = "sign_time") + @Property(value = "签到日期") + private String signTime; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/AfterSealService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/AfterSealService.java new file mode 100644 index 0000000..745ff2d --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/AfterSealService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AfterSealService + * @Description: 售后工单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/10 13:21 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface AfterSealService extends SkyeyeBusinessService { + + void editSealSeServiceWaitToWorkMation(InputObject inputObject, OutputObject outputObject); + + void receivingSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject); + + void updateStateById(String id, String state); + + void querySealSeServiceSignon(InputObject inputObject, OutputObject outputObject); + + void auditSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject); + + void finishSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealEvaluateService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealEvaluateService.java new file mode 100644 index 0000000..8f722b1 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealEvaluateService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.SealEvaluate; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: SealEvaluateService + * @Description: 工单服务评价服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 18:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealEvaluateService extends SkyeyeBusinessService { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultService.java new file mode 100644 index 0000000..ff28e5c --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.SealFault; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: SealFaultService + * @Description: 售后服务故障信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 17:39 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFaultService extends SkyeyeBusinessService { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultUseMaterialService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultUseMaterialService.java new file mode 100644 index 0000000..a3514dd --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFaultUseMaterialService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.SealFaultUseMaterial; +import com.skyeye.base.business.service.SkyeyeLinkDataService; + +import java.util.List; + +/** + * @ClassName: SealFaultUseMaterialService + * @Description: 售后服务故障配件使用信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 21:37 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFaultUseMaterialService extends SkyeyeLinkDataService { + + /** + * 计算单据信息的总价 + * + * @param sealFaultUseMaterials + * @return + */ + String calcOrderAllTotalPrice(List sealFaultUseMaterials); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFeedBackService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFeedBackService.java new file mode 100644 index 0000000..98cce9f --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealFeedBackService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.SealFeedBack; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: SealFeedBackService + * @Description: 工单情况反馈信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 15:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealFeedBackService extends SkyeyeBusinessService { + + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealSignService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealSignService.java new file mode 100644 index 0000000..1094935 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/SealSignService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service; + +import com.skyeye.afterseal.entity.SealSign; +import com.skyeye.base.business.service.SkyeyeBusinessService; + +/** + * @ClassName: SealSignService + * @Description: 工人签到信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 13:25 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealSignService extends SkyeyeBusinessService { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/AfterSealServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/AfterSealServiceImpl.java new file mode 100644 index 0000000..6dfae78 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/AfterSealServiceImpl.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.afterseal.classenum.AfterSealState; +import com.skyeye.afterseal.dao.AfterSealDao; +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.afterseal.service.AfterSealService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.crm.service.ICustomerService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.eve.rest.mq.JobMateMation; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.exception.CustomException; +import com.skyeye.worker.service.SealWorkerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealSeServiceServiceImpl + * @Description: 售后服务工单管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/8 21:23 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "售后工单管理", groupName = "售后工单") +public class AfterSealServiceImpl extends SkyeyeBusinessServiceImpl implements AfterSealService { + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private ICustomerService iCustomerService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private SealWorkerService sealWorkerService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + setPageInfoOfType(pageInfo, inputObject.getLogParams().get("id").toString()); + List> beans = skyeyeBaseMapper.querySealServiceOrderList(pageInfo); + + iCustomerService.setMationForMap(beans, "holderId", "holderMation"); + iAuthUserService.setMationForMap(beans, "declarationId", "declarationMation"); + iAuthUserService.setMationForMap(beans, "serviceUserId", "serviceUserMation"); + return beans; + } + + private void setPageInfoOfType(CommonPageInfo pageInfo, String userId) { + String state = pageInfo.getState(); + if (StrUtil.isEmpty(state)) { + return; + } + if (StrUtil.equals(state, AfterSealState.BE_DISPATCHED.getKey()) + || StrUtil.equals(state, AfterSealState.BE_EVALUATED.getKey()) + || StrUtil.equals(state, AfterSealState.AUDIT.getKey()) + || StrUtil.equals(state, AfterSealState.COMPLATE.getKey())) { + // 待派工,待评价,待审核,已完工的工单查询所有的 + } else { + pageInfo.setCreateId(userId); + } + } + + @Override + public AfterSeal selectById(String id) { + AfterSeal afterSeal = super.selectById(id); + + iAuthUserService.setDataMation(afterSeal, AfterSeal::getDeclarationId); + afterSeal.setServiceUserMation(sealWorkerService.selectByUserId(afterSeal.getServiceUserId())); + if (CollectionUtil.isNotEmpty(afterSeal.getCooperationUserId())) { + afterSeal.setCooperationUserMation(iAuthUserService.queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(afterSeal.getCooperationUserId()))); + } + + iMaterialService.setDataMation(afterSeal, AfterSeal::getProductId); + iCustomerService.setDataMation(afterSeal, AfterSeal::getHolderId); + return afterSeal; + } + + @Override + public void createPrepose(AfterSeal entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(this.getClass().getName(), business); + entity.setOddNumber(oddNumber); + if (StrUtil.isEmpty(entity.getServiceUserId())) { + entity.setState(AfterSealState.BE_DISPATCHED.getKey()); + } else { + // 默认有接单人 + entity.setState(AfterSealState.PENDING_ORDERS.getKey()); + entity.setServiceTime(DateUtil.getTimeAndToString()); + } + entity.setDeclarationId(InputObject.getLogParamsStatic().get("id").toString()); + } + + @Override + protected void validatorEntity(AfterSeal entity) { + if (StrUtil.isNotEmpty(entity.getId())) { + AfterSeal afterSeal = selectById(entity.getId()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_DISPATCHED.getKey()) + || StrUtil.equals(afterSeal.getState(), AfterSealState.PENDING_ORDERS.getKey())) { + // 待派工,待接单可以进行编辑 + } else { + throw new CustomException("该数据状态已改变,请刷新页面!"); + } + } + } + + @Override + protected void updatePrepose(AfterSeal entity) { + if (StrUtil.isEmpty(entity.getServiceUserId())) { + entity.setState(AfterSealState.BE_DISPATCHED.getKey()); + } else { + // 默认有接单人 + entity.setState(AfterSealState.PENDING_ORDERS.getKey()); + entity.setServiceTime(DateUtil.getTimeAndToString()); + } + } + + @Override + protected void writePostpose(AfterSeal entity, String userId) { + super.writePostpose(entity, userId); + + sendDispatchWork(entity.getId(), userId); + } + + private void sendDispatchWork(String id, String userId) { + // 发送消息 + Map notice = new HashMap<>(); + notice.put("serviceId", id); + notice.put("type", MqConstants.JobMateMationJobType.WATI_WORKER_SEND.getJobType()); + JobMateMation jobMateMation = new JobMateMation(); + jobMateMation.setJsonStr(JSONUtil.toJsonStr(notice)); + jobMateMation.setUserId(userId); + iJobMateMationService.sendMQProducer(jobMateMation); + } + + /** + * 派工 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void editSealSeServiceWaitToWorkMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String id = map.get("id").toString(); + AfterSeal afterSeal = selectById(id); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_DISPATCHED.getKey())) { + // 待派工可以进行派工 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, afterSeal.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(AfterSeal::getState), AfterSealState.PENDING_ORDERS.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(AfterSeal::getServiceUserId), map.get("serviceUserId").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(AfterSeal::getCooperationUserId), map.get("cooperationUserId").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(AfterSeal::getServiceTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + // 派工成功mq消息任务 + sendDispatchWork(id, afterSeal.getCreateId()); + refreshCache(id); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 接单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void receivingSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + AfterSeal afterSeal = selectById(map.get("id").toString()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.PENDING_ORDERS.getKey())) { + // 待接单可以进行接单 + updateStateById(afterSeal.getId(), AfterSealState.BE_SIGNED.getKey()); + refreshCache(afterSeal.getId()); + } else { + outputObject.setreturnMessage("该数据状态已改变,请刷新页面!"); + } + } + + @Override + public void deletePreExecution(AfterSeal afterSeal) { + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_DISPATCHED.getKey()) + || StrUtil.equals(afterSeal.getState(), AfterSealState.PENDING_ORDERS.getKey())) { + // 待派工/待接单可以进行删除 + } else { + throw new CustomException("该数据状态已改变,请刷新页面!"); + } + } + + /** + * 查询我的待完工状态的工单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void querySealSeServiceSignon(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(AfterSeal::getServiceUserId), InputObject.getLogParamsStatic().get("id").toString()); + queryWrapper.eq(MybatisPlusUtil.toColumns(AfterSeal::getState), AfterSealState.BE_COMPLETED.getKey()); + List afterSealList = list(queryWrapper); + outputObject.setBeans(afterSealList); + outputObject.settotal(afterSealList.size()); + } + + /** + * 工单完工操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void auditSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + AfterSeal afterSeal = selectById(map.get("id").toString()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_COMPLETED.getKey())) { + // 只有待完工状态下可以完工,修改为待评价状态 + updateStateById(afterSeal.getId(), AfterSealState.BE_EVALUATED.getKey()); + refreshCache(afterSeal.getId()); + } else { + throw new CustomException("该数据状态已改变,请刷新页面!"); + } + } + + @Override + public void updateStateById(String id, String state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(AfterSeal::getState), state); + update(updateWrapper); + refreshCache(id); + } + + /** + * 完工审核操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void finishSealSeServiceOrderById(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + AfterSeal afterSeal = selectById(map.get("id").toString()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.AUDIT.getKey())) { + // 待审核状态可以进行审核完工 + updateStateById(afterSeal.getId(), AfterSealState.COMPLATE.getKey()); + refreshCache(afterSeal.getId()); + } else { + throw new CustomException("该数据状态已改变,请刷新页面!"); + } + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealEvaluateServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealEvaluateServiceImpl.java new file mode 100644 index 0000000..26e1376 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealEvaluateServiceImpl.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.afterseal.classenum.AfterSealState; +import com.skyeye.afterseal.dao.SealEvaluateDao; +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.afterseal.entity.SealEvaluate; +import com.skyeye.afterseal.service.AfterSealService; +import com.skyeye.afterseal.service.SealEvaluateService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealEvaluateServiceImpl + * @Description: 工单服务评价服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 18:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "工单服务评价", groupName = "售后工单", teamAuth = true) +public class SealEvaluateServiceImpl extends SkyeyeBusinessServiceImpl implements SealEvaluateService { + + @Autowired + private AfterSealService afterSealService; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySealEvaluateList(commonPageInfo); + return beans; + } + + @Override + protected void validatorEntity(SealEvaluate entity) { + AfterSeal afterSeal = afterSealService.selectById(entity.getObjectId()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_EVALUATED.getKey())) { + // 待评价可以进行评价 + } else { + throw new CustomException("该工单已经评价。"); + } + } + + @Override + protected void createPostpose(SealEvaluate entity, String userId) { + // 修改工单信息为【待审核】 + afterSealService.updateStateById(entity.getObjectId(), AfterSealState.AUDIT.getKey()); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultServiceImpl.java new file mode 100644 index 0000000..61db607 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultServiceImpl.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.skyeye.accessory.classenum.UserStockPutOutType; +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.accessory.service.ServiceUserStockService; +import com.skyeye.afterseal.dao.SealFaultDao; +import com.skyeye.afterseal.entity.SealFault; +import com.skyeye.afterseal.entity.SealFaultUseMaterial; +import com.skyeye.afterseal.service.SealFaultService; +import com.skyeye.afterseal.service.SealFaultUseMaterialService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealFaultServiceImpl + * @Description: 售后服务故障信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 17:39 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "售后服务故障信息", groupName = "售后工单", teamAuth = true) +public class SealFaultServiceImpl extends SkyeyeBusinessServiceImpl implements SealFaultService { + + @Autowired + private SealFaultUseMaterialService sealFaultUseMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private ServiceUserStockService serviceUserStockService; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySealFaultList(commonPageInfo); + return beans; + } + + @Override + public void createPrepose(SealFault entity) { + check(entity); + getAllPrice(entity); + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getServiceClassName(), business); + entity.setOddNumber(oddNumber); + } + + @Override + public void updatePrepose(SealFault entity) { + check(entity); + getAllPrice(entity); + // 回退数量 + String userId = InputObject.getLogParamsStatic().get("id").toString(); + revertNum(entity.getId(), userId); + } + + @Override + protected void deletePreExecution(SealFault entity) { + // 回退数量 + String userId = InputObject.getLogParamsStatic().get("id").toString(); + revertNum(entity.getId(), userId); + } + + @Override + public void writePostpose(SealFault entity, String userId) { + if (CollectionUtil.isNotEmpty(entity.getSealFaultUseMaterialList())) { + sealFaultUseMaterialService.saveLinkList(entity.getId(), entity.getSealFaultUseMaterialList()); + // 出库 + for (SealFaultUseMaterial item : entity.getSealFaultUseMaterialList()) { + serviceUserStockService.editMaterialNormsUserStock(userId, item.getMaterialId(), item.getNormsId(), + item.getOperNumber(), UserStockPutOutType.OUT.getKey()); + } + } + super.writePostpose(entity, userId); + } + + private static void check(SealFault entity) { + if (CollectionUtil.isEmpty(entity.getSealFaultUseMaterialList())) { + return; + } + // 校验 + List sealFaultUseMaterialList = entity.getSealFaultUseMaterialList(); + if (CollectionUtil.isNotEmpty(sealFaultUseMaterialList)) { + List normsIds = sealFaultUseMaterialList.stream().map(SealFaultUseMaterial::getNormsId).distinct().collect(Collectors.toList()); + if (sealFaultUseMaterialList.size() != normsIds.size()) { + throw new CustomException("单据中不允许存在重复的产品规格信息"); + } + } + } + + private void revertNum(String id, String userId) { + SealFault sealFault = selectById(id); + if (CollectionUtil.isEmpty(sealFault.getSealFaultUseMaterialList())) { + return; + } + sealFault.getSealFaultUseMaterialList().forEach(sealFaultUseMaterial -> { + serviceUserStockService.editMaterialNormsUserStock(userId, sealFaultUseMaterial.getMaterialId(), sealFaultUseMaterial.getNormsId(), + sealFaultUseMaterial.getOperNumber(), UserStockPutOutType.PUT.getKey()); + }); + } + + private void getAllPrice(SealFault entity) { + String materialCost = sealFaultUseMaterialService.calcOrderAllTotalPrice(entity.getSealFaultUseMaterialList()); + entity.setMaterialCost(materialCost); + String allPrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, materialCost, entity.getCoverCost(), entity.getOtherCost()); + entity.setAllPrice(allPrice); + } + + @Override + public SealFault getDataFromDb(String id) { + SealFault sealFault = super.getDataFromDb(id); + + List sealFaultUseMaterialList = sealFaultUseMaterialService.selectByPId(sealFault.getId()); + sealFault.setSealFaultUseMaterialList(sealFaultUseMaterialList); + + return sealFault; + } + + @Override + public SealFault selectById(String id) { + SealFault sealFault = super.selectById(id); + if (CollectionUtil.isNotEmpty(sealFault.getSealFaultUseMaterialList())) { + // 产品信息 + iMaterialService.setDataMation(sealFault.getSealFaultUseMaterialList(), SealFaultUseMaterial::getMaterialId); + // 规格信息 + iMaterialNormsService.setDataMation(sealFault.getSealFaultUseMaterialList(), SealFaultUseMaterial::getNormsId); + List normsIds = sealFault.getSealFaultUseMaterialList().stream().map(SealFaultUseMaterial::getNormsId).collect(Collectors.toList()); + // 获取我的库存信息 + Map serviceUserStockMap = serviceUserStockService.queryUserStock(sealFault.getCreateId(), normsIds); + sealFault.getSealFaultUseMaterialList().forEach(sealFaultUseMaterial -> { + sealFaultUseMaterial.setServiceUserStock(serviceUserStockMap.get(sealFaultUseMaterial.getNormsId())); + }); + } + + return sealFault; + } +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultUseMaterialServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultUseMaterialServiceImpl.java new file mode 100644 index 0000000..1faed6f --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFaultUseMaterialServiceImpl.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.google.common.base.Joiner; +import com.skyeye.accessory.entity.ServiceUserStock; +import com.skyeye.accessory.service.ServiceUserStockService; +import com.skyeye.afterseal.dao.SealFaultUseMaterialDao; +import com.skyeye.afterseal.entity.SealFaultUseMaterial; +import com.skyeye.afterseal.service.SealFaultUseMaterialService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeLinkDataServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealFaultUseMaterialServiceImpl + * @Description: 售后服务故障配件使用信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/12 21:37 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "售后服务故障配件使用信息", groupName = "售后工单", manageShow = false) +public class SealFaultUseMaterialServiceImpl extends SkyeyeLinkDataServiceImpl implements SealFaultUseMaterialService { + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private ServiceUserStockService serviceUserStockService; + + @Override + protected void checkLinkList(String pId, List beans) { + if (CollectionUtil.isEmpty(beans)) { + return; + } + List normsId = beans.stream().map(SealFaultUseMaterial::getNormsId).collect(Collectors.toList()); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + Map userStockMap = serviceUserStockService.queryUserStock(userId, normsId); + beans.forEach(bean -> { + ServiceUserStock serviceUserStock = userStockMap.get(bean.getNormsId()); + if (ObjectUtil.isEmpty(serviceUserStock)) { + throw new CustomException("部分配件库存不足,请重新选择配件!"); + } + if (bean.getOperNumber() > serviceUserStock.getStock()) { + throw new CustomException("部分配件库存不足,请重新选择配件!"); + } + }); + } + + @Override + public String calcOrderAllTotalPrice(List sealFaultUseMaterials) { + String allPrice = "0"; + if (CollectionUtil.isEmpty(sealFaultUseMaterials)) { + return allPrice; + } + List normsIds = sealFaultUseMaterials.stream().map(SealFaultUseMaterial::getNormsId).collect(Collectors.toList()); + Map> normsMap = iMaterialNormsService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIds)); + + for (SealFaultUseMaterial sealFaultUseMaterial : sealFaultUseMaterials) { + // 子单据总价:使用数量 * 零售价 + Map norms = normsMap.get(sealFaultUseMaterial.getNormsId()); + sealFaultUseMaterial.setUnitPrice(norms.get("retailPrice").toString()); + sealFaultUseMaterial.setAllPrice( + CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(sealFaultUseMaterial.getOperNumber()), sealFaultUseMaterial.getUnitPrice())); + // 计算主单总价 + allPrice = CalculationUtil.add(CommonNumConstants.NUM_TWO, sealFaultUseMaterial.getAllPrice(), allPrice); + } + return allPrice; + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFeedBackServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFeedBackServiceImpl.java new file mode 100644 index 0000000..ddcee2e --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealFeedBackServiceImpl.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import com.skyeye.afterseal.dao.SealFeedBackDao; +import com.skyeye.afterseal.entity.SealFeedBack; +import com.skyeye.afterseal.service.SealFeedBackService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealFeedBackServiceImpl + * @Description: 工单情况反馈信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 15:21 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "工单情况反馈信息", groupName = "售后工单", teamAuth = true) +public class SealFeedBackServiceImpl extends SkyeyeBusinessServiceImpl implements SealFeedBackService { + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryFeedBackList(commonPageInfo); + return beans; + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealSignServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealSignServiceImpl.java new file mode 100644 index 0000000..9b49c62 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/afterseal/service/impl/SealSignServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.afterseal.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.skyeye.afterseal.classenum.AfterSealState; +import com.skyeye.afterseal.dao.SealSignDao; +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.afterseal.entity.SealSign; +import com.skyeye.afterseal.service.AfterSealService; +import com.skyeye.afterseal.service.SealSignService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealSignServiceImpl + * @Description: 工人签到信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 13:26 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "工人签到信息", groupName = "售后工单") +public class SealSignServiceImpl extends SkyeyeBusinessServiceImpl implements SealSignService { + + @Autowired + private AfterSealService afterSealService; + + @Override + protected List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySealSignList(commonPageInfo); + return beans; + } + + @Override + protected void validatorEntity(SealSign entity) { + AfterSeal afterSeal = afterSealService.selectById(entity.getObjectId()); + if (StrUtil.equals(afterSeal.getState(), AfterSealState.BE_SIGNED.getKey())) { + // 待签到可以进行签到 + } else { + throw new CustomException("该工单已经签到。"); + } + } + + @Override + protected void createPrepose(SealSign entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + entity.setSignId(userId); + entity.setSignTime(DateUtil.getTimeAndToString()); + } + + @Override + protected void createPostpose(SealSign entity, String userId) { + // 修改工单信息为【待完成】 + afterSealService.updateStateById(entity.getObjectId(), AfterSealState.BE_COMPLETED.getKey()); + } +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/mq/job/impl/WatiWorkerSendServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/mq/job/impl/WatiWorkerSendServiceImpl.java new file mode 100644 index 0000000..4ec763f --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/mq/job/impl/WatiWorkerSendServiceImpl.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.mq.job.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.google.common.base.Joiner; +import com.skyeye.afterseal.entity.AfterSeal; +import com.skyeye.afterseal.service.AfterSealService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.MqConstants; +import com.skyeye.common.enumeration.NoticeUserMessageTypeEnum; +import com.skyeye.common.util.MailUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.constants.SealConstants; +import com.skyeye.eve.rest.mq.JobMateUpdateMation; +import com.skyeye.eve.rest.notice.UserMessage; +import com.skyeye.eve.service.IAuthUserService; +import com.skyeye.eve.service.IJobMateMationService; +import com.skyeye.eve.service.IUserNoticeService; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WatiWorkerSendServiceImpl + * @Description: 派工通知 + * @author: skyeye云系列--卫志强 + * @date: 2021/7/6 22:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +@RocketMQMessageListener( + topic = "${topic.wati-worker-send-service}", + consumerGroup = "${topic.wati-worker-send-service}", + selectorExpression = "${spring.profiles.active}") +public class WatiWorkerSendServiceImpl implements RocketMQListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(WatiWorkerSendServiceImpl.class); + + @Autowired + private AfterSealService afterSealService; + + @Autowired + private IJobMateMationService iJobMateMationService; + + @Autowired + private IAuthUserService iAuthUserService; + + @Autowired + private IUserNoticeService iUserNoticeService; + + @Override + public void onMessage(String data) { + Map map = JSONUtil.toBean(data, null); + String jobId = map.get("jobMateId").toString(); + try { + // 任务开始 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_PROCESSING, StrUtil.EMPTY); + // 工单id + String serviceId = map.get("serviceId").toString(); + // 获取工单接收人和协助人id + AfterSeal afterSeal = afterSealService.selectById(serviceId); + // 如果工单信息不为空 + if (ObjectUtil.isNotEmpty(afterSeal)) { + // 调用消息系统添加通知 + List userMessageBoxList = new ArrayList<>(); + String content; + // 1.接收人通知 + if (StrUtil.isNotEmpty(afterSeal.getServiceUserId())) { + Map userMation = iAuthUserService.queryDataMationById(afterSeal.getServiceUserId()); + // 1.1内部消息 + content = SealConstants.getNoticeServiceUserContent(afterSeal.getOddNumber(), userMation.get("name").toString()); + + UserMessage userMessage = getUserNotice(afterSeal.getServiceUserId(), content); + userMessageBoxList.add(userMessage); + + // 1.2发送邮件 + String email = userMation.get("email").toString(); + if (ToolUtil.isEmail(email) && !ToolUtil.isBlank(email)) { + new MailUtil().send(email, "工单派工提醒", content); + } + } + // 2.协助人通知 + if (CollectionUtil.isNotEmpty(afterSeal.getCooperationUserId())) { + // 获取协助人 + List> cooperationUser = iAuthUserService + .queryDataMationByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(afterSeal.getCooperationUserId())); + + for (Map user : cooperationUser) { + // 2.1内部消息 + content = SealConstants.getNoticeCooperationUserContent(afterSeal.getOddNumber(), user.get("name").toString()); + UserMessage userMessage = getUserNotice(user.get("id").toString(), content); + userMessageBoxList.add(userMessage); + // 2.2发送邮件 + String email = user.get("email").toString(); + if (ToolUtil.isEmail(email) && !ToolUtil.isBlank(email)) { + new MailUtil().send(email, "工单派工提醒", content); + } + } + } + if (!userMessageBoxList.isEmpty()) { + iUserNoticeService.insertUserNoticeMation(userMessageBoxList); + } + } + // 任务完成 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_SUCCESS, StrUtil.EMPTY); + } catch (Exception e) { + LOGGER.warn("Dispatch notice failed, reason is {}.", e); + // 任务失败 + updateJobMation(jobId, MqConstants.JOB_TYPE_IS_FAIL, StrUtil.EMPTY); + } + } + + private UserMessage getUserNotice(String userId, String content) { + UserMessage userMessage = new UserMessage(); + userMessage.setName("工单派工提醒"); + userMessage.setRemark("您有一条新的派工信息,请及时阅读。"); + userMessage.setContent(content); + userMessage.setReceiveId(userId); + userMessage.setType(NoticeUserMessageTypeEnum.WORK_ORDER_REMINDER.getKey()); + userMessage.setCreateUserId(CommonConstants.ADMIN_USER_ID); + return userMessage; + } + + private void updateJobMation(String jobId, String status, String responseBody) { + JobMateUpdateMation jobMateUpdateMation = new JobMateUpdateMation(); + jobMateUpdateMation.setJobId(jobId); + jobMateUpdateMation.setStatus(status); + jobMateUpdateMation.setResponseBody(responseBody); + iJobMateMationService.comMQJobMation(jobMateUpdateMation); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IDepotRest.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IDepotRest.java new file mode 100644 index 0000000..021f686 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IDepotRest.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.depot.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: IDepotRest + * @Description: 仓库信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-erp}", configuration = ClientConfiguration.class) +public interface IDepotRest { + + /** + * 根据id批量获取仓库信息 + * + * @param ids 主键id,多个用逗号隔开 + */ + @PostMapping("/queryDepotByIds") + String queryDepotByIds(@RequestParam("ids") String ids); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IERPOrderRest.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IERPOrderRest.java new file mode 100644 index 0000000..4c0b476 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/rest/IERPOrderRest.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.depot.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: IERPOrderRest + * @Description: ERP订单接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/19 18:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-erp}", configuration = ClientConfiguration.class) +public interface IERPOrderRest { + + /** + * 将单据信息新增到ERP中 + * + * @param params 单据信息 + */ + @PostMapping("/createApprovelSuccessOrder") + String createApprovelSuccessOrder(Map params); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/IDepotService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/IDepotService.java new file mode 100644 index 0000000..7814959 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/IDepotService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.depot.service; + +import com.skyeye.base.rest.service.IService; + +/** + * @ClassName: IDepotService + * @Description: 仓库信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IDepotService extends IService { + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/impl/IDepotServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/impl/IDepotServiceImpl.java new file mode 100644 index 0000000..028cae2 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/rest/depot/service/impl/IDepotServiceImpl.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.depot.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.rest.depot.rest.IDepotRest; +import com.skyeye.rest.depot.service.IDepotService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: IDepotServiceImpl + * @Description: 仓库信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IDepotServiceImpl extends IServiceImpl implements IDepotService { + + @Autowired + private IDepotRest iDepotRest; + + @Override + public Map queryEntityMationById(String id) { + return queryEntityMationByIds(id).stream().findFirst().orElse(new HashMap<>()); + } + + @Override + public List> queryEntityMationByIds(String ids) { + return ExecuteFeignClient.get(() -> iDepotRest.queryDepotByIds(ids)).getRows(); + } + + @Override + public String queryCacheKeyById(String id) { + return String.format(Locale.ROOT, "%s:%s", CacheConstants.ERP_DEPOT_CACHE_KEY, id); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/controller/SealWorkerController.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/controller/SealWorkerController.java new file mode 100644 index 0000000..f504aa0 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/controller/SealWorkerController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worker.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.worker.entity.SealWorker; +import com.skyeye.worker.service.SealWorkerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: SealWorkerController + * @Description: 工人管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 19:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "工人管理", tags = "工人管理", modelName = "工人管理") +public class SealWorkerController { + + @Autowired + private SealWorkerService sealWorkerService; + + /** + * 获取工人信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "sealseserviceworker001", value = "获取工人信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/SealWorkerController/querySealWorkerList") + public void querySealWorkerList(InputObject inputObject, OutputObject outputObject) { + sealWorkerService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑工人资料信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeSealWorker", value = "新增/编辑工人资料信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SealWorker.class) + @RequestMapping("/post/SealWorkerController/writeSealWorker") + public void writeSealWorker(InputObject inputObject, OutputObject outputObject) { + sealWorkerService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除工人资料信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteSealWorkerById", value = "删除工人资料信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/SealWorkerController/deleteSealWorkerById") + public void deleteSealWorkerById(InputObject inputObject, OutputObject outputObject) { + sealWorkerService.deleteById(inputObject, outputObject); + } + + /** + * 获取所有工人信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllSealWorkerList", value = "获取所有工人信息", method = "GET", allUse = "2") + @RequestMapping("/post/SealWorkerController/queryAllSealWorkerList") + public void queryAllSealWorkerList(InputObject inputObject, OutputObject outputObject) { + sealWorkerService.queryAllSealWorkerList(inputObject, outputObject); + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/dao/SealWorkerDao.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/dao/SealWorkerDao.java new file mode 100644 index 0000000..0cd01af --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/dao/SealWorkerDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worker.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.worker.entity.SealWorker; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SealWorkerDao + * @Description: 工人信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 20:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SealWorkerDao extends SkyeyeBaseMapper { + + List> querySealWorkerList(CommonPageInfo commonPageInfo); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/entity/SealWorker.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/entity/SealWorker.java new file mode 100644 index 0000000..f7d9291 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/entity/SealWorker.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worker.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.AreaInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: SealWorker + * @Description: 工人管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 19:04 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@RedisCacheField(name = "seal:worker", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "crm_service_worker", autoResultMap = true) +@ApiModel("工人管理实体类") +public class SealWorker extends AreaInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @Property(value = "名称") + private String name; + + @TableField(value = "user_id") + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @TableField(exist = false) + @Property(value = "用户信息") + private Map userMation; + + @TableField(value = "longitude") + @ApiModelProperty(value = "经度") + private String longitude; + + @TableField(value = "latitude") + @ApiModelProperty(value = "纬度") + private String latitude; + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/SealWorkerService.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/SealWorkerService.java new file mode 100644 index 0000000..32f6f9f --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/SealWorkerService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worker.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.worker.entity.SealWorker; + +/** + * @ClassName: SealWorkerService + * @Description: 工人管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 19:01 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface SealWorkerService extends SkyeyeBusinessService { + + void queryAllSealWorkerList(InputObject inputObject, OutputObject outputObject); + + SealWorker selectByUserId(String userId); + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/impl/SealWorkerServiceImpl.java b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/impl/SealWorkerServiceImpl.java new file mode 100644 index 0000000..733ca64 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/java/com/skyeye/worker/service/impl/SealWorkerServiceImpl.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.worker.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.worker.dao.SealWorkerDao; +import com.skyeye.worker.entity.SealWorker; +import com.skyeye.worker.service.SealWorkerService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: SealWorkerServiceImpl + * @Description: 工人信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 20:51 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "工人管理", groupName = "工人管理") +public class SealWorkerServiceImpl extends SkyeyeBusinessServiceImpl implements SealWorkerService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.querySealWorkerList(commonPageInfo); + iAuthUserService.setMationForMap(beans, "userId", "userMation"); + return beans; + } + + @Override + public void validatorEntity(SealWorker entity) { + super.validatorEntity(entity); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SealWorker::getUserId), entity.getUserId()); + if (StringUtils.isNotEmpty(entity.getId())) { + queryWrapper.ne(CommonConstants.ID, entity.getId()); + } + SealWorker one = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(one)) { + throw new CustomException("该账号已为工人帐号."); + } + } + + @Override + public SealWorker selectById(String id) { + SealWorker sealWorker = super.selectById(id); + iAuthUserService.setDataMation(sealWorker, SealWorker::getUserId); + if (CollectionUtil.isNotEmpty(sealWorker.getUserMation())) { + sealWorker.setName(sealWorker.getUserMation().get("name").toString()); + } + return sealWorker; + } + + /** + * 获取所有工人信息供展示选择 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllSealWorkerList(InputObject inputObject, OutputObject outputObject) { + List sealWorkerList = list(); + List userIds = sealWorkerList.stream().map(SealWorker::getUserId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(userIds)) { + return; + } + iAuthUserService.setDataMation(sealWorkerList, SealWorker::getUserId); + outputObject.setBeans(sealWorkerList); + outputObject.settotal(sealWorkerList.size()); + } + + @Override + public SealWorker selectByUserId(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SealWorker::getUserId), userId); + SealWorker sealWorker = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(sealWorker)) { + iAuthUserService.setDataMation(sealWorker, SealWorker::getUserId); + if (CollectionUtil.isNotEmpty(sealWorker.getUserMation())) { + sealWorker.setName(sealWorker.getUserMation().get("name").toString()); + } + } + return sealWorker; + } + +} diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/AfterSealMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/AfterSealMapper.xml new file mode 100644 index 0000000..6eb5c18 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/AfterSealMapper.xml @@ -0,0 +1,51 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealEvaluateMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealEvaluateMapper.xml new file mode 100644 index 0000000..41091bd --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealEvaluateMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFaultMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFaultMapper.xml new file mode 100644 index 0000000..1cc5223 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFaultMapper.xml @@ -0,0 +1,40 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFeedBackMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFeedBackMapper.xml new file mode 100644 index 0000000..a2f2e41 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealFeedBackMapper.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealSignMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealSignMapper.xml new file mode 100644 index 0000000..47daf1f --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/afterSeal/SealSignMapper.xml @@ -0,0 +1,26 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/worker/SealWorkerMapper.xml b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/worker/SealWorkerMapper.xml new file mode 100644 index 0000000..6fd9093 --- /dev/null +++ b/skyeye-seal-service/seal-service-pro/src/main/resources/mapper/worker/SealWorkerMapper.xml @@ -0,0 +1,30 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-web/.gitignore b/skyeye-seal-service/seal-service-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-seal-service/seal-service-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-web/pom.xml b/skyeye-seal-service/seal-service-web/pom.xml new file mode 100644 index 0000000..f901937 --- /dev/null +++ b/skyeye-seal-service/seal-service-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-seal-service + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + seal-service-web + + + 8 + 8 + + + + + + com.skyeye + seal-service-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-web/src/main/java/com/SealServiceApplication.java b/skyeye-seal-service/seal-service-web/src/main/java/com/SealServiceApplication.java new file mode 100644 index 0000000..4b86a77 --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/java/com/SealServiceApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class SealServiceApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SealServiceApplication.class, args); + } + +} diff --git a/skyeye-seal-service/seal-service-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-seal-service/seal-service-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..049e97f --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-seal-service/seal-service-web/src/main/resources/banner.txt b/skyeye-seal-service/seal-service-web/src/main/resources/banner.txt new file mode 100644 index 0000000..303b500 --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev seal-service-web.jar >> /opt/service/project/nohup-seal-service.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-seal-service/seal-service-web/src/main/resources/bootstrap.yml b/skyeye-seal-service/seal-service-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..eac990c --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/resources/bootstrap.yml @@ -0,0 +1,52 @@ +server: + port: 8108 + +spring: + application: + name: skyeye-seal-service-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # ERP相关的服务 + skyeye-erp: skyeye-erp-${spring.profiles.active} + +topic: + # 派工通知的topic + wati-worker-send-service: WATI_WORKER_SEND_SERVICE + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-seal-service/seal-service-web/src/main/resources/jvm调优参数配置 b/skyeye-seal-service/seal-service-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-seal-service/seal-service-web/src/main/resources/log4j.properties b/skyeye-seal-service/seal-service-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-seal-service/seal-service-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-shop/.gitignore b/skyeye-shop/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/pom.xml b/skyeye-shop/pom.xml new file mode 100644 index 0000000..3e3add0 --- /dev/null +++ b/skyeye-shop/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-shop + 0.0.1-SNAPSHOT + pom + + + shop-common + shop-web + shop-entity + shop-member + shop-store + + + \ No newline at end of file diff --git a/skyeye-shop/shop-common/.gitignore b/skyeye-shop/shop-common/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/shop-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/shop-common/pom.xml b/skyeye-shop/shop-common/pom.xml new file mode 100644 index 0000000..e129b5b --- /dev/null +++ b/skyeye-shop/shop-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-shop + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + shop-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/rest/IMaterialNormsCodeRest.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/rest/IMaterialNormsCodeRest.java new file mode 100644 index 0000000..285d797 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/rest/IMaterialNormsCodeRest.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.norms.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: IMaterialNormsCodeRest + * @Description: ERP物料规格条形码信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-erp}", configuration = ClientConfiguration.class) +public interface IMaterialNormsCodeRest { + + /** + * 根据编码等信息查询门店规格条形码信息 + * + * @param params 参数信息: + * storeId:门店id--必填 + * normsCodeList:规格编码,多个用逗号隔开--必填 + * storeUseState:门店使用状态--非必填 + */ + @PostMapping("/queryMaterialNormsCode") + String queryMaterialNormsCode(Map params); + + /** + * 根据编码等信息修改门店规格条形码使用状态 + * + * @param params 参数信息: + * ids:规格条形码信息id,多个逗号隔开--必填 + * storeUseState:门店使用状态--必填 + */ + @PostMapping("/editStoreMaterialNormsCodeUseState") + String editStoreMaterialNormsCodeUseState(Map params); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/IMaterialNormsCodeService.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/IMaterialNormsCodeService.java new file mode 100644 index 0000000..10e40c7 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/IMaterialNormsCodeService.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.norms.service; + +import com.skyeye.base.rest.service.IService; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IMaterialNormsCodeService + * @Description: ERP物料规格条形码信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IMaterialNormsCodeService extends IService { + + List> queryMaterialNormsCode(String storeId, List normsCodeList, Integer storeUseState); + + void editStoreMaterialNormsCodeUseState(List ids, Integer storeUseState); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/service/IMaterialNormsCodeServiceImpl.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/service/IMaterialNormsCodeServiceImpl.java new file mode 100644 index 0000000..ad322f5 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/norms/service/service/IMaterialNormsCodeServiceImpl.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.norms.service.service; + +import com.google.common.base.Joiner; +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.rest.norms.rest.IMaterialNormsCodeRest; +import com.skyeye.rest.norms.service.IMaterialNormsCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IMaterialNormsCodeServiceImpl + * @Description: ERP物料规格条形码信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IMaterialNormsCodeServiceImpl extends IServiceImpl implements IMaterialNormsCodeService { + + @Autowired + private IMaterialNormsCodeRest iMaterialNormsCodeRest; + + @Override + public List> queryMaterialNormsCode(String storeId, List normsCodeList, Integer storeUseState) { + Map params = new HashMap<>(); + params.put("storeId", storeId); + params.put("normsCodeList", Joiner.on(CommonCharConstants.COMMA_MARK).join(normsCodeList)); + params.put("storeUseState", storeUseState); + return ExecuteFeignClient.get(() -> iMaterialNormsCodeRest.queryMaterialNormsCode(params)).getRows(); + } + + @Override + public void editStoreMaterialNormsCodeUseState(List ids, Integer storeUseState) { + Map params = new HashMap<>(); + params.put("ids", Joiner.on(CommonCharConstants.COMMA_MARK).join(ids)); + params.put("storeUseState", storeUseState); + ExecuteFeignClient.get(() -> iMaterialNormsCodeRest.editStoreMaterialNormsCodeUseState(params)).getRows(); + } + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/rest/IPayRest.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/rest/IPayRest.java new file mode 100644 index 0000000..fba15c7 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/rest/IPayRest.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.pay.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: IPayRest + * @Description: 支付接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface IPayRest { + + @PostMapping("/payment") + String payment(Map params); + + @PostMapping("/generatePayRrCode") + String generatePayRrCode(Map params); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/IPayService.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/IPayService.java new file mode 100644 index 0000000..39f3973 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/IPayService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.pay.service; + +import com.skyeye.base.rest.service.IService; +import com.skyeye.common.object.ResultEntity; + +import java.util.Map; + +/** + * @ClassName: IPayService + * @Description: 支付接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface IPayService extends IService { + + ResultEntity payment(Map data, String channelCode, String returnUrl, String channelExtras, String notifyUrl); + + /** + * 生成支付二维码 + * + * @param data 订单数据 + * @param channelCode 支付渠道 + * @param ip 支付请求的IP地址 + * @param notifyUrl 支付结果通知地址 + * @return + */ + Map generatePayRrCode(Map data, String channelCode, String ip, String notifyUrl); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/impl/IPayServiceImpl.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/impl/IPayServiceImpl.java new file mode 100644 index 0000000..523869c --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/pay/service/impl/IPayServiceImpl.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.pay.service.impl; + +import cn.hutool.json.JSONUtil; +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.object.ResultEntity; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.rest.pay.rest.IPayRest; +import com.skyeye.rest.pay.service.IPayService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: IPayServiceImpl + * @Description: 支付接口实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 9:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class IPayServiceImpl extends IServiceImpl implements IPayService { + + @Autowired + private IPayRest iPayRest; + + @Override + public ResultEntity payment(Map data, String channelCode, String returnUrl, String channelExtras, String notifyUrl) { + // 支付金额单位转换为分 + String payPrice = data.get("payPrice").toString(); + payPrice = CalculationUtil.multiply(payPrice, "100"); + data.put("payPrice", payPrice); + Map params = new HashMap<>(); + params.put("data", JSONUtil.toJsonStr(data)); + params.put("channelCode", channelCode); + params.put("returnUrl", returnUrl); + params.put("channelExtras", channelExtras); + params.put("notifyUrl", notifyUrl); + + return ExecuteFeignClient.get(() -> iPayRest.payment(params)); + } + + @Override + public Map generatePayRrCode(Map data, String channelCode, String ip, String notifyUrl) { + Map params = new HashMap<>(); + params.put("data", JSONUtil.toJsonStr(data)); + params.put("channelCode", channelCode); + params.put("ip", ip); + params.put("notifyUrl", notifyUrl); + + return ExecuteFeignClient.get(() -> iPayRest.generatePayRrCode(params)).getBean(); + } +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/rest/IShopMaterialNormsRest.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/rest/IShopMaterialNormsRest.java new file mode 100644 index 0000000..1d2e7a6 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/rest/IShopMaterialNormsRest.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shopmaterialnorms.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: IShopMaterialNormsRest + * @Description: ERP商城购物车信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-erp}", configuration = ClientConfiguration.class) +public interface IShopMaterialNormsRest { + + @PostMapping("/queryShopMaterialByNormsIdList") + String queryShopMaterialByNormsIdList(@RequestParam("normsIds") String normsIds); + + @PostMapping("/queryShopMaterialByMaterialIdList") + String queryShopMaterialByMaterialIdList(@RequestParam("materialIds") String materialIds); + + /** + * 根据id批量获取商城商品信息 + * + * @param ids 主键id,多个逗号隔开 + * @return + */ + @PostMapping("/queryShopMaterialByIds") + String queryShopMaterialByIds(@RequestParam("ids") String ids); + + /** + * 新增门店时,将所有商品同步到该门店 + * + * @param storeId 门店id + * @return + */ + @PostMapping("/saveShopMaterialStore") + String saveShopMaterialStore(@RequestParam("storeId") String storeId); + + /** + * 获取商城商品信息列表供选择 + * + * @return + */ + @GetMapping("/queryAllShopMaterialListForChoose") + String queryAllShopMaterialListForChoose(); +} \ No newline at end of file diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/IShopMaterialNormsService.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/IShopMaterialNormsService.java new file mode 100644 index 0000000..075f871 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/IShopMaterialNormsService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shopmaterialnorms.sevice; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IShopMaterialNormsService + * @Description: ERP商城购物车信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface IShopMaterialNormsService { + List> queryShopMaterialByNormsIdList(String normsIds); + + List> queryShopMaterialByMaterialIdList(String materialIds); + + /** + * 根据id批量获取商城商品信息 + * + * @param ids 商城商品materialId与storeId的关系id + * @return + */ + List> queryShopMaterialByIds(List ids); + + List> queryAllShopMaterialListForChoose(); +} \ No newline at end of file diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/service/IShopMaterialNormsServiceImpl.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/service/IShopMaterialNormsServiceImpl.java new file mode 100644 index 0000000..678abd7 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/shopmaterialnorms/sevice/service/IShopMaterialNormsServiceImpl.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.shopmaterialnorms.sevice.service; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Joiner; +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.object.ResultEntity; +import com.skyeye.rest.shopmaterialnorms.rest.IShopMaterialNormsRest; +import com.skyeye.rest.shopmaterialnorms.sevice.IShopMaterialNormsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: IShopMaterialNormsServiceImpl + * @Description: ERP商城购物车信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class IShopMaterialNormsServiceImpl extends IServiceImpl implements IShopMaterialNormsService { + + @Autowired + private IShopMaterialNormsRest iShopMaterialNormsRest; + + @Override + public List> queryShopMaterialByNormsIdList(String normsIds) { + ResultEntity resultEntity = ExecuteFeignClient.get(() -> iShopMaterialNormsRest.queryShopMaterialByNormsIdList(normsIds)); + List> rows = resultEntity.getRows(); + return rows; + } + + @Override + public List> queryShopMaterialByMaterialIdList(String materialIds) { + ResultEntity resultEntity = ExecuteFeignClient.get(() -> iShopMaterialNormsRest.queryShopMaterialByMaterialIdList(materialIds)); + List> rows = resultEntity.getRows(); + return rows; + } + + @Override + public List> queryShopMaterialByIds(List ids) { + if (ids == null) { + return new ArrayList<>(); + } + ids = ids.stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return new ArrayList<>(); + } + String joinIds = Joiner.on(CommonCharConstants.COMMA_MARK).join(ids); + ResultEntity resultEntity = ExecuteFeignClient.get(() -> iShopMaterialNormsRest.queryShopMaterialByIds(joinIds)); + List> rows = resultEntity.getRows(); + return rows; + } + + @Override + public List> queryAllShopMaterialListForChoose() { + ResultEntity resultEntity = ExecuteFeignClient.get(() -> iShopMaterialNormsRest.queryAllShopMaterialListForChoose()); + List> rows = resultEntity.getRows(); + return rows; + } +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/rest/ISmsCodeRest.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/rest/ISmsCodeRest.java new file mode 100644 index 0000000..e44fa1f --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/rest/ISmsCodeRest.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.sms.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: ISmsCodeRest + * @Description: 短信验证码接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 16:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface ISmsCodeRest { + + @PostMapping("/sendSmsCodeReq") + String sendSmsCodeReq(Map params); + + @PostMapping("/validateSmsCode") + String validateSmsCode(Map params); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/ISmsCodeService.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/ISmsCodeService.java new file mode 100644 index 0000000..9330440 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/ISmsCodeService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.sms.service; + +import com.skyeye.base.rest.service.IService; + +/** + * @ClassName: ISmsCodeService + * @Description: 短信验证码服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 16:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ISmsCodeService extends IService { + + void sendSmsCodeReq(String mobile, Integer scene); + + void validateSmsCode(String mobile, String smsCode, Integer scene); + +} diff --git a/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/impl/ISmsCodeServiceImpl.java b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/impl/ISmsCodeServiceImpl.java new file mode 100644 index 0000000..e5d9aeb --- /dev/null +++ b/skyeye-shop/shop-common/src/main/java/com/skyeye/rest/sms/service/impl/ISmsCodeServiceImpl.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.sms.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.rest.sms.rest.ISmsCodeRest; +import com.skyeye.rest.sms.service.ISmsCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: ISmsCodeServiceImpl + * @Description: 短信验证码服务接口实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 16:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ISmsCodeServiceImpl extends IServiceImpl implements ISmsCodeService { + + @Autowired + private ISmsCodeRest iSmsCodeRest; + + @Override + public void sendSmsCodeReq(String mobile, Integer scene) { + Map params = new HashMap<>(); + params.put("mobile", mobile); + params.put("scene", scene); + ExecuteFeignClient.get(() -> iSmsCodeRest.sendSmsCodeReq(params)).getRows(); + } + + @Override + public void validateSmsCode(String mobile, String smsCode, Integer scene) { + Map params = new HashMap<>(); + params.put("mobile", mobile); + params.put("smsCode", smsCode); + params.put("scene", scene); + ExecuteFeignClient.get(() -> iSmsCodeRest.validateSmsCode(params)).getRows(); + } +} diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/db2.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/db2.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/db2.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/h2.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/h2.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/hsql.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/hsql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/mssql.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/mssql.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/mssql.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/mysql.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/mysql.properties new file mode 100644 index 0000000..e69de29 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/oracle.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/oracle.properties new file mode 100644 index 0000000..68983a1 --- /dev/null +++ b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/oracle.properties @@ -0,0 +1 @@ +boolValue=1 diff --git a/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/postgres.properties b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/postgres.properties new file mode 100644 index 0000000..abe3f3d --- /dev/null +++ b/skyeye-shop/shop-common/src/main/resources/org/flowable/db/properties/postgres.properties @@ -0,0 +1 @@ +blobType=BINARY diff --git a/skyeye-shop/shop-entity/.gitignore b/skyeye-shop/shop-entity/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/shop-entity/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/shop-entity/pom.xml b/skyeye-shop/shop-entity/pom.xml new file mode 100644 index 0000000..f0191d4 --- /dev/null +++ b/skyeye-shop/shop-entity/pom.xml @@ -0,0 +1,27 @@ + + + + skyeye-shop + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + shop-entity + + + 8 + 8 + + + + + com.skyeye + shop-common + 0.0.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-entity/src/main/java/com/skyeye/entity/intercourse/StoreIntercourseQueryDo.java b/skyeye-shop/shop-entity/src/main/java/com/skyeye/entity/intercourse/StoreIntercourseQueryDo.java new file mode 100644 index 0000000..d4b9c38 --- /dev/null +++ b/skyeye-shop/shop-entity/src/main/java/com/skyeye/entity/intercourse/StoreIntercourseQueryDo.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity.intercourse; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.search.CommonPageInfo; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName: StoreIntercourseQueryDo + * @Description: 门店的支出/收入往来列表查询实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/6/29 22:12 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("门店的支出/收入往来列表查询实体类") +public class StoreIntercourseQueryDo extends CommonPageInfo implements Serializable { + + @ApiModelProperty(value = "保养门店id") + private String keepfitStoreId; + + @ApiModelProperty(value = "保养门店名称") + private String keepfitStoreName; + + @ApiModelProperty(value = "套餐购买门店id") + private String mealByStoreId; + + @ApiModelProperty(value = "套餐购买门店名称") + private String mealByStoreName; + + @ApiModelProperty(value = "开始日期") + private String startTime; + + @ApiModelProperty(value = "结束日期") + private String endTime; + + /** + * 单据往来日期,格式为yyyy-MM-dd + */ + private String day; + +} diff --git a/skyeye-shop/shop-member/.gitignore b/skyeye-shop/shop-member/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/shop-member/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/shop-member/pom.xml b/skyeye-shop/shop-member/pom.xml new file mode 100644 index 0000000..115e0d1 --- /dev/null +++ b/skyeye-shop/shop-member/pom.xml @@ -0,0 +1,27 @@ + + + + skyeye-shop + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + shop-member + + + 8 + 8 + + + + + com.skyeye + shop-entity + 0.0.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/MemberController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/MemberController.java new file mode 100644 index 0000000..70b7111 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/MemberController.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.entity.Member; +import com.skyeye.service.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MemberController + * @Description: 会员管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/2 15:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "会员管理", tags = "会员管理", modelName = "会员管理") +public class MemberController { + + @Autowired + private MemberService memberService; + + @ApiOperation(id = "member001", value = "获取会员信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MemberController/queryMemberByList") + public void queryMemberByList(InputObject inputObject, OutputObject outputObject) { + memberService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeMember", value = "添加/编辑会员信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Member.class) + @RequestMapping("/post/MemberController/writeMember") + public void writeMember(InputObject inputObject, OutputObject outputObject) { + memberService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryMemberById", value = "据ID查询会员信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MemberController/queryMemberById") + public void queryMemberById(InputObject inputObject, OutputObject outputObject) { + memberService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "queryMemberListById", value = "根据ID批量查询会员信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/MemberController/queryMemberListById") + public void queryMemberListById(InputObject inputObject, OutputObject outputObject) { + memberService.selectByIds(inputObject, outputObject); + } + + @ApiOperation(id = "member004", value = "删除会员信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MemberController/deleteMemberById") + public void deleteMemberById(InputObject inputObject, OutputObject outputObject) { + memberService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "queryMyWriteMemberList", value = "获取我录入的会员信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MemberController/queryMyWriteMemberList") + public void queryMyWriteMemberList(InputObject inputObject, OutputObject outputObject) { + memberService.queryMyWriteMemberList(inputObject, outputObject); + } + + @ApiOperation(id = "updateCurrentLoginMemberNickname", value = "修改当前登录用户的昵称", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "name", name = "name", value = "昵称", required = "required")}) + @RequestMapping("/post/MemberController/updateCurrentLoginMemberNickname") + public void updateCurrentLoginMemberNickname(InputObject inputObject, OutputObject outputObject) { + memberService.updateCurrentLoginMemberNickname(inputObject, outputObject); + } + + @ApiOperation(id = "updateCurrentLoginMemberAvatar", value = "修改当前登录用户的头像", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "avatar", name = "avatar", value = "头像地址", required = "required")}) + @RequestMapping("/post/MemberController/updateCurrentLoginMemberAvatar") + public void updateCurrentLoginMemberAvatar(InputObject inputObject, OutputObject outputObject) { + memberService.updateCurrentLoginMemberAvatar(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/ShopAppAuthController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/ShopAppAuthController.java new file mode 100644 index 0000000..f00d6d5 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/controller/ShopAppAuthController.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.service.ShopAppAuthService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopAppAuthController + * @Description: 商城登录管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 11:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商城登录管理", tags = "商城登录管理", modelName = "商城登录管理") +public class ShopAppAuthController { + + @Autowired + private ShopAppAuthService shopAppAuthService; + + @ApiOperation(id = "shopLoginForPC", value = "登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "phone", name = "phone", value = "手机号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/shopLoginForPC") + public void shopLoginForPC(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.shopLoginForPC(inputObject, outputObject); + } + + @ApiOperation(id = "shopLoginForApp", value = "手机端用户登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "phone", name = "phone", value = "手机号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required"), + @ApiImplicitParam(id = "cId", name = "cId", value = "cId,用于手机端消息通知")}) + @RequestMapping("/post/ShopAppAuthController/shopLoginForApp") + public void shopLoginForApp(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.shopLoginForApp(inputObject, outputObject); + } + + @ApiOperation(id = "shopLogout", value = "退出", method = "POST", allUse = "2") + @RequestMapping("/post/ShopAppAuthController/shopLogout") + public void shopLogout(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.shopLogout(inputObject, outputObject); + } + + @ApiOperation(id = "editShopUserPassword", value = "修改密码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "newPassword", name = "newPassword", value = "新密码", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/editShopUserPassword") + public void editShopUserPassword(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.editShopUserPassword(inputObject, outputObject); + } + + @ApiOperation(id = "editShopUserPasswordByPhone", value = "根据手机号修改密码", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "newPassword", name = "newPassword", value = "新密码", required = "required"), + @ApiImplicitParam(id = "phone", name = "phone", value = "手机号", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/editShopUserPasswordByPhone") + public void editShopUserPasswordByPhone(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.editShopUserPasswordByPhone(inputObject, outputObject); + } + + @ApiOperation(id = "sendShopSmsCode", value = "发送手机验证码", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mobile", name = "mobile", value = "手机号"), + @ApiImplicitParam(id = "scene", name = "scene", value = "发送场景,参考#SmsSceneEnum", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/sendShopSmsCode") + public void sendShopSmsCode(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.sendShopSmsCode(inputObject, outputObject); + } + + @ApiOperation(id = "smsShopLogin", value = "短信验证码登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mobile", name = "mobile", value = "手机号", required = "required"), + @ApiImplicitParam(id = "smsCode", name = "smsCode", value = "短信验证码", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/smsLsmsShopLoginogin") + public void smsShopLogin(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.smsShopLogin(inputObject, outputObject); + } + + @ApiOperation(id = "smsShopMemberRegister", value = "会员注册", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mobile", name = "mobile", value = "手机号", required = "required"), + @ApiImplicitParam(id = "smsCode", name = "smsCode", value = "短信验证码", required = "required")}) + @RequestMapping("/post/ShopAppAuthController/smsShopMemberRegister") + public void smsShopMemberRegister(InputObject inputObject, OutputObject outputObject) { + shopAppAuthService.smsShopMemberRegister(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/dao/MemberDao.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/dao/MemberDao.java new file mode 100644 index 0000000..225de2f --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/dao/MemberDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.entity.Member; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MemberDao + * @Description: 会员管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/2 15:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MemberDao extends SkyeyeBaseMapper { + + List> queryMemberByList(CommonPageInfo pageInfo); + + Long queryMemberByList_COUNT(CommonPageInfo pageInfo); + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/entity/Member.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/entity/Member.java new file mode 100644 index 0000000..874834c --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/entity/Member.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.base.handler.enclosure.bean.Enclosure; +import com.skyeye.common.base.handler.enclosure.bean.EnclosureFace; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.AreaInfo; +import com.skyeye.level.entity.ShopMemberLevel; +import com.skyeye.store.entity.ShopStore; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Member + * @Description: 会员实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/2 21:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField(value = {"phone"}) +@RedisCacheField(name = CacheConstants.SHOP_MEMBER_CACHE_KEY) +@TableName(value = "sys_member", autoResultMap = true) +@ApiModel("会员实体类") +public class Member extends AreaInfo implements EnclosureFace { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "avatar") + @ApiModelProperty(value = "头像") + private String avatar; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(value = "phone") + @ApiModelProperty(value = "联系电话", required = "required,phone") + private String phone; + + @TableField("password") + @ApiModelProperty(value = "密码") + private String password; + + @TableField("pwd_num_enc") + @Property(value = "用户密码加密次数") + private Integer pwdNumEnc; + + @TableField("level_id") + @Property(value = "会员等级id") + private String levelId; + + @TableField(exist = false) + @Property(value = "会员等级信息") + private ShopMemberLevel levelMation; + + @TableField("wechat_open_id") + @ApiModelProperty(value = "微信的openId") + private String wechatOpenId; + + @TableField(value = "email") + @ApiModelProperty(value = "电子邮箱", required = "email") + private String email; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "store_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "如果是门店工作人员录入,则为门店id") + private String storeId; + + @TableField(exist = false) + @ApiModelProperty(value = "门店信息") + private ShopStore storeMation; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @ApiModelProperty(value = "附件", required = "json") + private Enclosure enclosureInfo; + + @TableField(exist = false) + @Property(value = "用户token") + private String userToken; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/level/controller/ShopMemberLevelController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/controller/ShopMemberLevelController.java new file mode 100644 index 0000000..c7f6823 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/controller/ShopMemberLevelController.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.level.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.level.entity.ShopMemberLevel; +import com.skyeye.level.service.ShopMemberLevelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopMemberLevelController + * @Description: 会员等级控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "会员等级", tags = "会员等级", modelName = "会员等级") +public class ShopMemberLevelController { + + @Autowired + private ShopMemberLevelService shopMemberLevelService; + + @ApiOperation(id = "queryMemberLevelList", value = "分页获取会员等级信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopMemberLevelController/queryMemberLevelList") + public void queryMemberLevelList(InputObject inputObject, OutputObject outputObject) { + shopMemberLevelService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeMemberLevel", value = "添加/编辑会员等级", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopMemberLevel.class) + @RequestMapping("/post/ShopMemberLevelController/writeMemberLevel") + public void writeMemberLevel(InputObject inputObject, OutputObject outputObject) { + shopMemberLevelService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "deleteMemberLeveByIds", value = "批量删除会员等级信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/ShopMemberLevelController/deleteMemberLeveByIds") + public void deleteMemberLeveByIds(InputObject inputObject, OutputObject outputObject) { + shopMemberLevelService.deleteByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryMemberLevel", value = "获得所有已启用的会员等级列表", method = "POST", allUse = "0") + @RequestMapping("/post/ShopMemberLevelController/queryMemberLevel") + public void queryMemberLevel(InputObject inputObject, OutputObject outputObject) { + shopMemberLevelService.queryList(inputObject, outputObject); + } +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/level/dao/ShopMemberLevelDao.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/dao/ShopMemberLevelDao.java new file mode 100644 index 0000000..d3c5fea --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/dao/ShopMemberLevelDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.level.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.level.entity.ShopMemberLevel; + +/** + * @ClassName: ShopMemberLevelDao + * @Description: 会员等级数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMemberLevelDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/level/entity/ShopMemberLevel.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/entity/ShopMemberLevel.java new file mode 100644 index 0000000..580fcfa --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/entity/ShopMemberLevel.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.level.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ShopMemberLevel + * @Description: 会员级别实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "shop:memberLevel") +@TableName(value = "shop_member_level") +@ApiModel("会员级别实体类") +public class ShopMemberLevel extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "等级名称", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "`level`") + @ApiModelProperty(value = "等级", required = "required") + private Integer level; + + @TableField(value = "`experience`") + @ApiModelProperty(value = "升级经验", required = "required") + private Integer experience; + + @TableField(value = "`discount_percent`") + @ApiModelProperty(value = "享受折扣") + private String discountPercent; + + @TableField(value = "`icon`") + @ApiModelProperty(value = "等级图标", required = "required") + private String icon; + + @TableField(value = "`background_url`") + @ApiModelProperty(value = "等级背景图", required = "required") + private String backgroundUrl; + + @TableField(value = "`enabled`") + @ApiModelProperty(value = "状态", required = "required") + private Integer enabled; +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/ShopMemberLevelService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/ShopMemberLevelService.java new file mode 100644 index 0000000..30b2f78 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/ShopMemberLevelService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.level.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.level.entity.ShopMemberLevel; + +/** + * @ClassName: ShopMemberLevelService + * @Description: 会员等级服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMemberLevelService extends SkyeyeBusinessService { + + ShopMemberLevel getMinLevel(); + + ShopMemberLevel getSimpleLevelByLevel(Integer level); + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/impl/ShopMemberLevelServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/impl/ShopMemberLevelServiceImpl.java new file mode 100644 index 0000000..e129477 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/level/service/impl/ShopMemberLevelServiceImpl.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.level.service.impl; + +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.level.dao.ShopMemberLevelDao; +import com.skyeye.level.entity.ShopMemberLevel; +import com.skyeye.level.service.ShopMemberLevelService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMemberLevelServiceImpl + * @Description: 会员等级服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "会员等级", groupName = "会员等级") +public class ShopMemberLevelServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMemberLevelService { + + @Override + public List> queryDataList(InputObject inputObject) { + List beans = queryAllEnabledMemberLevel(); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + private List queryAllEnabledMemberLevel() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMemberLevel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(ShopMemberLevel::getLevel)); + List beans = list(queryWrapper); + return beans; + } + + @Override + public ShopMemberLevel getMinLevel() { + List beans = queryAllEnabledMemberLevel(); + return beans.stream().findFirst().orElse(null); + } + + @Override + public ShopMemberLevel getSimpleLevelByLevel(Integer level) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMemberLevel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMemberLevel::getLevel), level); + ShopMemberLevel bean = getOne(queryWrapper, false); + return bean; + } +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/service/MemberService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/MemberService.java new file mode 100644 index 0000000..900ea82 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/MemberService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.entity.Member; + +/** + * @ClassName: MemberService + * @Description: 会员管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/2 15:36 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MemberService extends SkyeyeBusinessService { + + void queryMyWriteMemberList(InputObject inputObject, OutputObject outputObject); + + Member queryMemberByPhone(String phone); + + void editMemberPassword(String userId, String newPassword, int pwdNum); + + void updateCurrentLoginMemberNickname(InputObject inputObject, OutputObject outputObject); + + void updateCurrentLoginMemberAvatar(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/service/ShopAppAuthService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/ShopAppAuthService.java new file mode 100644 index 0000000..a3d998e --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/ShopAppAuthService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: ShopAppAuthService + * @Description: 商城登录管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 11:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopAppAuthService { + + void shopLoginForPC(InputObject inputObject, OutputObject outputObject); + + void shopLoginForApp(InputObject inputObject, OutputObject outputObject); + + void shopLogout(InputObject inputObject, OutputObject outputObject); + + void editShopUserPassword(InputObject inputObject, OutputObject outputObject); + + void sendShopSmsCode(InputObject inputObject, OutputObject outputObject); + + void smsShopLogin(InputObject inputObject, OutputObject outputObject); + + void smsShopMemberRegister(InputObject inputObject, OutputObject outputObject); + + void editShopUserPasswordByPhone(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/MemberServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/MemberServiceImpl.java new file mode 100644 index 0000000..7ac09ff --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/MemberServiceImpl.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.SysUserAuthConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CharUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.dao.MemberDao; +import com.skyeye.entity.Member; +import com.skyeye.eve.service.IAreaService; +import com.skyeye.level.entity.ShopMemberLevel; +import com.skyeye.level.service.ShopMemberLevelService; +import com.skyeye.service.MemberService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MemberServiceImpl + * @Description: 会员管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/2 15:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "会员管理", groupName = "会员管理") +public class MemberServiceImpl extends SkyeyeBusinessServiceImpl implements MemberService { + + @Autowired + private IAreaService iAreaService; + + @Autowired + private ShopMemberLevelService shopMemberLevelService; + + @Autowired + private ShopStoreService shopStoreService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryMemberByList(pageInfo); + return beans; + } + + @Override + public void createPrepose(Member entity) { + setMemberMation(entity); + setLevel(entity); + } + + private void setLevel(Member entity) { + ShopMemberLevel minLevel = shopMemberLevelService.getMinLevel(); + if (ObjectUtil.isNotEmpty(minLevel)) { + entity.setLevelId(minLevel.getId()); + } + } + + @Override + public void updatePrepose(Member entity) { + setMemberMation(entity); + Member oldMember = selectById(entity.getId()); + entity.setPassword(oldMember.getPassword()); + entity.setWechatOpenId(oldMember.getWechatOpenId()); + entity.setPwdNumEnc(oldMember.getPwdNumEnc()); + if (StrUtil.isEmpty(entity.getLevelId())) { + setLevel(entity); + } else { + ShopMemberLevel shopMemberLevel = shopMemberLevelService.selectById(entity.getLevelId()); + if (StrUtil.isEmpty(shopMemberLevel.getId())) { + shopMemberLevel = shopMemberLevelService.getSimpleLevelByLevel(CommonNumConstants.NUM_ONE); + entity.setLevelId(shopMemberLevel.getId()); + } + } + } + + private void setMemberMation(Member entity) { + String name = entity.getName(); + name = CharUtil.filterEmoji(name); + name = CharUtil.removeFourChar(name); + entity.setName(name); + } + + @Override + public Member selectById(String id) { + Member member = super.selectById(id); + iAreaService.setDataMation(member, Member::getProvinceId); + iAreaService.setDataMation(member, Member::getCityId); + iAreaService.setDataMation(member, Member::getAreaId); + iAreaService.setDataMation(member, Member::getTownshipId); + shopStoreService.setDataMation(member, Member::getStoreId); + return member; + } + + /** + * 获取我录入的会员信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyWriteMemberList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setCreateId(inputObject.getLogParams().get("id").toString()); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryMemberByList(pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public Member queryMemberByPhone(String phone) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Member::getPhone), phone); + queryWrapper.eq(MybatisPlusUtil.toColumns(Member::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + Member member = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(member)) { + shopMemberLevelService.setDataMation(member, Member::getLevelId); + } + return member; + } + + @Override + public void editMemberPassword(String userId, String newPassword, int pwdNum) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Member::getPassword), newPassword); + updateWrapper.set(MybatisPlusUtil.toColumns(Member::getPwdNumEnc), pwdNum); + update(updateWrapper); + } + + @Override + public void updateCurrentLoginMemberNickname(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String name = params.get("name").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 根据id更新会员昵称 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Member::getName), name); + update(updateWrapper); + editCache(outputObject, userId); + } + + private void editCache(OutputObject outputObject, String userId) { + // 更新缓存 + refreshCache(userId); + // 更新会员登录缓存 + Member member = selectById(userId); + member.setPassword(null); + member.setPwdNumEnc(null); + SysUserAuthConstants.setUserLoginRedisCache(member.getId() + SysUserAuthConstants.APP_IDENTIFYING, BeanUtil.beanToMap(member)); + SysUserAuthConstants.setUserLoginRedisCache(member.getId(), BeanUtil.beanToMap(member)); + outputObject.setBean(member); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void updateCurrentLoginMemberAvatar(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String avatar = params.get("avatar").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 根据id更新会员昵称 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, userId); + updateWrapper.set(MybatisPlusUtil.toColumns(Member::getAvatar), avatar); + update(updateWrapper); + editCache(outputObject, userId); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/ShopAppAuthServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/ShopAppAuthServiceImpl.java new file mode 100644 index 0000000..926ba0b --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/service/impl/ShopAppAuthServiceImpl.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.SysUserAuthConstants; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.enumeration.RequestType; +import com.skyeye.common.enumeration.SmsSceneEnum; +import com.skyeye.common.object.GetUserToken; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.entity.Member; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.sms.service.ISmsCodeService; +import com.skyeye.service.MemberService; +import com.skyeye.service.ShopAppAuthService; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +import static com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl.TRANSACTION_MANAGER_VALUE; + +/** + * @ClassName: ShopAppAuthServiceImpl + * @Description: 商城登录管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/16 11:57 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class ShopAppAuthServiceImpl implements ShopAppAuthService { + + @Autowired + private MemberService memberService; + + @Autowired + private ISmsCodeService iSmsCodeService; + + @Override + public void shopLoginForPC(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Member member = login(map, RequestType.PC.getKey()); + outputObject.setBean(member); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + private Member login(Map map, String requestType) { + String phone = map.get("phone").toString(); + Member member = memberService.queryMemberByPhone(phone); + if (ObjectUtil.isEmpty(member)) { + throw new CustomException("手机号码不存在,请先注册!"); + } + if (StrUtil.isEmpty(member.getPassword())) { + throw new CustomException("该用户未设置密码!"); + } + String password = map.get("password").toString(); + for (int i = 0; i < member.getPwdNumEnc(); i++) { + password = ToolUtil.MD5(password); + } + if (!StrUtil.equals(password, member.getPassword())) { + throw new CustomException("密码错误!"); + } + return getMember(requestType, member, password); + } + + @NotNull + private static Member getMember(String requestType, Member member, String password) { + member.setPassword(null); + member.setPwdNumEnc(null); + String userToken; + if (RequestType.APP.getKey().equals(requestType)) { + userToken = GetUserToken.createNewToken(member.getId() + SysUserAuthConstants.APP_IDENTIFYING, password); + SysUserAuthConstants.setUserLoginRedisCache(member.getId() + SysUserAuthConstants.APP_IDENTIFYING, BeanUtil.beanToMap(member)); + } else { + userToken = GetUserToken.createNewToken(member.getId(), password); + SysUserAuthConstants.setUserLoginRedisCache(member.getId(), BeanUtil.beanToMap(member)); + } + member.setUserToken(userToken); + return member; + } + + @Override + public void shopLoginForApp(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + Member member = login(map, RequestType.APP.getKey()); + outputObject.setBean(member); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void shopLogout(InputObject inputObject, OutputObject outputObject) { + String userId = GetUserToken.getUserTokenUserId(PutObject.getRequest()); + SysUserAuthConstants.delUserLoginRedisCache(userId); + inputObject.removeSession(); + } + + @Override + public void editShopUserPassword(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String newPassword = map.get("newPassword").toString(); + String userId = inputObject.getLogParams().get("id").toString(); + int pwdNum = (int) (Math.random() * 100); + for (int i = 0; i < pwdNum; i++) { + newPassword = ToolUtil.MD5(newPassword); + } + memberService.editMemberPassword(userId, newPassword, pwdNum); + } + + @Override + public void sendShopSmsCode(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mobile = params.get("mobile").toString(); + Integer scene = Integer.parseInt(params.get("scene").toString()); + // 情况 1:如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了 + if (scene == SmsSceneEnum.UPDATE_MOBILE.getKey()) { + Member member = memberService.queryMemberByPhone(mobile); + if (ObjectUtil.isNotEmpty(member)) { + throw new CustomException("手机号已经被使用"); + } + } + // 情况 2:如果是重置密码场景,需要校验手机号是存在的 + if (scene == SmsSceneEnum.RESET_PASSWORD.getKey()) { + Member member = memberService.queryMemberByPhone(mobile); + if (ObjectUtil.isEmpty(member)) { + throw new CustomException("手机号不存在"); + } + } + // 情况 3:如果是修改密码场景,需要查询手机号,无需前端传递 + if (scene == SmsSceneEnum.UPDATE_PASSWORD.getKey()) { + String id = inputObject.getLogParams().get("id").toString(); + Member member = memberService.selectById(id); + if (StrUtil.isEmpty(member.getPhone())) { + throw new CustomException("您还没有绑定手机号,请先绑定手机号"); + } + mobile = member.getPhone(); + } + if (StrUtil.isEmpty(mobile)) { + throw new CustomException("手机号不能为空"); + } + // 发送短信验证码 + iSmsCodeService.sendSmsCodeReq(mobile, scene); + } + + @Override + public void smsShopLogin(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mobile = params.get("mobile").toString(); + String smsCode = params.get("smsCode").toString(); + // 校验验证码 + iSmsCodeService.validateSmsCode(mobile, smsCode, SmsSceneEnum.LOGIN.getKey()); + // 登录 + Member member = memberService.queryMemberByPhone(mobile); + if (ObjectUtil.isEmpty(member)) { + throw new CustomException("手机号码不存在,请先注册!"); + } + String requestType = InputObject.getRequest().getHeader("requestType"); + member = getMember(requestType, member, member.getPassword()); + outputObject.setBean(member); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void smsShopMemberRegister(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mobile = params.get("mobile").toString(); + String smsCode = params.get("smsCode").toString(); + // 校验验证码 + iSmsCodeService.validateSmsCode(mobile, smsCode, SmsSceneEnum.LOGIN.getKey()); + Member member = memberService.queryMemberByPhone(mobile); + if (ObjectUtil.isNotEmpty(member)) { + throw new CustomException("手机号已经被使用"); + } + // 注册 + Member saveMember = new Member(); + saveMember.setPhone(mobile); + saveMember.setName("未命名"); + saveMember.setEnabled(EnableEnum.ENABLE_USING.getKey()); + memberService.createEntity(saveMember, null); + } + + @Override + public void editShopUserPasswordByPhone(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String newPassword = map.get("newPassword").toString(); + String phone = map.get("phone").toString(); + Member member = memberService.queryMemberByPhone(phone); + if (ObjectUtil.isEmpty(member)) { + throw new CustomException("手机号码不存在,请先注册!"); + } + int pwdNum = (int) (Math.random() * 100); + for (int i = 0; i < pwdNum; i++) { + newPassword = ToolUtil.MD5(newPassword); + } + memberService.editMemberPassword(member.getId(), newPassword, pwdNum); + } +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/classenum/StoreOnlineBookType.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/classenum/StoreOnlineBookType.java new file mode 100644 index 0000000..c96d9d3 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/classenum/StoreOnlineBookType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: StoreOnlineBookType + * @Description: 门店线上预约类型的设定 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/12 9:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum StoreOnlineBookType implements SkyeyeEnumClass { + + MAINTENANCE_STAND(1, "按维修机位", true, true), + WORKER_NUM(2, "按工人数", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopAreaController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopAreaController.java new file mode 100644 index 0000000..939ba05 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopAreaController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopArea; +import com.skyeye.store.service.ShopAreaService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopAreaController + * @Description: 区域管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "区域管理", tags = "区域管理", modelName = "区域管理") +public class ShopAreaController { + + @Autowired + private ShopAreaService shopAreaService; + + /** + * 获取区域信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "area001", value = "获取区域信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/AreaController/queryAreaList") + public void queryAreaList(InputObject inputObject, OutputObject outputObject) { + shopAreaService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑区域 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopArea", value = "添加/编辑区域", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopArea.class) + @RequestMapping("/post/AreaController/writeShopArea") + public void writeShopArea(InputObject inputObject, OutputObject outputObject) { + shopAreaService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除区域信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAreaById", value = "根据id删除区域信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AreaController/deleteAreaById") + public void deleteAreaById(InputObject inputObject, OutputObject outputObject) { + shopAreaService.deleteById(inputObject, outputObject); + } + + /** + * 获取区域列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllEnabledAreaList", value = "获取区域列表信息", method = "GET", allUse = "2") + @RequestMapping("/post/AreaController/queryAllEnabledAreaList") + public void queryAllEnabledAreaList(InputObject inputObject, OutputObject outputObject) { + shopAreaService.queryAllEnabledAreaList(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreController.java new file mode 100644 index 0000000..10f0c1c --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreController.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopStoreController + * @Description: 门店管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 12:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店管理", tags = "门店管理", modelName = "门店管理") +public class ShopStoreController { + + @Autowired + private ShopStoreService shopStoreService; + + @ApiOperation(id = "store001", value = "获取门店信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopStoreController/queryStoreList") + public void queryStoreList(InputObject inputObject, OutputObject outputObject) { + shopStoreService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "queryStoreListFoServer", value = "其他微服务调用,获取门店信息", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class, value = { + @ApiImplicitParam(id = "enabled", name = "enabled", value = "状态", required = "required,num", defaultValue = "1")}) + @RequestMapping("/post/ShopStoreController/queryStoreListFoServer") + public void queryStoreListFoServer(InputObject inputObject, OutputObject outputObject) { + shopStoreService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "writeStore", value = "添加/编辑门店", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopStore.class) + @RequestMapping("/post/ShopStoreController/writeStore") + public void writeStore(InputObject inputObject, OutputObject outputObject) { + shopStoreService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryStoreById", value = "据ID查询门店信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopStoreController/queryStoreById") + public void queryStoreById(InputObject inputObject, OutputObject outputObject) { + shopStoreService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "queryStoreByIds", value = "根据ID批量查询门店信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopStoreController/queryStoreByIds") + public void queryStoreByIds(InputObject inputObject, OutputObject outputObject) { + shopStoreService.selectByIds(inputObject, outputObject); + } + + @ApiOperation(id = "deleteStoreById", value = "根据id删除门店信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopStoreController/deleteStoreById") + public void deleteStoreById(InputObject inputObject, OutputObject outputObject) { + shopStoreService.deleteById(inputObject, outputObject); + } + + @ApiOperation(id = "queryStoreListByParams", value = "获取门店列表信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "shopAreaId", name = "shopAreaId", value = "区域ID"), + @ApiImplicitParam(id = "enabled", name = "enabled", value = "状态", required = "num")}) + @RequestMapping("/post/ShopStoreController/queryStoreListByParams") + public void queryStoreListByParams(InputObject inputObject, OutputObject outputObject) { + shopStoreService.queryStoreListByParams(inputObject, outputObject); + } + + @ApiOperation(id = "queryStoreOnlineById", value = "根据门店ID获取门店设置的线上预约信息(已结合当前登陆用户)", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopStoreController/queryStoreOnlineById") + public void queryStoreOnlineById(InputObject inputObject, OutputObject outputObject) { + shopStoreService.queryStoreOnlineById(inputObject, outputObject); + } + + @ApiOperation(id = "saveStoreOnlineMation", value = "保存门店线上预约信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "营业开始时间", required = "required"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "营业结束时间", required = "required"), + @ApiImplicitParam(id = "onlineBookAppoint", name = "onlineBookAppoint", value = "是否开启线上预约", required = "required,num"), + @ApiImplicitParam(id = "onlineBookRadix", name = "onlineBookRadix", value = "线上预约基数,以分钟为单位,如果设置为30,则会自动计算在营业时间段内的可预约时间段", required = "num"), + @ApiImplicitParam(id = "onlineBookType", name = "onlineBookType", value = "线上预约类型的设定", required = "num"), + @ApiImplicitParam(id = "onlineBookJson", name = "onlineBookJson", value = "设置线上预约时需要存储各个时间段内的信息", required = "json")}) + @RequestMapping("/post/ShopStoreController/saveStoreOnlineMation") + public void saveStoreOnlineMation(InputObject inputObject, OutputObject outputObject) { + shopStoreService.saveStoreOnlineMation(inputObject, outputObject); + } + + @ApiOperation(id = "store010", value = "获取门店指定日期的预约信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "门店id", required = "required"), + @ApiImplicitParam(id = "onlineDay", name = "onlineDay", value = "预约日期,格式为YYYY-MM-dd", required = "required")}) + @RequestMapping("/post/ShopStoreController/queryStoreOnlineMationPointDay") + public void queryStoreOnlineMationPointDay(InputObject inputObject, OutputObject outputObject) { + shopStoreService.queryStoreOnlineMationPointDay(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreStaffController.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreStaffController.java new file mode 100644 index 0000000..91ab263 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/controller/ShopStoreStaffController.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopStoreStaffVO; +import com.skyeye.store.service.ShopStoreStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopStoreStaffController + * @Description: 门店与员工的关系控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店员工关系管理", tags = "门店员工关系管理", modelName = "门店员工关系管理") +public class ShopStoreStaffController { + + @Autowired + private ShopStoreStaffService shopStoreStaffService; + + /** + * 获取门店下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storeStaff001", value = "获取门店下的员工信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopStoreStaffController/queryStoreStaffList") + public void queryStoreStaffList(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.queryPageList(inputObject, outputObject); + } + + /** + * 删除门店下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storeStaff002", value = "删除门店下的员工信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "门店与员工的关系表主键id", required = "required")}) + @RequestMapping("/post/ShopStoreStaffController/deleteStoreStaffMationById") + public void deleteStoreStaffMationById(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.deleteById(inputObject, outputObject); + } + + /** + * 新增门店下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storeStaff003", value = "新增门店下的员工信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopStoreStaffVO.class) + @RequestMapping("/post/ShopStoreStaffController/insertStoreStaffMation") + public void insertStoreStaffMation(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.insertStoreStaffMation(inputObject, outputObject); + } + + /** + * 获取当前登陆用户所属的区域列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storeStaff004", value = "获取当前登陆用户所属的区域列表", method = "GET", allUse = "2") + @RequestMapping("/post/ShopStoreStaffController/queryStaffBelongAreaList") + public void queryStaffBelongAreaList(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.queryStaffBelongAreaList(inputObject, outputObject); + } + + /** + * 获取当前登陆用户所属的门店列表(只包含已启用门店) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "storeStaff005", value = "获取当前登陆用户所属的门店列表", method = "GET", allUse = "2") + @RequestMapping("/post/ShopStoreStaffController/queryStaffBelongStoreList") + public void queryStaffBelongStoreList(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.queryStaffBelongStoreList(inputObject, outputObject); + } + + /** + * 根据员工id删除所有的所属门店信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteStoreStaffMationByStaffId", value = "根据员工id删除所有的所属门店信息", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "员工id", required = "required")}) + @RequestMapping("/post/ShopStoreStaffController/deleteStoreStaffMationByStaffId") + public void deleteStoreStaffMationByStaffId(InputObject inputObject, OutputObject outputObject) { + shopStoreStaffService.deleteStoreStaffMationByStaffId(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopAreaDao.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopAreaDao.java new file mode 100644 index 0000000..ac0e652 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopAreaDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.store.entity.ShopArea; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopAreaDao + * @Description: 区域管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopAreaDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreDao.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreDao.java new file mode 100644 index 0000000..ae67145 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.store.entity.ShopStore; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StoreDao + * @Description: 门店管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 12:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStoreDao extends SkyeyeBaseMapper { + + List> queryOnlineAppointmentMation(@Param("onlineDay") String onlineDay, @Param("list") List onlineTime); + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreStaffDao.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreStaffDao.java new file mode 100644 index 0000000..571c094 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/dao/ShopStoreStaffDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.store.entity.ShopStoreStaff; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopStoreStaffDao + * @Description: 门店与员工的关系数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStoreStaffDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopArea.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopArea.java new file mode 100644 index 0000000..00984b0 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopArea.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: ShopArea + * @Description: 区域管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "shop:area", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_area") +@ApiModel("区域管理实体类") +public class ShopArea extends BaseGeneralInfo { + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStore.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStore.java new file mode 100644 index 0000000..4d34f8f --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStore.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.AreaInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopStore + * @Description: 门店管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 12:39 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = CacheConstants.SHOP_STORE_CACHE_KEY) +@TableName(value = "shop_store", autoResultMap = true) +@ApiModel("门店管理实体类") +public class ShopStore extends AreaInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "门店名称", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "logo") + @ApiModelProperty(value = "logo图片") + private String logo; + + @TableField(value = "img") + @ApiModelProperty(value = "背景图") + private String img; + + @TableField(value = "shop_area_id") + @ApiModelProperty(value = "区域ID", required = "required") + private String shopAreaId; + + @TableField(exist = false) + @Property(value = "区域信息") + private ShopArea shopAreaMation; + + @TableField(value = "remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "num") + private Integer enabled; + + @TableField(value = "longitude") + @ApiModelProperty(value = "经度") + private String longitude; + + @TableField(value = "latitude") + @ApiModelProperty(value = "纬度") + private String latitude; + + @TableField(exist = false) + @Property(value = "两点之间的距离,单位:米") + private Double distance; + + @TableField("start_time") + @ApiModelProperty(value = "开始时间") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间") + private String endTime; + + @TableField(value = "online_book_appoint") + @ApiModelProperty(value = "是否开启线上预约,参考#WhetherEnum", required = "num") + private Integer onlineBookAppoint; + + @TableField(value = "online_book_radix") + @ApiModelProperty(value = "线上预约基数,以分钟为单位,如果设置为30,则会自动计算在营业时间段内的可预约时间段", required = "num") + private Integer onlineBookRadix; + + @TableField(value = "online_book_type") + @ApiModelProperty(value = "线上预约类型的设定,参考#StoreOnlineBookType", required = "num") + private Integer onlineBookType; + + @TableField(value = "online_book_json", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "设置线上预约时需要存储各个时间段内的信息,包含time和value属性", required = "json") + private List> onlineBookJson; + + @TableField(exist = false) + @Property(value = "门店下的员工") + private List storeStaffList; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaff.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaff.java new file mode 100644 index 0000000..d498664 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaff.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ShopStoreStaff + * @Description: 门店与员工的关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_store_staff", autoResultMap = true) +@ApiModel("门店与员工的关系实体类") +public class ShopStoreStaff extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "store_id") + @ApiModelProperty(value = "门店ID", required = "required") + private String storeId; + + @TableField(value = "staff_id") + @ApiModelProperty(value = "员工ID", required = "required") + private String staffId; + + @TableField(exist = false) + @Property(value = "员工信息") + private Map staffMation; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaffVO.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaffVO.java new file mode 100644 index 0000000..a69caaf --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/entity/ShopStoreStaffVO.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName: ShopStoreStaffVO + * @Description: 门店与员工的关系入参实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("门店与员工的关系入参实体类") +public class ShopStoreStaffVO implements Serializable { + + @ApiModelProperty(value = "门店ID", required = "required") + private String storeId; + + @ApiModelProperty(value = "员工ID", required = "required,json") + private List staffId; + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopAreaService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopAreaService.java new file mode 100644 index 0000000..a98e6fd --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopAreaService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopArea; + +/** + * @ClassName: ShopAreaService + * @Description: 区域管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopAreaService extends SkyeyeBusinessService { + + void queryAllEnabledAreaList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreService.java new file mode 100644 index 0000000..a7298ab --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopStore; + +/** + * @ClassName: StoreService + * @Description: 门店管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 12:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStoreService extends SkyeyeBusinessService { + + void queryStoreListByParams(InputObject inputObject, OutputObject outputObject); + + void queryStoreOnlineById(InputObject inputObject, OutputObject outputObject); + + void saveStoreOnlineMation(InputObject inputObject, OutputObject outputObject); + + void queryStoreOnlineMationPointDay(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreStaffService.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreStaffService.java new file mode 100644 index 0000000..326cc18 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/ShopStoreStaffService.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopArea; +import com.skyeye.store.entity.ShopStoreStaff; + +import java.util.List; + +/** + * @ClassName: ShopStoreStaffService + * @Description: 门店与员工的关系服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopStoreStaffService extends SkyeyeBusinessService { + + void insertStoreStaffMation(InputObject inputObject, OutputObject outputObject); + + void queryStaffBelongAreaList(InputObject inputObject, OutputObject outputObject); + + /** + * 根据员工id查询员工所在的区域信息 + * + * @param staffId 员工id + */ + List queryStaffBelongAreaListByStaffId(String staffId); + + List getShopStoresByStoreId(String storeId); + + void queryStaffBelongStoreList(InputObject inputObject, OutputObject outputObject); + + void deleteStoreStaffMationByStaffId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopAreaServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopAreaServiceImpl.java new file mode 100644 index 0000000..a4fa2a3 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopAreaServiceImpl.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.store.dao.ShopAreaDao; +import com.skyeye.store.entity.ShopArea; +import com.skyeye.store.service.ShopAreaService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: ShopAreaServiceImpl + * @Description: 区域管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "区域管理", groupName = "区域管理") +public class ShopAreaServiceImpl extends SkyeyeBusinessServiceImpl implements ShopAreaService { + + @Override + public void queryAllEnabledAreaList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopArea::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreServiceImpl.java new file mode 100644 index 0000000..e3f936a --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreServiceImpl.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.MapUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.rest.shopmaterialnorms.rest.IShopMaterialNormsRest; +import com.skyeye.store.dao.ShopStoreDao; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.entity.ShopStoreStaff; +import com.skyeye.store.service.ShopAreaService; +import com.skyeye.store.service.ShopStoreService; +import com.skyeye.store.service.ShopStoreStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: StoreServiceImpl + * @Description: 门店管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 12:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店管理", groupName = "门店管理") +public class ShopStoreServiceImpl extends SkyeyeBusinessServiceImpl implements ShopStoreService { + + @Autowired + private ShopAreaService shopAreaService; + + @Autowired + private ShopStoreStaffService shopStoreStaffService; + + @Autowired + private IShopMaterialNormsRest iShopMaterialNormsRest; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (commonPageInfo.getEnabled() != null) { + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStore::getEnabled), commonPageInfo.getEnabled()); + } + return queryWrapper; + } + + @Override + public void setDefaultOrderBy(CommonPageInfo commonPageInfo, QueryWrapper wrapper) { + if (StrUtil.isNotEmpty(commonPageInfo.getLatitude()) && StrUtil.isNotEmpty(commonPageInfo.getLongitude())) { + // 使用ST_Distance_Sphere函数计算距离并按距离排序 + String orderByClause = "ORDER BY CASE WHEN longitude IS NULL THEN 1 ELSE 0 END, ST_Distance_Sphere(point(longitude, latitude), " + + "point(" + commonPageInfo.getLongitude() + ", " + commonPageInfo.getLatitude() + ")) ASC"; + wrapper.last(orderByClause); + } + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = super.queryPageDataList(inputObject); + shopAreaService.setMationForMap(beans, "shopAreaId", "shopAreaMation"); + if (StrUtil.isNotEmpty(commonPageInfo.getLatitude()) && StrUtil.isNotEmpty(commonPageInfo.getLongitude())) { + // 计算距离并添加距离字段 + beans.forEach(bean -> { + double distance = ToolUtil.calculateDistance(Double.parseDouble(commonPageInfo.getLatitude()), Double.parseDouble(commonPageInfo.getLongitude()), + Double.parseDouble(MapUtil.checkKeyIsNull(bean, "latitude") ? "0" : bean.get("latitude").toString()), + Double.parseDouble(MapUtil.checkKeyIsNull(bean, "longitude") ? "0" : bean.get("longitude").toString())); + bean.put("distance", distance); + }); + } + return beans; + } + + @Override + public void createPostpose(ShopStore entity, String userId) { + // 新增门店时,新增门店商品 + ExecuteFeignClient.get(() -> iShopMaterialNormsRest.saveShopMaterialStore(entity.getId())); + } + + @Override + public ShopStore selectById(String id) { + ShopStore shopStore = super.selectById(id); + shopAreaService.setDataMation(shopStore, ShopStore::getShopAreaId); + return shopStore; + } + + @Override + public List selectByIds(String... ids) { + List shopStores = super.selectByIds(ids); + shopAreaService.setDataMation(shopStores, ShopStore::getShopAreaId); + return shopStores; + } + + /** + * 获取门店列表信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStoreListByParams(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String shopAreaId = params.get("shopAreaId").toString(); + String enabled = params.get("enabled").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (StrUtil.isNotEmpty(shopAreaId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStore::getShopAreaId), shopAreaId); + } + if (StrUtil.isNotEmpty(enabled)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStore::getEnabled), enabled); + } + List list = list(queryWrapper); + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + /** + * 根据门店ID获取门店设置的线上预约信息(已结合当前登陆用户) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStoreOnlineById(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + ShopStore shopStore = selectById(id); + + // 获取该门店的成员 + List shopStoreStaffs = shopStoreStaffService.getShopStoresByStoreId(id); + Map> userStaffMap = iAuthUserService.queryUserMationListByStaffIds( + shopStoreStaffs.stream().map(ShopStoreStaff::getStaffId).collect(Collectors.toList())); + shopStoreStaffs.forEach(shopStoreStaff -> { + shopStoreStaff.setStaffMation(userStaffMap.get(shopStoreStaff.getStaffId())); + }); + shopStore.setStoreStaffList(shopStoreStaffs); + + outputObject.setBean(shopStore); + outputObject.settotal(1); + } + + /** + * 保存门店线上预约信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void saveStoreOnlineMation(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, params.get("id").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getStartTime), params.get("startTime").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getEndTime), params.get("endTime").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookAppoint), params.get("onlineBookAppoint").toString()); + if (Integer.parseInt(params.get("onlineBookAppoint").toString()) == WhetherEnum.ENABLE_USING.getKey()) { + // 开启线上预约 + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookRadix), params.get("onlineBookRadix").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookType), params.get("onlineBookType").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookJson), params.get("onlineBookJson").toString()); + } else { + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookRadix), null); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookType), null); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopStore::getOnlineBookJson), null); + } + update(updateWrapper); + refreshCache(params.get("id").toString()); + } + + /** + * 获取门店指定日期的预约信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStoreOnlineMationPointDay(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String onlineDay = params.get("onlineDay").toString(); + ShopStore shopStore = selectById(id); + + // 是否开启线上预约 + if (shopStore.getOnlineBookAppoint() == WhetherEnum.ENABLE_USING.getKey()) { + // 获取预约时间段信息 + List onlineTime = shopStore.getOnlineBookJson().stream().map(bean -> bean.get("time").toString()).collect(Collectors.toList()); + // 获取现有的预约信息 + List> onlineAppointmentMation = skyeyeBaseMapper.queryOnlineAppointmentMation(onlineDay, onlineTime); + Map onlineAppointmentMap = onlineAppointmentMation + .stream().collect(Collectors.toMap(bean -> bean.get("onlineTime").toString(), bean -> bean.get("onlineOrderNum").toString())); + // 循环遍历预约时间点,减去预约日期指定时间段内已有的预约单数 + shopStore.getOnlineBookJson().forEach(bean -> { + if (onlineAppointmentMap.containsKey(bean.get("time").toString())) { + bean.put("value", CalculationUtil.subtract(bean.get("onlineOrderNum").toString(), onlineAppointmentMap.get(bean.get("time").toString()))); + } + }); + } + outputObject.setBean(shopStore); + outputObject.settotal(1); + } + +} diff --git a/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreStaffServiceImpl.java b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreStaffServiceImpl.java new file mode 100644 index 0000000..77020a2 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/java/com/skyeye/store/service/impl/ShopStoreStaffServiceImpl.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.store.dao.ShopStoreStaffDao; +import com.skyeye.store.entity.ShopArea; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.entity.ShopStoreStaff; +import com.skyeye.store.service.ShopStoreService; +import com.skyeye.store.service.ShopStoreStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopStoreStaffServiceImpl + * @Description: 门店与员工的关系服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 21:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店与员工的关系管理", groupName = "门店与员工的关系管理", manageShow = false) +public class ShopStoreStaffServiceImpl extends SkyeyeBusinessServiceImpl implements ShopStoreStaffService { + + @Autowired + private ShopStoreService shopStoreService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + if (StrUtil.isEmpty(commonPageInfo.getObjectId())) { + return CollectionUtil.newArrayList(); + } + List> beans = super.queryPageDataList(inputObject); + // 设置员工信息 + List staffIds = beans.stream().map(bean -> bean.get("staffId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String staffId = bean.get("staffId").toString(); + bean.put("staffMation", staffMap.get(staffId)); + }); + return beans; + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStoreStaff::getStoreId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + /** + * 新增门店下的员工信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void insertStoreStaffMation(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String storeId = params.get("storeId").toString(); + List staffId = (List) params.get("staffId"); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStoreStaff::getStoreId), storeId); + List list = list(queryWrapper); + List storeStaffIdList = list.stream().map(ShopStoreStaff::getStaffId).collect(Collectors.toList()); + + List beans = new ArrayList<>(); + String userId = inputObject.getLogParams().get("id").toString(); + for (String str : staffId) { + if (storeStaffIdList.contains(str)) { + // 如果该门店已经存在这个员工,则跳过 + continue; + } + if (StrUtil.isNotEmpty(str)) { + ShopStoreStaff item = new ShopStoreStaff(); + item.setStoreId(storeId); + item.setStaffId(str); + beans.add(item); + } + } + if (CollectionUtil.isNotEmpty(beans)) { + createEntity(beans, userId); + } + } + + /** + * 获取当前登陆用户所属的区域列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStaffBelongAreaList(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + + List shopAreaList = queryStaffBelongAreaListByStaffId(staffId); + outputObject.setBeans(shopAreaList); + outputObject.settotal(shopAreaList.size()); + } + + @Override + public List queryStaffBelongAreaListByStaffId(String staffId) { + List shopStores = getShopStoresByStaffId(staffId); + List shopAreaList = new ArrayList<>(shopStores.stream() + .filter(bean -> ObjectUtil.isNotEmpty(bean.getShopAreaMation())) + .map(ShopStore::getShopAreaMation) + .collect(Collectors.toMap(ShopArea::getId, Function.identity(), (oldValue, newValue) -> oldValue)) + .values()); + return shopAreaList; + } + + /** + * 获取当前登陆用户所属的门店列表(只包含已启用门店) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStaffBelongStoreList(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getLogParams().get("staffId").toString(); + List shopStores = getShopStoresByStaffId(staffId); + shopStores = shopStores.stream().filter(store -> store.getEnabled().equals(EnableEnum.ENABLE_USING.getKey())).collect(Collectors.toList()); + outputObject.setBeans(shopStores); + outputObject.settotal(shopStores.size()); + } + + private List getShopStoresByStaffId(String staffId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStoreStaff::getStaffId), staffId); + List list = list(queryWrapper); + // 获取门店id + List storeIds = list.stream().map(ShopStoreStaff::getStoreId).collect(Collectors.toList()); + // 查询门店信息 + List shopStores = shopStoreService.selectByIds(storeIds.toArray(new String[]{})); + return shopStores; + } + + @Override + public List getShopStoresByStoreId(String storeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStoreStaff::getStoreId), storeId); + List list = list(queryWrapper); + return list; + } + + /** + * 根据员工id删除所有的所属门店信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void deleteStoreStaffMationByStaffId(InputObject inputObject, OutputObject outputObject) { + String staffId = inputObject.getParams().get("id").toString(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopStoreStaff::getStaffId), staffId); + remove(queryWrapper); + } +} diff --git a/skyeye-shop/shop-member/src/main/resources/mapper/member/MemberMapper.xml b/skyeye-shop/shop-member/src/main/resources/mapper/member/MemberMapper.xml new file mode 100644 index 0000000..d997771 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/resources/mapper/member/MemberMapper.xml @@ -0,0 +1,53 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-member/src/main/resources/mapper/store/ShopStoreDao.xml b/skyeye-shop/shop-member/src/main/resources/mapper/store/ShopStoreDao.xml new file mode 100644 index 0000000..6b63c93 --- /dev/null +++ b/skyeye-shop/shop-member/src/main/resources/mapper/store/ShopStoreDao.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-store/.gitignore b/skyeye-shop/shop-store/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/shop-store/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/shop-store/pom.xml b/skyeye-shop/shop-store/pom.xml new file mode 100644 index 0000000..a570b42 --- /dev/null +++ b/skyeye-shop/shop-store/pom.xml @@ -0,0 +1,28 @@ + + + + skyeye-shop + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + shop-store + + + 8 + 8 + + + + + com.skyeye + shop-member + 0.0.1-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/controller/AdsenseController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/controller/AdsenseController.java new file mode 100644 index 0000000..da0345d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/controller/AdsenseController.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.adsense.controller; + +import com.skyeye.adsense.entity.Adsense; +import com.skyeye.adsense.service.AdsenseService; +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: AdsenseController + * @Description: 广告位管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * + * + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "广告位管理", tags = "广告位管理", modelName = "广告位管理") +public class AdsenseController { + + @Autowired + private AdsenseService adsenseService; + + /** + * 分頁查询广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAdsenseList", value = "分页查询广告位管理信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/DeliveryController/queryAdsenseList") + public void queryAdsenseList(InputObject inputObject, OutputObject outputObject) { + adsenseService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeAdsense", value = "新增/编辑广告位管理信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Adsense.class) + @RequestMapping("/post/AdsenseController/writeAdsense") + public void writeAdsense(InputObject inputObject, OutputObject outputObject) { + adsenseService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteAdsenseByIds", value = "批量删除广告位管理信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/AdsenseController/deleteAdsenseByIds") + public void deleteAdsenseByIds(InputObject inputObject, OutputObject outputObject) { + adsenseService.deleteByIds(inputObject, outputObject); + } + + /** + * 获取已启用广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAdsense", value = "获取已启用广告位管理信息", method = "POST", allUse = "0") + @RequestMapping("/post/AdsenseController/queryAdsense") + public void queryAdsense(InputObject inputObject, OutputObject outputObject) { + adsenseService.queryList(inputObject, outputObject); + } + + /** + * 根据id获取广告位 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAdsenseById", value = "根据id获取广告位", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/AdsenseController/queryAdsenseById") + public void queryAdsenseById(InputObject inputObject, OutputObject outputObject) { + adsenseService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/dao/AdsenseDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/dao/AdsenseDao.java new file mode 100644 index 0000000..ef5faa5 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/dao/AdsenseDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + + +package com.skyeye.adsense.dao; + +import com.skyeye.adsense.entity.Adsense; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +/** + * @ClassName: AdsenseDao + * @Description: 广告位管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AdsenseDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/entity/Adsense.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/entity/Adsense.java new file mode 100644 index 0000000..0a3c217 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/entity/Adsense.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + + +package com.skyeye.adsense.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; +/** + * @ClassName: Adsense + * @Description: 广告位管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ + +@Data +@UniqueField +@TableName(value = "shop_adsense") +@ApiModel("广告位管理") +public class Adsense extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "标题", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "`jump_url`") + @ApiModelProperty(value = "跳转链接") + private String jumpUrl; + + @TableField(value = "`pc_logo`") + @ApiModelProperty(value = "pc端Logo") + private String pcLogo; + + @TableField(value = "`app_logo`") + @ApiModelProperty(value = "app端Logo") + private String appLogo; + + @TableField(value = "`enabled`") + @ApiModelProperty(value = "状态", required = "required") + private Integer enabled; + + @TableField(value = "`order_by`") + @ApiModelProperty(value = "序号", required = "required") + private Integer orderBy; + + @TableField(value = "`remark`") + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/AdsenseService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/AdsenseService.java new file mode 100644 index 0000000..69993ce --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/AdsenseService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.adsense.service; + +import com.skyeye.adsense.entity.Adsense; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: AdsenseService + * @Description: 广告位管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface AdsenseService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/Impl/AdsenseServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/Impl/AdsenseServiceImpl.java new file mode 100644 index 0000000..c1abfc9 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/adsense/service/Impl/AdsenseServiceImpl.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.adsense.service.Impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.adsense.dao.AdsenseDao; +import com.skyeye.adsense.entity.Adsense; +import com.skyeye.adsense.service.AdsenseService; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: AdsenseServiceImpl + * @Description: 广告位管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "广告位管理", groupName = "广告位管理") +public class AdsenseServiceImpl extends SkyeyeBusinessServiceImpl implements AdsenseService { + + /** + * 获取已启用广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Adsense::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + /** + * 重写新增编辑前置条件广告位管理 + */ + @Override + public void validatorEntity(Adsense adsense) { + super.validatorEntity(adsense); + if (StrUtil.isNotEmpty(adsense.getName()) && adsense.getName().length() > 100) { + throw new CustomException("广告位名称过长"); + } + if (adsense.getOrderBy() < -128 || adsense.getOrderBy() > 127) { + throw new CustomException("广告位排序值超出范围"); + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponController.java new file mode 100644 index 0000000..d918f8f --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponController.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.coupon.entity.Coupon; +import com.skyeye.coupon.service.CouponService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CouponController + * @Description: 优惠券/模版信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:06 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "优惠券/模版信息管理", tags = "优惠券/模版信息管理", modelName = "优惠券/模版信息管理") +public class CouponController { + + @Autowired + private CouponService couponService; + + @ApiOperation(id = "writeCoupon", value = "新增/编辑优惠券/模版信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Coupon.class) + @RequestMapping("/post/CouponController/writeCoupon") + public void writeCoupon(InputObject inputObject, OutputObject outputObject) { + couponService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponList", value = "分页获取优惠券/模版信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CouponController/queryCouponList") + public void queryCouponList(InputObject inputObject, OutputObject outputObject) { + couponService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponListByState", value = "根据类型/门店获取已启用的优惠券/模版信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id"), + @ApiImplicitParam(id = "type", name = "type", value = "类型:优惠券:1,优惠券模板:0,全部:为空")}) + @RequestMapping("/post/CouponController/queryCouponListByState") + public void queryCouponListByState(InputObject inputObject, OutputObject outputObject) { + couponService.queryCouponListByState(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponById", value = "根据id获取优惠券/模版信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CouponController/queryCouponById") + public void queryCouponById(InputObject inputObject, OutputObject outputObject) { + couponService.selectById(inputObject, outputObject); + } + + @ApiOperation(id = "deleteCouponById", value = "根据id删除优惠券/模版信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个主键用逗号隔开", required = "required")}) + @RequestMapping("/post/CouponController/deleteCouponById") + public void deleteCouponById(InputObject inputObject, OutputObject outputObject) { + couponService.deleteByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponListByMaterialId", value = "根据商品id获取所有已启用的优惠券列表", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "materialId", name = "materialId", value = "商品id", required = "required")}) + @RequestMapping("/post/CouponController/queryCouponListByMaterialId") + public void queryCouponListByMaterialId(InputObject inputObject, OutputObject outputObject) { + couponService.queryCouponListByMaterialId(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponUseController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponUseController.java new file mode 100644 index 0000000..f7851c8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/controller/CouponUseController.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.coupon.entity.CouponUse; +import com.skyeye.coupon.service.CouponUseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CouponUseController + * @Description: 优惠券领取信息管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "优惠券领取信息管理", tags = "优惠券领取信息管理", modelName = "优惠券领取信息管理") +public class CouponUseController { + + @Autowired + private CouponUseService couponUseService; + + @ApiOperation(id = "writeCouponUse", value = "新增/编辑优惠券领取信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CouponUse.class) + @RequestMapping("/post/CouponUseController/writeCouponUse") + public void writeCouponUse(InputObject inputObject, OutputObject outputObject) { + couponUseService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponUsePageList", value = "分页查询优惠券领取信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CouponUseController/queryCouponUsePageList") + public void queryCouponUsePageList(InputObject inputObject, OutputObject outputObject) { + couponUseService.queryPageList(inputObject, outputObject); + } + + @ApiOperation(id = "queryMyCouponUseByState", value = "根据状态查询自己的优惠券领取信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "state", name = "state", value = "优惠券状态")}) + @RequestMapping("/post/CouponUseController/queryMyCouponUseByState") + public void queryMyCouponUseByState(InputObject inputObject, OutputObject outputObject) { + couponUseService.queryList(inputObject, outputObject); + } + + @ApiOperation(id = "deleteCouponUseByIds", value = "批量删除优惠券领取信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号隔开", required = "required")}) + @RequestMapping("/post/CouponUseController/deleteCouponUseByIds") + public void deleteCouponUseByIds(InputObject inputObject, OutputObject outputObject) { + couponUseService.deleteByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryCouponUseById", value = "根据id查询优惠券领取信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CouponUseController/queryCouponUseById") + public void queryCouponUseById(InputObject inputObject, OutputObject outputObject) { + couponUseService.selectById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponDao.java new file mode 100644 index 0000000..6aa7a07 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.dao; + +import com.skyeye.coupon.entity.Coupon; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CouponDao + * @Description: 优惠券/模版信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponMaterialDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponMaterialDao.java new file mode 100644 index 0000000..b5b0735 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponMaterialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.dao; + +import com.skyeye.coupon.entity.CouponMaterial; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CouponMaterialDao + * @Description: 优惠券/模版适用商品对象管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponMaterialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponStoreDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponStoreDao.java new file mode 100644 index 0000000..3456510 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponStoreDao.java @@ -0,0 +1,7 @@ +package com.skyeye.coupon.dao; + +import com.skyeye.coupon.entity.CouponStore; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +public interface CouponStoreDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseDao.java new file mode 100644 index 0000000..7d1a89d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.dao; + +import com.skyeye.coupon.entity.CouponUse; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CouponUseDao + * @Description: 优惠券领取信息管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponUseDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseMaterialDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseMaterialDao.java new file mode 100644 index 0000000..7ab1adf --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/dao/CouponUseMaterialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.dao; + +import com.skyeye.coupon.entity.CouponUseMaterial; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CouponUseMaterialDao + * @Description: 优惠券领取适用商品对象数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponUseMaterialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/Coupon.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/Coupon.java new file mode 100644 index 0000000..c0c3efe --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/Coupon.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.coupon.enums.CouponTakeType; +import com.skyeye.coupon.enums.CouponValidityType; +import com.skyeye.coupon.enums.PromotionDiscountType; +import com.skyeye.coupon.enums.PromotionMaterialScope; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Coupon + * @Description: 优惠券/模版信息管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_coupon") +@RedisCacheField(name = "shop:coupon", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@ApiModel(value = "优惠券/模版信息管理实体类") +public class Coupon extends BaseGeneralInfo { + + @TableField(exist = false) + @ApiModelProperty(value = "发布门店id列表", required = "json") + private List storeIdList; + + @TableField(value = "template_id") + @ApiModelProperty(value = "模板id") + private String templateId; + + @TableField(value = "enabled") + @ApiModelProperty(value = "状态", required = "required,num", enumClass = EnableEnum.class) + private Integer enabled; + + @TableField(value = "total_count") + @ApiModelProperty(value = "发放数量,-1表示不限制发放数量", required = "required") + private Integer totalCount; + + @TableField(value = "take_limit_count") + @ApiModelProperty(value = "每人限领个数,-1表示不限制", required = "required") + private Integer takeLimitCount; + + @TableField(value = "take_type") + @ApiModelProperty(value = "领取方式", required = "required,num",enumClass = CouponTakeType.class) + private Integer takeType; + + @TableField(value = "use_price") + @ApiModelProperty(value = "是否设置满多少金额可用,单位:分。0 - 不限制,大于 0 - 多少金额可用", required = "required") + private String usePrice; + + @TableField(value = "product_scope") + @ApiModelProperty(value = "商品范围", required = "required,num", enumClass = PromotionMaterialScope.class) + private Integer productScope; + + @TableField(value = "validity_type") + @ApiModelProperty(value = "生效日期类型", required = "required,num",enumClass = CouponValidityType.class) + private Integer validityType; + + @TableField(value = "valid_start_time") + @ApiModelProperty(value = "固定日期 - 生效开始时间,日期格式yyyy-MM-dd HH:mm:ss") + private String validStartTime; + + @TableField(value = "valid_end_time") + @ApiModelProperty(value = "固定日期 - 生效结束时间,日期格式yyyy-MM-dd HH:mm:ss") + private String validEndTime; + + @TableField(value = "fixed_start_time") + @ApiModelProperty(value = "领取日期 - 领取几天后可以开始使用") + private Integer fixedStartTime; + + @TableField(value = "fixed_end_time") + @ApiModelProperty(value = "领取日期 - 领取开始使用时几天后结束") + private Integer fixedEndTime; + + @TableField(value = "discount_type") + @ApiModelProperty(value = "折扣类型", required = "required,num",enumClass = PromotionDiscountType.class) + private Integer discountType; + + @TableField(value = "discount_percent") + @ApiModelProperty(value = "折扣百分比,例如,80% 为 80") + private Integer discountPercent; + + @TableField(value = "discount_price") + @ApiModelProperty(value = "优惠金额,单位:分") + private String discountPrice; + + @TableField(value = "discount_limit_price") + @ApiModelProperty(value = "折扣上限,百分比折扣也受其约束") + private String discountLimitPrice; + + @TableField(value = "take_count") + @Property(value = "已经领取优惠券的数量") + private Integer takeCount; + + @TableField(value = "use_count") + @ApiModelProperty(value = "使用优惠券的总次数") + private Integer useCount; + + @TableField(exist = false) + @ApiModelProperty(value = "优惠券适用对象列表", required = "json") + private List couponMaterialList; + + @TableField(exist = false) + @Property(value = "是否可领取") + private Boolean canDraw; + + +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponMaterial.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponMaterial.java new file mode 100644 index 0000000..6eaeebd --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponMaterial.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: CouponMaterial + * @Description: 优惠券/模版适用商品对象管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName("shop_coupon_material") +@ApiModel(value = "优惠券/模版适用商品对象管理实体类") +public class CouponMaterial extends CommonInfo { + + @TableId("id") + @Property("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id") + private String materialId; + + @TableField(value = "coupon_id") + @Property(value = "优惠券/模版id") + private String couponId; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponStore.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponStore.java new file mode 100644 index 0000000..b1f6c1e --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponStore.java @@ -0,0 +1,28 @@ +package com.skyeye.coupon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +@Data +@TableName(value = "shop_coupon_store") +@ApiModel(value = "门店与优惠券关联表实体类") +public class CouponStore extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "store_id") + @ApiModelProperty(value = "门店id") + private String storeId; + + @TableField(value = "coupon_id") + @ApiModelProperty(value = "优惠券id") + private String couponId; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUse.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUse.java new file mode 100644 index 0000000..9b1e12d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUse.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.coupon.enums.CouponTakeType; +import com.skyeye.coupon.enums.CouponUseState; +import com.skyeye.coupon.enums.PromotionDiscountType; +import com.skyeye.coupon.enums.PromotionMaterialScope; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: CouponUse + * @Description: 优惠券领取信息管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_coupon_use") +@ApiModel(value = "优惠券领取信息管理实体类") +public class CouponUse extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "coupon_id") + @ApiModelProperty(value = "优惠券id", required = "required") + private String couponId; + + @TableField(exist = false) + @Property(value = "优惠券信息") + private Coupon couponMation; + + @TableField(value = "state") + @Property(value = "状态", enumClass = CouponUseState.class) + private Integer state; + + @TableField(value = "task_type") + @ApiModelProperty(value = "领取类型", required = "required", enumClass = CouponTakeType.class) + private Integer taskType; + + @TableField(value = "use_price") + @Property(value = "是否设置满多少金额可用,单位:分。0 - 不限制,大于 0 - 多少金额可用") + private String usePrice; + + @TableField(value = "product_scope") + @Property(value = "商品范围", enumClass = PromotionMaterialScope.class) + private Integer productScope; + + @TableField(value = "valid_start_time") + @Property(value = "生效开始时间") + private String validStartTime; + + @TableField(value = "valid_end_time") + @Property(value = "生效结束时间") + private String validEndTime; + + @TableField(value = "discount_type") + @Property(value = "折扣类型", enumClass = PromotionDiscountType.class) + private Integer discountType; + + @TableField(value = "discount_percent") + @Property(value = "折扣百分比,例如,80% 为 80") + private Integer discountPercent; + + @TableField(value = "discount_price") + @Property(value = "优惠金额,单位:分") + private String discountPrice; + + @TableField(value = "discount_limit_price") + @Property(value = "折扣上限,百分比折扣也受其越约束") + private String discountLimitPrice; + + @TableField(value = "use_order_id") + @ApiModelProperty(value = "使用订单id") + private String useOrderId; + + @TableField(value = "use_time") + @ApiModelProperty(value = "使用时间") + private String useTime; + + @TableField(exist = false) + @ApiModelProperty(value = "用户领取的优惠券适用对象列表") + private List couponUseMaterialList; + + @TableField(value = "usage_count") + @ApiModelProperty(value = "总使用次数") + private Integer usageCount; + + @TableField(value = "used_count") + @ApiModelProperty(value = "已使用次数") + private Integer usedCount; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUseMaterial.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUseMaterial.java new file mode 100644 index 0000000..04b6f5f --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/entity/CouponUseMaterial.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: CouponUseMaterial + * @Description: 优惠券领取信息管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName("shop_coupon_use_material") +@ApiModel(value = "用户领取的优惠券适用商品对象管理实体类") +public class CouponUseMaterial extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(value = "coupon_id") + @Property(value = "优惠券/模版id") + private String couponId; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponTakeType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponTakeType.java new file mode 100644 index 0000000..6e0c816 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponTakeType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CouponTakeType + * @Description: 优惠券/模版领取方式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/19 8:56 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CouponTakeType implements SkyeyeEnumClass { + + USER(1, "直接领取", "用户可在首页、每日领劵直接领取", true, true), + ADMIN(2, "指定发放", "后台指定会员赠送优惠劵", true, false), + REGISTER(3, "新人券", "注册时自动领取", true, false); + + private Integer key; + + private String value; + + private String remark; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponUseState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponUseState.java new file mode 100644 index 0000000..d340097 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponUseState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CouponUseState + * @Description: 优惠券使用状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/19 9:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CouponUseState implements SkyeyeEnumClass { + + UNUSED(1, "未使用", true, false), + USED(2, "已使用", true, false), + EXPIRE(3, "已过期", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponValidityType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponValidityType.java new file mode 100644 index 0000000..cbde8c8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/CouponValidityType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CouponValidityType + * @Description: 优惠券/模版有效期类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/19 9:09 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CouponValidityType implements SkyeyeEnumClass { + + DATE(1, "固定日期", true, true), + TERM(2, "领取之后", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionDiscountType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionDiscountType.java new file mode 100644 index 0000000..58ad2e7 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionDiscountType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PromotionDiscountType + * @Description: 优惠券/模版折扣类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/19 9:19 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PromotionDiscountType implements SkyeyeEnumClass { + + PRICE(1, "满减", "具体金额", true, true), + PERCENT(2, "折扣", "百分比", true, false); + + private Integer key; + + private String value; + + private String remark; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionMaterialScope.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionMaterialScope.java new file mode 100644 index 0000000..fee05d4 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/enums/PromotionMaterialScope.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PromotionMaterialScope + * @Description: 优惠券/模版使用商品范围枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/19 9:02 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PromotionMaterialScope implements SkyeyeEnumClass { + + ALL(1, "全部商品", true, true), + SPU(2, "指定商品", true, false), + CATEGORY(3, "指定品类", false, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponMaterialService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponMaterialService.java new file mode 100644 index 0000000..e4b7571 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponMaterialService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.coupon.entity.CouponMaterial; + +import java.util.List; + +/** + * @ClassName: CouponMaterialService + * @Description: 优惠券/模版适用商品对象管理服务接口 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:38 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponMaterialService extends SkyeyeBusinessService { + List queryListByCouponId(String couponId); + + void deleteByCouponId(String id); + + void deleteByCouponId(List ids); + + void insertCouponMaterial(String couponId, List couponMaterialList, String userId); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponService.java new file mode 100644 index 0000000..001bae8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.coupon.entity.Coupon; + +/** + * @ClassName: CouponService + * @Description: 优惠券/模版信息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponService extends SkyeyeBusinessService { + void updateTakeCount(String couponId, Integer takeCount); + + void setStateByCoupon(String surveyId); + + void queryCouponListByState(InputObject inputObject, OutputObject outputObject); + + void queryCouponListByMaterialId(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponStoreService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponStoreService.java new file mode 100644 index 0000000..b9db419 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponStoreService.java @@ -0,0 +1,14 @@ +package com.skyeye.coupon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.coupon.entity.CouponStore; + +import java.util.List; + +public interface CouponStoreService extends SkyeyeBusinessService { + void createEntity(String couponId, List storeIdList); + + List queryListByStoreId(String storeId); + + void deleteByCouponIds(List ids); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseMaterialService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseMaterialService.java new file mode 100644 index 0000000..d7e42ce --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseMaterialService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.coupon.entity.CouponUseMaterial; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CouponUseMaterialService + * @Description: 优惠券领取的优惠券适用商品对象管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponUseMaterialService extends SkyeyeBusinessService { + List queryListByCouponIds(List couponIds); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseService.java new file mode 100644 index 0000000..48536c8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/CouponUseService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.coupon.entity.CouponUse; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CouponUseService + * @Description: 优惠券领取信息管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:44 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CouponUseService extends SkyeyeBusinessService { + + Map queryIdTotalMapByCouponId(List couponIdList); + + void setCouponUseStateByDate(String surveyId); + + void setCouponUseStateByTerm(String userId, String couponUseId); + + void updateState(String couponUseId); + + void UpdateUsedCount(String couponUseId); + + void deleteByCouponIds(List ids); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponMaterialServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponMaterialServiceImpl.java new file mode 100644 index 0000000..fb08d67 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponMaterialServiceImpl.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.dao.CouponMaterialDao; +import com.skyeye.coupon.entity.CouponMaterial; +import com.skyeye.coupon.service.CouponMaterialService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: CouponMaterialServiceImpl + * @Description: 优惠券/模版适用商品对象管理服务实现类 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:37 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "优惠券/模版适用商品对象管理", groupName = "优惠券/模版适用商品对象管理", manageShow = false) +public class CouponMaterialServiceImpl extends SkyeyeBusinessServiceImpl implements CouponMaterialService { + + @Override + public List queryListByCouponId(String couponId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponMaterial::getCouponId), couponId); + return list(queryWrapper); + } + + @Override + public void deleteByCouponId(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponMaterial::getCouponId), id); + remove(queryWrapper); + } + + @Override + public void deleteByCouponId(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CouponMaterial::getCouponId), ids); + remove(queryWrapper); + } + + @Override + public void insertCouponMaterial(String couponId, List couponMaterialList, String userId) { + // 删除原本的适用商品信息 + deleteByCouponId(couponId); + // 批量新增 + if (CollectionUtil.isNotEmpty(couponMaterialList)) { + couponMaterialList.forEach(couponMaterial -> { + couponMaterial.setCouponId(couponId); + }); + createEntity(couponMaterialList, userId); + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponServiceImpl.java new file mode 100644 index 0000000..34f3b11 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponServiceImpl.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.dao.CouponDao; +import com.skyeye.coupon.entity.Coupon; +import com.skyeye.coupon.entity.CouponMaterial; +import com.skyeye.coupon.enums.CouponValidityType; +import com.skyeye.coupon.enums.PromotionDiscountType; +import com.skyeye.coupon.enums.PromotionMaterialScope; +import com.skyeye.coupon.service.CouponMaterialService; +import com.skyeye.coupon.service.CouponService; +import com.skyeye.coupon.service.CouponStoreService; +import com.skyeye.coupon.service.CouponUseService; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.shopmaterialnorms.sevice.IShopMaterialNormsService; +import com.skyeye.xxljob.ShopXxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: CouponServiceImpl + * @Description: 优惠券/模版信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:07 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "优惠券/模版信息管理", groupName = "优惠券/模版信息管理") +public class CouponServiceImpl extends SkyeyeBusinessServiceImpl implements CouponService { + + @Autowired + private CouponMaterialService couponMaterialService; + + @Autowired + private IShopMaterialNormsService iShopMaterialNormsService; + + @Autowired + private CouponUseService couponUseService; + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private CouponStoreService couponStoreService; + + private static Logger log = LoggerFactory.getLogger(ShopXxlJob.class); + + @Override + public void validatorEntity(Coupon coupon) { + // 模板新增 + if (StrUtil.isEmpty(coupon.getId()) && StrUtil.isEmpty(coupon.getTemplateId()) && // 主键和模板id为空时,即为模板 + coupon.getProductScope() != PromotionMaterialScope.ALL.getKey() && // 判断适用商品类型 + CollectionUtil.isEmpty(coupon.getCouponMaterialList())) // 不适用全部商品时,适用对象不能为空。 + { + throw new CustomException("需要指定优惠券适用的商品范围,适用全部商品时可为空"); + } + if (Objects.equals(coupon.getValidityType(), CouponValidityType.DATE.getKey())) { + if (StrUtil.isEmpty(coupon.getValidStartTime()) || StrUtil.isEmpty(coupon.getValidEndTime())) { + throw new CustomException("固定日期类型优惠券,有效期不能为空"); + } + try { + // 创建SimpleDateFormat对象,并设置日期格式 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // 将字符串转换为Date对象 + Date parse = sdf.parse(coupon.getValidEndTime()); + Date now = new Date(); + // 判断ValidEndTime是否早于当前时间 + if (parse.before(now)) { + throw new CustomException("优惠券结束时间不能早于当前时间"); + } + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + if (Objects.equals(coupon.getValidityType(), CouponValidityType.TERM.getKey())) { + if (coupon.getFixedStartTime() == null || coupon.getFixedEndTime() == null || coupon.getFixedEndTime() == 0) { + throw new CustomException("领取之后类型优惠券,有效期不能为空或为零"); + } + } + if (Objects.equals(coupon.getDiscountType(), PromotionDiscountType.PRICE.getKey())) { + if (coupon.getDiscountPrice() == null) { + throw new CustomException("价格折扣类型优惠券,折扣金额不能为空"); + } + if (Integer.parseInt(coupon.getDiscountPrice()) > Integer.parseInt(coupon.getDiscountLimitPrice())) { + throw new CustomException("价格折扣类型优惠券,折扣金额不能大于等于优惠上限金额"); + } + if (Integer.parseInt(coupon.getDiscountPrice()) > Integer.parseInt(coupon.getUsePrice())) { + throw new CustomException("价格折扣类型优惠券,折扣金额不能大于等于使用金额"); + } + } else { + if (coupon.getDiscountPercent() == null) { + throw new CustomException("折扣率类型优惠券,折扣率不能为空"); + } + } + if (coupon.getTotalCount() <= CommonNumConstants.NUM_ZERO && coupon.getTotalCount() != -1) { + throw new CustomException("优惠券总量不能为空"); + } + if (coupon.getUseCount() <= CommonNumConstants.NUM_ZERO) { + throw new CustomException("优惠券总使用次数不能为零"); + } + } + + @Override + public void createPrepose(Coupon entity) { + entity.setTakeCount(CommonNumConstants.NUM_ZERO); + } + + @Override + public void createPostpose(Coupon entity, String userId) { + if (CollectionUtil.isNotEmpty(entity.getStoreIdList())) {// 优惠券关联门店 + couponStoreService.createEntity(entity.getId(), entity.getStoreIdList()); + } + if (StrUtil.isNotEmpty(entity.getTemplateId())) {// 优惠券 + if (Objects.equals(entity.getValidityType(), CouponValidityType.DATE.getKey())) { + log.info("优惠券id" + entity.getId() + "创建定时任务-- 开始"); + startUpTaskQuartz(entity.getId(), entity.getName(), entity.getValidEndTime()); + log.info("优惠券id" + entity.getId() + "创建定时任务-- 结束"); + } + } + } + + private void startUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.SHOP_COUPON.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + @Override + public void updatePrepose(Coupon entity) { + Coupon oldCoupon = selectById(entity.getId()); + entity.setTakeCount(oldCoupon.getTakeCount()); + } + + @Override + public void writePostpose(Coupon coupon, String userId) { + // 新增/编辑优惠券的适用商品对象 + if (coupon.getProductScope() == PromotionMaterialScope.ALL.getKey()) { + // 适用全部商品 + List> material = iShopMaterialNormsService.queryAllShopMaterialListForChoose(); + if (CollectionUtil.isNotEmpty(material)) { + List couponMaterialList = material.stream().map(bean -> { + CouponMaterial couponMaterial = new CouponMaterial(); + couponMaterial.setMaterialId(bean.get("id").toString()); + return couponMaterial; + }).collect(Collectors.toList()); + couponMaterialService.insertCouponMaterial(coupon.getId(), couponMaterialList, userId); + } + } else if (coupon.getProductScope() == PromotionMaterialScope.SPU.getKey()) { + // 适用指定商品 + if (CollectionUtil.isNotEmpty(coupon.getCouponMaterialList())) { + couponMaterialService.insertCouponMaterial(coupon.getId(), coupon.getCouponMaterialList(), userId); + } + } + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String type = commonPageInfo.getType(); + if (StrUtil.isEmpty(type)) { + throw new CustomException("暂不支持该类型查询"); + } + String typeKey = MybatisPlusUtil.toColumns(Coupon::getTemplateId); + if (type.equals(CommonNumConstants.NUM_ZERO.toString())) { + queryWrapper.and(wra -> { + wra.isNull(typeKey).or().eq(typeKey, StrUtil.EMPTY); + }); + } + if (type.equals(CommonNumConstants.NUM_ONE.toString())) { + queryWrapper.and(wra -> { + wra.isNotNull(typeKey).ne(typeKey, StrUtil.EMPTY); + }); + } + return queryWrapper; + } + + @Override + public void queryCouponListByState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + String storeId = params.get("storeId").toString(); + String type = params.get("type").toString(); + /* + * todo 优惠券是由厂商发布的,门店无法发放优惠券 + * 需要线判断type,再考虑storeId + * 模板通用、查模板时不需要storeId,先判断type + */ + String typeKey = MybatisPlusUtil.toColumns(Coupon::getTemplateId); + if (StrUtil.equals(type, CommonNumConstants.NUM_ZERO.toString())) { + queryWrapper.and(wrapper -> { + wrapper.isNull(typeKey).or().eq(typeKey, StrUtil.EMPTY); + }); + } + if (StrUtil.equals(type, CommonNumConstants.NUM_ONE.toString())) { + queryWrapper.and(Wrapper -> { + Wrapper.isNotNull(typeKey).ne(typeKey, StrUtil.EMPTY); + }); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(Coupon::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List list = list(queryWrapper); + setDrawState(list);// 设置是否可以领取状态 + outputObject.setBeans(list); + outputObject.settotal(list.size()); + } + + @Override + public void updateTakeCount(String couponId, Integer takeCount) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, couponId); + updateWrapper.set(MybatisPlusUtil.toColumns(Coupon::getTakeCount), takeCount); + update(updateWrapper); + refreshCache(couponId); + } + + @Override + public void deletePostpose(List ids) { + couponMaterialService.deleteByCouponId(ids);// 删除优惠券的适用对象 + couponStoreService.deleteByCouponIds(ids);// 删除优惠券与门店关联的信息 + couponUseService.deleteByCouponIds(ids); // 删除已领取的但是未使用的优惠券 + } + + @Override + public Coupon getDataFromDb(String id) { + Coupon coupon = super.getDataFromDb(id); + coupon.setCouponMaterialList(couponMaterialService.queryListByCouponId(id)); + setDrawState(Collections.singletonList(coupon));// 设置是否可以领取状态 + return coupon; + } + + @Override + public void queryCouponListByMaterialId(InputObject inputObject, OutputObject outputObject) { + String materialId = inputObject.getParams().get("materialId").toString(); + String typeKey = MybatisPlusUtil.toColumns(Coupon::getTemplateId); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .innerJoin(CouponMaterial.class, CouponMaterial::getCouponId, Coupon::getId) + .eq(CouponMaterial::getMaterialId, materialId) + .eq(MybatisPlusUtil.toColumns(Coupon::getEnabled), EnableEnum.ENABLE_USING.getKey()) + .isNotNull(typeKey).ne(typeKey, StrUtil.EMPTY); + List list = skyeyeBaseMapper.selectJoinList(Coupon.class, wrapper); + setDrawState(list);// 设置是否可以领取状态 + outputObject.setBean(list); + outputObject.settotal(list.size()); + } + + private void setDrawState(List list) { + if (CollectionUtil.isEmpty(list)) return; + List couponIdList = list.stream().map(Coupon::getId).collect(Collectors.toList()); + Map map = couponUseService.queryIdTotalMapByCouponId(couponIdList); + for (Coupon coupon : list) { + Integer takeLimitCount = coupon.getTakeLimitCount();// 限制领取数量 + Integer takeCount = map.containsKey(coupon.getId()) ? map.get(coupon.getId()) : CommonNumConstants.NUM_ZERO;// 已经领的 + coupon.setCanDraw(takeLimitCount == -1 ? true : takeCount < takeLimitCount); + } + } + + @Override + public void setStateByCoupon(String surveyId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, surveyId); + updateWrapper.set(MybatisPlusUtil.toColumns(Coupon::getEnabled), EnableEnum.DISABLE_USING.getKey()); + update(updateWrapper); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponStoreServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponStoreServiceImpl.java new file mode 100644 index 0000000..d08f64c --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponStoreServiceImpl.java @@ -0,0 +1,46 @@ +package com.skyeye.coupon.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.dao.CouponStoreDao; +import com.skyeye.coupon.entity.CouponStore; +import com.skyeye.coupon.service.CouponStoreService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@SkyeyeService(name = "门店与优惠券关联表信息管理", groupName = "门店与优惠券关联表信息管理") +public class CouponStoreServiceImpl extends SkyeyeBusinessServiceImpl implements CouponStoreService { + + @Override + public void createEntity(String couponId, List storeIdList) { + List list = super.queryAllData(); + for (String s : storeIdList) { + CouponStore couponStore = new CouponStore(); + couponStore.setStoreId(s); + couponStore.setCouponId(couponId); + list.add(couponStore); + } + super.createEntity(list, StrUtil.EMPTY); + } + + @Override + public List queryListByStoreId(String storeId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponStore::getStoreId), storeId); + return CollectionUtil.isEmpty(list(queryWrapper)) ? new ArrayList<>() : list(queryWrapper); + } + + @Override + public void deleteByCouponIds(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CouponStore::getCouponId), ids); + remove(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseMaterialServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseMaterialServiceImpl.java new file mode 100644 index 0000000..1b4b331 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseMaterialServiceImpl.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.dao.CouponUseMaterialDao; +import com.skyeye.coupon.entity.CouponUseMaterial; +import com.skyeye.coupon.service.CouponUseMaterialService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: CouponUseMaterialServiceImpl + * @Description: 用户领取的优惠券适用商品对象管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户领取的优惠券适用商品对象管理", groupName = "用户领取的优惠券适用商品对象管理", manageShow = false) +public class CouponUseMaterialServiceImpl extends SkyeyeBusinessServiceImpl implements CouponUseMaterialService { + @Override + public List queryListByCouponIds(List couponIds) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CouponUseMaterial::getCouponId), couponIds); + List list = list(queryWrapper); + return CollectionUtil.isEmpty(list) ? new ArrayList<>() : list; + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseServiceImpl.java new file mode 100644 index 0000000..78252b8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/coupon/service/impl/CouponUseServiceImpl.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.coupon.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.constans.SysUserAuthConstants; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.GetUserToken; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.dao.CouponUseDao; +import com.skyeye.coupon.entity.Coupon; +import com.skyeye.coupon.entity.CouponMaterial; +import com.skyeye.coupon.entity.CouponUse; +import com.skyeye.coupon.entity.CouponUseMaterial; +import com.skyeye.coupon.enums.CouponUseState; +import com.skyeye.coupon.enums.CouponValidityType; +import com.skyeye.coupon.enums.PromotionDiscountType; +import com.skyeye.coupon.service.CouponService; +import com.skyeye.coupon.service.CouponUseMaterialService; +import com.skyeye.coupon.service.CouponUseService; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.exception.CustomException; +import com.skyeye.xxljob.ShopXxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: CouponUseServiceImpl + * @Description: 优惠券领取信息管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/10/23 10:43 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "优惠券领取信息管理", groupName = "优惠券领取信息管理") +public class CouponUseServiceImpl extends SkyeyeBusinessServiceImpl implements CouponUseService { + + @Autowired + private CouponService couponService; + + @Autowired + private CouponUseMaterialService couponUseMaterialService; + + @Autowired + private IQuartzService iQuartzService; + + private static Logger log = LoggerFactory.getLogger(ShopXxlJob.class); + + private void check(Coupon coupon) { + if (ObjectUtil.isEmpty(coupon)) { + throw new CustomException("优惠券不存在"); + } + if (Objects.equals(coupon.getEnabled(), WhetherEnum.DISABLE_USING.getKey())) { + throw new CustomException("优惠券已过期"); + } + if (coupon.getTotalCount() != -1) { + // 优惠券数量限制, -1表示不限制, 其他正数表示数量限制 + if (coupon.getTakeCount() >= coupon.getTotalCount()) { + throw new CustomException("优惠券已被领完."); + } + } + // 领取限制, -1表示不限制 + if (coupon.getTakeLimitCount() == -1) { + return; + } + // 个人领取该优惠券的数量限制查询 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCouponId), coupon.getId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCreateId), InputObject.getLogParamsStatic().get("id").toString()); + if (count(queryWrapper) >= coupon.getTakeLimitCount()) { + throw new CustomException("超出领取数量限制"); + } + } + + @Override + public void createPrepose(CouponUse couponUse) { + Coupon coupon = couponService.selectById(couponUse.getCouponId()); + couponUse.setUsageCount(coupon.getUseCount()); + check(coupon); + // 设置适用对象 + List couponUseMaterialList = couponUse.getCouponUseMaterialList(); + for (CouponMaterial couponMaterial : coupon.getCouponMaterialList()) { + CouponUseMaterial couponUseMaterial = new CouponUseMaterial(); + couponUseMaterial.setCouponId(coupon.getId()); + couponUseMaterial.setMaterialId(couponMaterial.getMaterialId()); + couponUseMaterialList.add(couponUseMaterial); + } + // 状态 + couponUse.setState(CouponUseState.UNUSED.getKey()); + //满减 + couponUse.setUsePrice(coupon.getUsePrice()); + //使用范围 + couponUse.setProductScope(coupon.getProductScope()); + //生效时间 + if (Objects.equals(CouponValidityType.DATE.getKey(), coupon.getValidityType())) { + couponUse.setValidStartTime(coupon.getValidStartTime()); + couponUse.setValidEndTime(coupon.getValidEndTime()); + } else { + DateFormat df = new SimpleDateFormat(DateUtil.YYYY_MM_DD_HH_MM_SS); + // 计算开始生效时间 + Date validStartTime = DateUtil.getAfDate(DateUtil.getPointTime(DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD_HH_MM_SS), coupon.getFixedStartTime(), "d"); + // 在开始生效时间基础上加上fixedEndTime天数,得到结束时间 + Date validEndTime = DateUtil.getAfDate(validStartTime, coupon.getFixedEndTime(), "d"); + // 设置优惠券的开始和结束时间 + couponUse.setValidStartTime(df.format(validStartTime)); + couponUse.setValidEndTime(df.format(validEndTime)); +// DateFormat df = new SimpleDateFormat(DateUtil.YYYY_MM_DD_HH_MM_SS); +// couponUse.setValidStartTime(df.format(DateUtil.getAfDate(DateUtil.getPointTime(DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD_HH_MM_SS), coupon.getFixedStartTime(), "d"))); +// couponUse.setValidEndTime(df.format(DateUtil.getAfDate(DateUtil.getPointTime(DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD_HH_MM_SS), coupon.getFixedEndTime(), "d"))); + } + // 领取非固定类型优惠券时,借助couponMation成员变量存储优惠券信息,便于后置执行新增定时任务 + couponUse.setCouponMation(coupon); + //折扣类型 + couponUse.setDiscountType(coupon.getDiscountType()); + //折扣值 + if (Objects.equals(PromotionDiscountType.PERCENT.getKey(), coupon.getDiscountType())) { + couponUse.setDiscountPercent(coupon.getDiscountPercent()); + } else { + couponUse.setDiscountPrice(coupon.getDiscountPrice()); + } + //折扣上限 + couponUse.setDiscountLimitPrice(coupon.getDiscountLimitPrice()); + } + + @Override + public void createPostpose(CouponUse couponUse, String userId) { + // 更新优惠券领取数量 + couponService.updateTakeCount(couponUse.getCouponId(), couponUse.getCouponMation().getTakeCount() + 1); + // 新增优惠券可使用的商品信息 + couponUseMaterialService.createEntity(couponUse.getCouponUseMaterialList(), userId); + // 定时任务 + Coupon couponMation = couponUse.getCouponMation(); + if (Objects.equals(couponMation.getValidityType(), CouponValidityType.TERM.getKey())) { + log.info("领取优惠券的id(couponUseId)" + couponUse.getId() + "创建定时任务--开始"); + startUpTaskQuartz(couponUse.getId(), couponMation.getName(), couponUse.getValidEndTime()); + log.info("领取优惠券的id(couponUseId)" + couponUse.getId() + "创建定时任务--结束"); + } + } + + private void startUpTaskQuartz(String name, String title, String delayedTime) { + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(delayedTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.SHOP_COUPON_USE.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + @Override + public void writePostpose(CouponUse couponUse, String userId) { + if (ObjectUtil.isNotEmpty(couponUse.getCouponUseMaterialList())) { + couponUse.getCouponUseMaterialList().forEach(couponMaterial -> couponMaterial.setCouponId(couponUse.getId())); + couponUseMaterialService.createEntity(couponUse.getCouponUseMaterialList(), userId); + } + } + + @Override + public void updatePrepose(CouponUse couponUse) { + if (StrUtil.isNotEmpty(couponUse.getUseOrderId())) { + couponUse.setUseTime(DateUtil.getTimeAndToString()); + couponUse.setState(CouponUseState.USED.getKey()); + } + } + + @Override + public void updatePostpose(CouponUse couponUse, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCouponId), couponUse.getCouponId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.USED.getKey()); + Coupon coupon = couponService.selectById(couponUse.getCouponId()); + if (ObjectUtil.isNotEmpty(coupon) && Objects.equals(coupon.getValidityType(), CouponValidityType.TERM.getKey())) { + iQuartzService.stopAndDeleteTaskQuartz(couponUse.getId());// 删除任务 + } + } + + @Override + protected List> queryPageDataList(InputObject inputObject) { + List> mapList = super.queryPageDataList(inputObject); + couponService.setMationForMap(mapList, "couponId", "couponMation"); + return mapList; + } + + @Override + public List> queryDataList(InputObject inputObject) { + Map params = inputObject.getParams(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCreateId), inputObject.getLogParams().get("id").toString()); + if (params.containsKey("state")) { + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getState), params.get("state").toString()); + } + // 查询时获取数据 + List list = list(queryWrapper); + couponService.setDataMation(list, CouponUse::getCouponId); + List collect = list.stream().map(item -> { + if (item.getCouponMation() != null) { + item.setUsageCount(item.getCouponMation().getUseCount()); + } + return item; + }).collect(Collectors.toList()); + return JSONUtil.toList(JSONUtil.toJsonStr(collect), null); + } + + @Override + public Map queryIdTotalMapByCouponId(List couponIdList) { + String userToken = GetUserToken.getUserToken(InputObject.getRequest()); + if (StrUtil.isEmpty(userToken)) { + return new HashMap<>(); + } + String userTokenUserId = GetUserToken.getUserTokenUserId(InputObject.getRequest()); + Boolean aBoolean = SysUserAuthConstants.exitUserLoginRedisCache(userTokenUserId); + if (!aBoolean) { + return new HashMap<>(); + } + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.select(MybatisPlusUtil.toColumns(CouponUse::getCouponId), "count(id) as total"); + queryWrapper.in(MybatisPlusUtil.toColumns(CouponUse::getCouponId), couponIdList); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCreateId), userId); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(CouponUse::getCouponId)); + List> mapList = listMaps(queryWrapper); + return CollectionUtil.isEmpty(mapList) ? new HashMap<>() + : mapList.stream().collect(Collectors.toMap(map -> map.get("coupon_id").toString(), map -> Integer.parseInt(map.get("total").toString()))); + } + + /** + * xxlJob任务管理器定时修改过期优惠券的状态 + */ + @Override + public void setCouponUseStateByDate(String couponId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + // 取优未使用的优惠券 + updateWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.UNUSED.getKey()); + updateWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCouponId), couponId); + // 更改状态为过期 + updateWrapper.set(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.EXPIRE.getKey()); + update(updateWrapper); + } + + @Override + public void setCouponUseStateByTerm(String userId, String couponUseId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, couponUseId); + updateWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getCreateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.EXPIRE.getKey()); + update(updateWrapper); + } + + @Override + public void updateState(String couponUseId) { + CouponUse couponUse = selectById(couponUseId); + if (ObjUtil.isEmpty(couponUse)) { + throw new CustomException("优惠券使用记录不存在"); + } + if (couponUse.getUsedCount() == couponUse.getUsageCount()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, couponUseId); + updateWrapper.set(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.USED.getKey()); + update(updateWrapper); + } + } + + @Override + public void UpdateUsedCount(String couponUseId) { + CouponUse couponUse = selectById(couponUseId); + if (ObjUtil.isEmpty(couponUse)) { + throw new CustomException("优惠券使用记录不存在"); + } + Integer usedCount = couponUse.getUsedCount(); + if (couponUse.getUsedCount() < couponUse.getUsageCount()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, couponUseId); + updateWrapper.set(MybatisPlusUtil.toColumns(CouponUse::getUsedCount), usedCount + 1); + update(updateWrapper); + } else { + throw new CustomException("优惠券使用次数已达到上限"); + } + } + + @Override + public void deleteByCouponIds(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(CouponUse::getCouponId), ids); + queryWrapper.eq(MybatisPlusUtil.toColumns(CouponUse::getState), CouponUseState.UNUSED.getKey()); + remove(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryCompanyController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryCompanyController.java new file mode 100644 index 0000000..9710499 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryCompanyController.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.delivery.entity.ShopDeliveryCompany; +import com.skyeye.delivery.service.ShopDeliveryCompanyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopDeliveryCompanyController + * @Description: 快递公司管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "快递公司管理", tags = "快递公司管理", modelName = "快递公司管理") +public class ShopDeliveryCompanyController { + + @Autowired + private ShopDeliveryCompanyService shopDeliveryCompanyService; + + /** + * 分页获取快递公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDeliveryList", value = "分页获取快递公司信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopDeliveryCompanyController/queryDeliveryList") + public void queryMemberLevelList(InputObject inputObject, OutputObject outputObject) { + shopDeliveryCompanyService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑快递公司 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeDelivery", value = "添加/编辑快递公司", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopDeliveryCompany.class) + @RequestMapping("/post/ShopDeliveryCompanyController/writeDelivery") + public void writeDelivery(InputObject inputObject, OutputObject outputObject) { + shopDeliveryCompanyService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除快递公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteDeliveryByIds", value = "批量删除快递公司信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopDeliveryCompanyController/deleteDeliveryByIds") + public void deleteDeliveryByIds(InputObject inputObject, OutputObject outputObject) { + shopDeliveryCompanyService.deleteByIds(inputObject, outputObject); + } + + /** + * 获取全部已启用快递公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDelivery", value = "获取全部已启用快递公司信息", method = "POST", allUse = "0") + @RequestMapping("/post/ShopDeliveryCompanyController/queryDelivery") + public void queryDelivery(InputObject inputObject, OutputObject outputObject) { + shopDeliveryCompanyService.queryList(inputObject, outputObject); + } + + /** + * 根据id获取快递公司信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDeliveryById", value = "根据id获取快递公司信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopDeliveryCompanyController/queryDeliveryById") + public void queryDeliveryById(InputObject inputObject, OutputObject outputObject) { + shopDeliveryCompanyService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateChargeController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateChargeController.java new file mode 100644 index 0000000..826b15f --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateChargeController.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.delivery.entity.ShopDeliveryTemplateCharge; +import com.skyeye.delivery.service.ShopDeliveryTemplateChargeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopDeliveryTemplateChargeController + * @Description: 快递运费费用模版控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "快递运费费用模版", tags = "快递运费费用模版", modelName = "快递运费费用模版") +public class ShopDeliveryTemplateChargeController { + + @Autowired + private ShopDeliveryTemplateChargeService shopDeliveryTemplateChargeService; + + /** + * 新增/编辑快递运费费用模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopDeliveryTemplateCharge", value = "添加/修改快递运费模板", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopDeliveryTemplateCharge.class) + @RequestMapping("/post/shopDeliveryTemplateChargeController/writeShopDeliveryTemplateCharge") + public void writeShopDeliveryTemplateCharge(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateChargeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除快递运费费用模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShopDeliveryTemplateChargeByIds", value = "批量删除快递运费模版信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/shopDeliveryTemplateChargeController/deleteShopDeliveryTemplateChargeByIds") + public void deleteShopDeliveryTemplateChargeByIds(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateChargeService.deleteByIds(inputObject, outputObject); + } + + /** + * 分页查询快递运费费用模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopDeliveryTemplateChargeList", value = "分页查询快递运费模版信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/shopDeliveryTemplateChargeController/queryShopDeliveryTemplateChargeList") + public void queryShopDeliveryTemplateChargeList(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateChargeService.queryPageList(inputObject, outputObject); + } + + /** + * 获取已启用的快递运费费用模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopDeliveryTemplateCharge", value = "获取全部快递运费费用模版信息", method = "POST", allUse = "0") + @RequestMapping("/post/shopDeliveryTemplateChargeController/queryShopDeliveryTemplateCharge") + public void queryShopDeliveryTemplateCharge(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateChargeService.queryList(inputObject, outputObject); + } + + /** + * 根据id获取快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopDeliveryTemplateChargeById", value = "根据id获取快递运费模版信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/shopDeliveryTemplateChargeController/queryShopDeliveryTemplateChargeById") + public void queryShopDeliveryTemplateChargeById(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateChargeService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateController.java new file mode 100644 index 0000000..8642a5b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/controller/ShopDeliveryTemplateController.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import com.skyeye.delivery.entity.ShopDeliveryCompany; +import com.skyeye.delivery.entity.ShopDeliveryTemplate; +import com.skyeye.delivery.service.ShopDeliveryTemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopDeliveryTemplateController + * @Description: 快递运费模版控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "快递运费模版", tags = "快递运费模版", modelName = "快递运费模版") +public class ShopDeliveryTemplateController { + + @Autowired + private ShopDeliveryTemplateService shopDeliveryTemplateService; + + /** + * 新增/编辑快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopDeliveryTemplate", value = "添加/修改快递运费模板", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopDeliveryTemplate.class) + @RequestMapping("/post/ShopDeliveryCompanyController/writeShopDeliveryTemplate") + public void writeShopDeliveryTemplate(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShopDeliveryTemplateByIds", value = "批量删除快递运费模版信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/ShopDeliveryTemplateController/deleteShopDeliveryTemplateByIds") + public void deleteShopDeliveryTemplateByIds(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateService.deleteByIds(inputObject, outputObject); + } + + /** + * 分页查询快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopDeliveryTemplateList", value = "分页查询快递运费模版信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopDeliveryTemplateController/queryShopDeliveryTemplateList") + public void queryShopDeliveryTemplateList(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateService.queryPageList(inputObject, outputObject); + } + + /** + * 获取全部已启用的快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopDeliveryTemplate", value = "获取全部快递运费模版信息", method = "POST", allUse = "0") + @RequestMapping("/post/ShopDeliveryTemplateController/queryShopDeliveryTemplate") + public void queryShopDeliveryTemplate(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateService.queryList(inputObject, outputObject); + } + + /** + * 根据id获取快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectShopDeliveryTemplateById", value = "根据id获取快递运费模版信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopDeliveryTemplateController/selectShopDeliveryTemplateById") + public void selectShopDeliveryTemplateById(InputObject inputObject, OutputObject outputObject) { + shopDeliveryTemplateService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryCompanyDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryCompanyDao.java new file mode 100644 index 0000000..555e67f --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryCompanyDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.dao; + +import com.skyeye.delivery.entity.ShopDeliveryCompany; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopDeliveryCompanyDao + * @Description: 快递公司管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryCompanyDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateChargeDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateChargeDao.java new file mode 100644 index 0000000..5438799 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateChargeDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.dao; + +import com.skyeye.delivery.entity.ShopDeliveryTemplateCharge; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopDeliveryTemplateChargeDao + * @Description: 快递运费费用模版数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryTemplateChargeDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateDao.java new file mode 100644 index 0000000..bb5e966 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/dao/ShopDeliveryTemplateDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.dao; + +import com.skyeye.delivery.entity.ShopDeliveryTemplate; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopDeliveryTemplateDao + * @Description: 快递运费模版数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryTemplateDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryCompany.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryCompany.java new file mode 100644 index 0000000..6deda67 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryCompany.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ShopDeliveryCompany + * @Description: 快递公司管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "shop_delivery_company") +@ApiModel("快递公司管理") +public class ShopDeliveryCompany extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`code_num`") + @ApiModelProperty(value = "快递公司 code",required = "required") + private String codeNum; + + @TableField(value = "`name`") + @ApiModelProperty(value = "快递公司名称", required = "required",fuzzyLike = true) + private String name; + + @TableField(value = "`logo`") + @ApiModelProperty(value = "快递公司 logo",required = "required") + private String logo; + + @TableField(value = "`remark`") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "`enabled`") + @ApiModelProperty(value = "状态",required = "required") + private String enabled; + + @TableField(value = "`order_by`") + @ApiModelProperty(value = "排序",required = "required") + private Integer orderBy; + + @TableField(value = "`store_id`") + @ApiModelProperty(value = "门店id",required = "required",fuzzyLike = true) + private String storeId; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplate.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplate.java new file mode 100644 index 0000000..de79ec6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplate.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ShopDeliveryTemplate + * @Description: 快递运费模版实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_delivery_template") +@ApiModel("快递运费模版") +public class ShopDeliveryTemplate extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "模板名称",required = "required",fuzzyLike = true) + private String name; + + @TableField(value = "`remark`") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField(value = "`type`") + @ApiModelProperty(value = "配送计费方式,参考#DeliveryExpressType",required = "num") + private Integer type; + + @TableField(value = "`order_by`") + @ApiModelProperty(value = "排序",required = "num") + private Integer orderBy; + + @TableField(value = "`store_id`") + @ApiModelProperty(value = "门店id",fuzzyLike = true) + private String storeId; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplateCharge.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplateCharge.java new file mode 100644 index 0000000..205470d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/entity/ShopDeliveryTemplateCharge.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: ShopDeliveryTemplateCharge + * @Description: 快递公司管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@TableName(value = "shop_delivery_template_charge") +@ApiModel("快递公司管理") +public class ShopDeliveryTemplateCharge extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`template_id`") + @ApiModelProperty(value = "模板ID",required = "required",fuzzyLike = true) + private String templateId; + + @TableField(value = "`area_id`") + @ApiModelProperty(value = "区域id,集合",required = "required") + private String areaId; + + @TableField(value = "`start_count`") + @ApiModelProperty(value = "首件数量(件数,重量,或体积)") + private Double startCount; + + @TableField(value = "`start_price`") + @ApiModelProperty(value = "起步价,单位:分") + private String startPrice; + + @TableField(value = "`extra_count`") + @ApiModelProperty(value = "续件数量(件, 重量,或体积)") + private Double extraCount; + + @TableField(value = "`extra_price`") + @ApiModelProperty(value = "额外价,单位:分") + private String extraPrice; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/enums/DeliveryExpressType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/enums/DeliveryExpressType.java new file mode 100644 index 0000000..20e73ac --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/enums/DeliveryExpressType.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: DeliveryExpressType + * @Description: 快递配送计费方式枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/20 17:16 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum DeliveryExpressType implements SkyeyeEnumClass { + + COUNT(1, "按件", true, false), + WEIGHT(2, "按重量", true, false), + VOLUME(3, "按体积", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryCompanyService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryCompanyService.java new file mode 100644 index 0000000..8a9ec38 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryCompanyService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.delivery.entity.ShopDeliveryCompany; + +/** + * @ClassName: ShopDeliveryCompanyService + * @Description: 快递公司管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryCompanyService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateChargeService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateChargeService.java new file mode 100644 index 0000000..1a94747 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateChargeService.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.delivery.entity.ShopDeliveryTemplateCharge; + +/** + * @ClassName: StoreTypeController + * @Description: 快递运费费用模板服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryTemplateChargeService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateService.java new file mode 100644 index 0000000..f3233eb --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/ShopDeliveryTemplateService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.delivery.entity.ShopDeliveryTemplate; + +/** + * @ClassName: ShopDeliveryTemplateService + * @Description: 快递运费模板服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopDeliveryTemplateService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryCompanyServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryCompanyServiceImpl.java new file mode 100644 index 0000000..064d288 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryCompanyServiceImpl.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.delivery.dao.ShopDeliveryCompanyDao; +import com.skyeye.delivery.entity.ShopDeliveryCompany; +import com.skyeye.delivery.service.ShopDeliveryCompanyService; +import com.skyeye.exception.CustomException; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopDeliveryCompanyServiceImpl + * @Description: 快递运费模版服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "快递公司管理", groupName = "快递公司管理") +public class ShopDeliveryCompanyServiceImpl extends SkyeyeBusinessServiceImpl implements ShopDeliveryCompanyService { + + @Autowired + private ShopStoreService shopStoreService; + + /** + * 分页查询-快递公司 + * + * @param commonPageInfo + * @return + */ + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.like(MybatisPlusUtil.toColumns(ShopDeliveryCompany::getStoreId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + /** + * 获取全部已启用广告位管理信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopDeliveryCompany::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + /** + * 重写新增编辑前置条件快递公司管理信息 + */ + @Override + public void validatorEntity(ShopDeliveryCompany shopDeliveryCompany) { + super.validatorEntity(shopDeliveryCompany); + if (StrUtil.isNotEmpty(shopDeliveryCompany.getCodeNum()) && shopDeliveryCompany.getCodeNum().length() > 50) { + throw new CustomException("快递公司 code过长"); + } + if (StrUtil.isNotEmpty(shopDeliveryCompany.getName()) && shopDeliveryCompany.getName().length() > 50) { + throw new CustomException("快递公司名称过长"); + } + if (shopDeliveryCompany.getOrderBy() < -128 || shopDeliveryCompany.getOrderBy() > 127) { + throw new CustomException("运费模板排序值超出范围"); + } + //判断StoreId是否存在 + if (ObjectUtil.isNotNull(shopDeliveryCompany.getStoreId())) { + ShopStore shopStore = shopStoreService.selectById(shopDeliveryCompany.getStoreId()); + //判断shopStore是否为空,如果为空,则抛出异常 + if (StrUtil.isEmpty(shopStore.getId())) { + throw new CustomException("门店不存在: " + shopDeliveryCompany.getStoreId()); + } + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateChargeServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateChargeServiceImpl.java new file mode 100644 index 0000000..69c3c1d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateChargeServiceImpl.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.adsense.entity.Adsense; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.delivery.dao.ShopDeliveryTemplateChargeDao; +import com.skyeye.delivery.entity.ShopDeliveryTemplate; +import com.skyeye.delivery.entity.ShopDeliveryTemplateCharge; +import com.skyeye.delivery.service.ShopDeliveryTemplateChargeService; +import com.skyeye.delivery.service.ShopDeliveryTemplateService; +import com.skyeye.exception.CustomException; +import com.skyeye.store.entity.ShopArea; +import com.skyeye.store.service.ShopAreaService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopDeliveryTemplateChargeServiceImpl + * @Description: 快递运费费用模版服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "快递运费费用模版", groupName = "快递运费费用模版") +public class ShopDeliveryTemplateChargeServiceImpl extends SkyeyeBusinessServiceImpl implements ShopDeliveryTemplateChargeService { + + @Autowired + private ShopDeliveryTemplateService shopDeliveryTemplateService; + + @Autowired + private ShopAreaService shopAreaService; + + /** + * 分页查询-根据快递运费模版模板ID + * @param commonPageInfo + * @return + */ + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String objectStr = commonPageInfo.getObjectId(); + if (StrUtil.isNotEmpty(objectStr)) { + queryWrapper.like(MybatisPlusUtil.toColumns(ShopDeliveryTemplateCharge::getTemplateId), objectStr); + } + return queryWrapper; + } + + /** + * 获取全部快递运费费用模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @return + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + /** + * 重写新增编辑前置条件快递运费费用模版信息 + */ + @Override + public void validatorEntity(ShopDeliveryTemplateCharge shopDeliveryTemplateCharge) { + super.validatorEntity(shopDeliveryTemplateCharge); + ShopDeliveryTemplate shopDeliveryTemplate = shopDeliveryTemplateService.selectById(shopDeliveryTemplateCharge.getTemplateId()); + ShopArea shopArea = shopAreaService.selectById(shopDeliveryTemplateCharge.getAreaId()); + + // 判断shopDeliveryTemplate是否为空,如果为空则抛出异常 + if (StrUtil.isEmpty(shopDeliveryTemplate.getId())) { + throw new CustomException("模板不存在: " + shopDeliveryTemplateCharge.getTemplateId()); + } + + // 判断shopArea是否为空,如果为空则抛出异常 + if (StrUtil.isEmpty(shopArea.getId())) { + throw new CustomException("区域不存在: " + shopDeliveryTemplateCharge.getAreaId()); + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateServiceImpl.java new file mode 100644 index 0000000..85e2b74 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/delivery/service/impl/ShopDeliveryTemplateServiceImpl.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.delivery.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.delivery.dao.ShopDeliveryTemplateDao; +import com.skyeye.delivery.entity.ShopDeliveryTemplate; +import com.skyeye.delivery.service.ShopDeliveryTemplateService; +import com.skyeye.exception.CustomException; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopDeliveryTemplateServiceImpl + * @Description: 快递运费模版服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "快递运费模版", groupName = "快递运费模版") +public class ShopDeliveryTemplateServiceImpl extends SkyeyeBusinessServiceImpl implements ShopDeliveryTemplateService { + + @Autowired + private ShopStoreService shopStoreService; + + /** + * 分页查询-快递运费模版 + * + * @param commonPageInfo + * @return + */ + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopDeliveryTemplate::getStoreId), commonPageInfo.getObjectId()); + return queryWrapper; + } + + /** + * 获取全部快递运费模版信息 + * + * @param inputObject 入参以及用户信息等获取对象 + */ + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List beans = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + /** + * 重写新增编辑前置条件快递运费模版信息 + */ + @Override + public void validatorEntity(ShopDeliveryTemplate shopDeliveryTemplate) { + super.validatorEntity(shopDeliveryTemplate); + if (StrUtil.isNotEmpty(shopDeliveryTemplate.getName()) && shopDeliveryTemplate.getName().length() > 100) { + throw new CustomException("运费模板名称过长"); + } + if (shopDeliveryTemplate.getOrderBy() < -128 || shopDeliveryTemplate.getOrderBy() > 127) { + throw new CustomException("运费模板排序值超出范围"); + } + + //判断StoreId是否存在 + if (StrUtil.isNotEmpty(shopDeliveryTemplate.getStoreId())) { + ShopStore shopStore = shopStoreService.selectById(shopDeliveryTemplate.getStoreId()); + //判断shopStore是否为空,如果为空,则抛出异常 + if (StrUtil.isEmpty(shopStore.getId())) { + throw new CustomException("门店不存在: " + shopStore.getId()); + } + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderState.java new file mode 100644 index 0000000..1dcb813 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderState.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: KeepFitOrderState + * @Description: 保养订单状态枚举类 + * 操作: 保养完成 核销 + * 状态:保养中 ----------》待核销 ----------》已核销 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 19:55 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum KeepFitOrderState implements SkyeyeEnumClass { + + NO_PAYING(1, "待支付", true, false), + PAY(2, "已支付", true, false), + FIT_COMPLATE(3, "保养完成(待核销)", true, false), + PAY_VERIFICATION(4, "已核销", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderUserType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderUserType.java new file mode 100644 index 0000000..a79b316 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/classenum/KeepFitOrderUserType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: KeepFitOrderUserType + * @Description: 保养订单用户类型枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 19:45 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum KeepFitOrderUserType implements SkyeyeEnumClass { + + ANONYMOUS_USER(1, "匿名用户", true, false), + MEMBER(2, "会员", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/controller/KeepFitOrderController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/controller/KeepFitOrderController.java new file mode 100644 index 0000000..dffa6c9 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/controller/KeepFitOrderController.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.keepfit.entity.KeepFitOrder; +import com.skyeye.keepfit.service.KeepFitOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: KeepFitOrderController + * @Description: 保养订单管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "保养订单管理", tags = "保养订单管理", modelName = "保养订单管理") +public class KeepFitOrderController { + + @Autowired + private KeepFitOrderService keepFitOrderService; + + /** + * 获取保养订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryKeepFitOrderList", value = "获取保养订单信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/KeepFitOrderController/queryKeepFitOrderList") + public void queryKeepFitOrderList(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 添加订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertKeepFitOrder", value = "添加订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = KeepFitOrder.class) + @RequestMapping("/post/KeepFitOrderController/insertKeepFitOrder") + public void insertKeepFitOrder(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.createEntity(inputObject, outputObject); + } + + /** + * 支付订单完成后的回调 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "keepFitOrderNotify", value = "支付订单完成后的回调", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "out_trade_no", name = "outTradeNo", value = "商户订单号", required = "required"), + @ApiImplicitParam(id = "total_fee", name = "totalFee", value = "实际支付的订单金额:单位 分", required = "required")}) + @RequestMapping("/post/KeepFitOrderController/keepFitOrderNotify") + public void keepFitOrderNotify(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.keepFitOrderNotify(inputObject, outputObject); + } + + /** + * 保养订单购买详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryKeepFitOrderById", value = "保养订单购买详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "保养订单id", required = "required")}) + @RequestMapping("/post/KeepFitOrderController/queryKeepFitOrderById") + public void queryKeepFitOrderById(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.selectById(inputObject, outputObject); + } + + /** + * 单据核销 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "verificationKeepFitOrder", value = "单据核销", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "保养订单id", required = "required")}) + @RequestMapping("/post/KeepFitOrderController/verificationKeepFitOrder") + public void verificationOrder(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.verificationOrder(inputObject, outputObject); + } + + /** + * 删除保养订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteKeepFitOrderById", value = "删除保养订单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/KeepFitOrderController/deleteKeepFitOrderById") + public void deleteKeepFitOrderById(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.deleteById(inputObject, outputObject); + } + + /** + * 完成保养 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "complateKeepFitOrder", value = "完成保养", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "订单id", required = "required"), + @ApiImplicitParam(id = "serviceTechnicianId", name = "serviceTechnicianId", value = "维修技师id(员工id)", required = "required"), + @ApiImplicitParam(id = "nextServiceMileage", name = "nextServiceMileage", value = "下次保养公里数", required = "required,num"), + @ApiImplicitParam(id = "nextServiceTime", name = "nextServiceTime", value = "下次保养时间 格式为yyyy-MM-dd", required = "required")}) + @RequestMapping("/post/KeepFitOrderController/complateKeepFitOrder") + public void complateKeepFitOrder(InputObject inputObject, OutputObject outputObject) { + keepFitOrderService.complateKeepFitOrder(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderConsumeDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderConsumeDao.java new file mode 100644 index 0000000..31e93f6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderConsumeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.keepfit.entity.KeepFitOrderConsume; + +/** + * @ClassName: KeepFitOrderConsumeDao + * @Description: 保养订单耗材管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 16:22 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KeepFitOrderConsumeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderDao.java new file mode 100644 index 0000000..a22328b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/dao/KeepFitOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.keepfit.entity.KeepFitOrder; + +/** + * @ClassName: KeepFitOrderDao + * @Description: 保养订单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KeepFitOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrder.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrder.java new file mode 100644 index 0000000..2d563b6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrder.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.meal.entity.MealOrderChild; +import com.skyeye.store.entity.ShopStore; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: KeepFitOrderMation + * @Description: 保养订单管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "shop:keepFitOrder", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_keepfit_order") +@ApiModel("保养订单管理实体类") +public class KeepFitOrder extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property(value = "单据编号", fuzzyLike = true) + private String oddNumber; + + @TableField("type") + @ApiModelProperty(value = "订单来源,和套餐订单一样,参考#ShopMealOrderType", required = "required,num") + private Integer type; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("user_type") + @ApiModelProperty(value = "用户类型,参考#KeepFitOrderUserType", required = "required,num") + private Integer userType; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key") + private String objectKey; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Map materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "规格物品编码", fuzzyLike = true) + private String codeNum; + + @TableField(exist = false) + @Property(value = "规格物品编码信息") + private Map codeNumMation; + + @TableField("payable_price") + @Property(value = "应付金额") + private String payablePrice; + + @TableField("pay_price") + @Property(value = "实付金额") + private String payPrice; + + @TableField("pay_time") + @Property(value = "实付日期") + private String payTime; + + @TableField("service_price") + @ApiModelProperty(value = "服务费", required = "double", defaultValue = "0.0") + private String servicePrice; + + @TableField("meal_order_child_id") + @ApiModelProperty(value = "如果使用套餐,则为套餐订单子表的id 如果user_type=2,该字段可能有值") + private String mealOrderChildId; + + @TableField(exist = false) + @Property(value = "套餐订单子表信息") + private MealOrderChild mealOrderChildMation; + + @TableField(value = "store_id") + @ApiModelProperty(value = "门店ID", required = "required") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private ShopStore storeMation; + + @TableField(value = "state") + @Property(value = "状态,参考#KeepFitOrderState") + private Integer state; + + @TableField(value = "online_day") + @ApiModelProperty(value = "线上预约日期 如果type=1,该字段必有值") + private String onlineDay; + + @TableField(value = "online_time") + @ApiModelProperty(value = "线上预约时间段 如果type=1,该字段必有值") + private String onlineTime; + + @TableField(value = "complate_pay_user_id") + @Property(value = "完成支付操作的操作人id") + private String complatePayUserId; + + @TableField(exist = false) + @Property(value = "完成支付操作的操作人信息") + private Map complatePayUserMation; + + @TableField(value = "verification_user_id") + @Property(value = "完成核销时的操作人id") + private String verificationUserId; + + @TableField(exist = false) + @Property(value = "完成核销时的操作人信息") + private Map verificationUserMation; + + @TableField(value = "service_technician_id") + @Property(value = "维修技师id(员工id)") + private String serviceTechnicianId; + + @TableField(exist = false) + @Property(value = "维修技师信息") + private Map serviceTechnicianMation; + + @TableField(value = "next_service_mileage") + @Property(value = "下次保养公里数") + private String nextServiceMileage; + + @TableField(value = "next_service_time") + @Property(value = "下次保养时间,格式为yyyy-MM-dd") + private String nextServiceTime; + + @TableField(exist = false) + @ApiModelProperty(value = "保养订单耗材") + private List consumeMationList; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrderConsume.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrderConsume.java new file mode 100644 index 0000000..8bad56a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/entity/KeepFitOrderConsume.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: KeepFitOrderConsume + * @Description: 保养订单关联耗材实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:16 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_keepfit_order_consume") +@ApiModel("保养订单关联耗材实体类") +public class KeepFitOrderConsume extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("order_id") + @Property(value = "订单id") + private String orderId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Map materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "规格物品编码", fuzzyLike = true) + private String codeNum; + + @TableField(exist = false) + @ApiModelProperty(value = "产品条形码编号集合", required = "json") + private List normsCodeList; + + @TableField(exist = false) + @Property(value = "规格物品编码信息") + private Map codeNumMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("oper_number") + @ApiModelProperty(value = "申领数量", required = "required,num") + private Integer operNumber; + + @TableField("unit_price") + @ApiModelProperty(value = "单价", required = "double", defaultValue = "0") + private String unitPrice; + + @TableField("all_price") + @ApiModelProperty(value = "总金额", required = "double", defaultValue = "0") + private String allPrice; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderConsumeService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderConsumeService.java new file mode 100644 index 0000000..5b25f5b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderConsumeService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.keepfit.entity.KeepFitOrderConsume; + +import java.util.List; + +/** + * @ClassName: KeepFitOrderConsumeService + * @Description: 保养订单关联耗材服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 20:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KeepFitOrderConsumeService extends SkyeyeBusinessService { + + String calculationTotalPrice(List keepFitOrderConsumeList); + + void deleteByOrderId(String orderId); + + List selectByOrderId(String orderId); + + void saveList(String orderId, List keepFitOrderConsumeList); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderService.java new file mode 100644 index 0000000..c33c85a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/KeepFitOrderService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.keepfit.entity.KeepFitOrder; + +/** + * @ClassName: KeepFitOrderService + * @Description: 保养订单管理服务接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface KeepFitOrderService extends SkyeyeBusinessService { + + void keepFitOrderNotify(InputObject inputObject, OutputObject outputObject); + + void verificationOrder(InputObject inputObject, OutputObject outputObject); + + void complateKeepFitOrder(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderConsumeServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderConsumeServiceImpl.java new file mode 100644 index 0000000..d76930b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderConsumeServiceImpl.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.exception.CustomException; +import com.skyeye.keepfit.dao.KeepFitOrderConsumeDao; +import com.skyeye.keepfit.entity.KeepFitOrderConsume; +import com.skyeye.keepfit.service.KeepFitOrderConsumeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: KeepFitOrderConsumeServiceImpl + * @Description: 保养订单关联耗材服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 20:23 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "保养订单关联耗材", groupName = "保养订单管理", manageShow = false) +public class KeepFitOrderConsumeServiceImpl extends SkyeyeBusinessServiceImpl implements KeepFitOrderConsumeService { + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Override + public String calculationTotalPrice(List keepFitOrderConsumeList) { + String payablePrice = "0"; + if (CollectionUtil.isNotEmpty(keepFitOrderConsumeList)) { + List normsId = keepFitOrderConsumeList.stream() + .map(KeepFitOrderConsume::getNormsId).distinct().collect(Collectors.toList()); + Map> normsMap = iMaterialNormsService + .queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsId)); + + for (KeepFitOrderConsume bean : keepFitOrderConsumeList) { + Map norms = normsMap.get(bean.getNormsId()); + if (CollectionUtil.isEmpty(norms) || StrUtil.isEmpty(norms.get("retailPrice").toString())) { + throw new CustomException("耗材不存在,请刷新后重试."); + } + String retailPrice = norms.get("retailPrice").toString(); + bean.setUnitPrice(retailPrice); + String allPrice = CalculationUtil.multiply(CommonNumConstants.NUM_TWO, String.valueOf(bean.getOperNumber()), retailPrice); + bean.setAllPrice(allPrice); + payablePrice = CalculationUtil.add(payablePrice, allPrice, CommonNumConstants.NUM_TWO); + } + } + return payablePrice; + } + + @Override + public void deleteByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrderConsume::getOrderId), orderId); + remove(queryWrapper); + } + + @Override + public List selectByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrderConsume::getOrderId), orderId); + List keepFitOrderConsumeList = list(queryWrapper); + return keepFitOrderConsumeList; + } + + @Override + public void saveList(String orderId, List keepFitOrderConsumeList) { + deleteByOrderId(orderId); + if (CollectionUtil.isNotEmpty(keepFitOrderConsumeList)) { + for (KeepFitOrderConsume keepFitOrderConsume : keepFitOrderConsumeList) { + keepFitOrderConsume.setOrderId(orderId); + } + createEntity(keepFitOrderConsumeList, StrUtil.EMPTY); + } + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderServiceImpl.java new file mode 100644 index 0000000..0e3c031 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/keepfit/service/impl/KeepFitOrderServiceImpl.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.keepfit.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.keepfit.classenum.KeepFitOrderState; +import com.skyeye.keepfit.classenum.KeepFitOrderUserType; +import com.skyeye.keepfit.dao.KeepFitOrderDao; +import com.skyeye.keepfit.entity.KeepFitOrder; +import com.skyeye.keepfit.entity.KeepFitOrderConsume; +import com.skyeye.keepfit.service.KeepFitOrderConsumeService; +import com.skyeye.keepfit.service.KeepFitOrderService; +import com.skyeye.meal.classenum.ShopMealOrderType; +import com.skyeye.meal.service.MealOrderChildService; +import com.skyeye.rest.norms.service.IMaterialNormsCodeService; +import com.skyeye.service.MemberService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: KeepFitOrderServiceImpl + * @Description: 保养订单服务类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/8 15:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "保养订单管理", groupName = "保养订单管理") +public class KeepFitOrderServiceImpl extends SkyeyeBusinessServiceImpl implements KeepFitOrderService { + + @Autowired + private MealOrderChildService mealOrderChildService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private ShopStoreService shopStoreService; + + @Autowired + private KeepFitOrderConsumeService keepFitOrderConsumeService; + + @Autowired + private MemberService memberService; + + @Autowired + private IMaterialNormsCodeService iMaterialNormsCodeService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "Store")) { + // 门店下的订单 + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrder::getStoreId), commonPageInfo.getHolderId()); + } else if (StrUtil.equals(commonPageInfo.getType(), "All")) { + // 所有订单 + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + shopStoreService.setMationForMap(beans, "storeId", "storeMation"); + memberService.setMationForMap(beans, "objectId", "objectMation"); + return beans; + } + + @Override + public void createPrepose(KeepFitOrder entity) { + if (entity.getType() == ShopMealOrderType.MEMBER.getKey()) { + // 会员线上下单 + if (StrUtil.isEmpty(entity.getOnlineDay())) { + throw new CustomException("线上预约日期不能为空."); + } + if (StrUtil.isEmpty(entity.getOnlineTime())) { + throw new CustomException("线上预约时间段不能为空."); + } + } + if (entity.getUserType() == KeepFitOrderUserType.MEMBER.getKey()) { + if (StrUtil.isEmpty(entity.getObjectId())) { + throw new CustomException("会员信息不能为空."); + } + } + if (entity.getUserType() == KeepFitOrderUserType.MEMBER.getKey()) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrder::getMaterialId), entity.getMaterialId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrder::getNormsId), entity.getNormsId()); + // 商品信息 + Map material = iMaterialService.queryDataMationById(entity.getMaterialId()); + if (CollectionUtil.isEmpty(material)) { + throw new CustomException("商品信息不存在"); + } + Integer itemCode = Integer.parseInt(material.get("itemCode").toString()); + if (itemCode == 1) { + // 一物一码 + if (StrUtil.isEmpty(entity.getCodeNum())) { + throw new CustomException("请输入条形码"); + } + } + if (StrUtil.isNotEmpty(entity.getCodeNum())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrder::getCodeNum), entity.getCodeNum()); + } + List stateList = Arrays.asList(KeepFitOrderState.NO_PAYING.getKey(), KeepFitOrderState.PAY.getKey()); + queryWrapper.in(MybatisPlusUtil.toColumns(KeepFitOrder::getState), stateList); + KeepFitOrder keepFitOrder = getOne(queryWrapper, false); + if (ObjectUtil.isNotEmpty(keepFitOrder)) { + throw new CustomException("该商品正在保养中/未完成核销,请勿重复下单"); + } + } + checkNormsCodeAndOutbound(entity, true); + entity.setState(KeepFitOrderState.NO_PAYING.getKey()); + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + entity.setOddNumber(oddNumber); + // 计算应付金额 + String payablePrice = keepFitOrderConsumeService.calculationTotalPrice(entity.getConsumeMationList()); + payablePrice = CalculationUtil.add(payablePrice, entity.getServicePrice(), CommonNumConstants.NUM_TWO); + entity.setPayablePrice(payablePrice); + } + + /** + * 校验商品规格条形码与单据明细的参数是否匹配 + * + * @param entity + * @param onlyCheck 是否只进行校验,true:是;false:否 + */ + private List checkNormsCodeAndOutbound(KeepFitOrder entity, Boolean onlyCheck) { + if (CollectionUtil.isEmpty(entity.getConsumeMationList())) { + return CollectionUtil.newArrayList(); + } + List materialIdList = entity.getConsumeMationList().stream().map(KeepFitOrderConsume::getMaterialId).distinct().collect(Collectors.toList()); + List normsIdList = entity.getConsumeMationList().stream().map(KeepFitOrderConsume::getNormsId).distinct().collect(Collectors.toList()); + Map> materialMap = iMaterialService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(materialIdList)); + Map> normsMap = iMaterialNormsService.queryDataMationForMapByIds(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIdList)); + // 所有需要进行出库的条形码编码 + List allNormsCodeList = new ArrayList<>(); + int allCodeNum = checkErpOrderItemDetail(entity, materialMap, normsMap, allNormsCodeList); + if (CollectionUtil.isNotEmpty(allNormsCodeList)) { + allNormsCodeList = allNormsCodeList.stream().distinct().collect(Collectors.toList()); + if (allCodeNum != allNormsCodeList.size()) { + throw new CustomException("商品明细中存在相同的条形码编号,请确认"); + } + // 从数据库查询入库状态的条形码信息 + List> materialNormsCodeList = iMaterialNormsCodeService.queryMaterialNormsCode(entity.getStoreId(), allNormsCodeList, + CommonNumConstants.NUM_ONE); + List inSqlNormsCodeList = materialNormsCodeList.stream().map(bean -> bean.get("codeNum").toString()).collect(Collectors.toList()); + // 获取所有前端传递过来的条形码信息,求差集(在入参中有,但是在数据库中不包含的条形码信息) + List diffList = allNormsCodeList.stream() + .filter(num -> !inSqlNormsCodeList.contains(num)).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(diffList)) { + throw new CustomException( + String.format(Locale.ROOT, "编码【%s】不存在/未入库/已经出库,请确认", Joiner.on(CommonCharConstants.COMMA_MARK).join(diffList))); + } + // 判断条形码是否就在出库仓库里面 + Map> materialNormsCodeMap = materialNormsCodeList.stream() + .collect(Collectors.toMap(bean -> bean.get("codeNum").toString(), bean -> bean)); + for (KeepFitOrderConsume keepFitOrderConsume : entity.getConsumeMationList()) { + Map material = materialMap.get(keepFitOrderConsume.getMaterialId()); + Integer itemCode = Integer.parseInt(material.get("itemCode").toString()); + if (itemCode == 1) { + // 一物一码 + keepFitOrderConsume.getNormsCodeList().forEach(normsCode -> { + Map materialNormsCode = materialNormsCodeMap.get(normsCode); + if (!StrUtil.equals(materialNormsCode.get("storeId").toString(), entity.getStoreId())) { + throw new CustomException( + String.format(Locale.ROOT, "条形码【%s】不在指定门店,请确认", normsCode)); + } + if (!StrUtil.equals(materialNormsCode.get("normsId").toString(), keepFitOrderConsume.getNormsId())) { + throw new CustomException(String.format(Locale.ROOT, "条形码【%s】与商品规格不匹配,请确认", normsCode)); + } + }); + } + } + if (!onlyCheck) { + // 批量修改条形码信息 + List ids = materialNormsCodeList.stream().map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + iMaterialNormsCodeService.editStoreMaterialNormsCodeUseState(ids, CommonNumConstants.NUM_TWO); + } + } + return allNormsCodeList; + } + + private int checkErpOrderItemDetail(KeepFitOrder entity, Map> materialMap, Map> normsMap, List allNormsCodeList) { + int allCodeNum = 0; + for (KeepFitOrderConsume keepFitOrderConsume : entity.getConsumeMationList()) { + Map material = materialMap.get(keepFitOrderConsume.getMaterialId()); + Map norms = normsMap.get(keepFitOrderConsume.getNormsId()); + if (keepFitOrderConsume.getOperNumber() == 0) { + throw new CustomException( + String.format(Locale.ROOT, "耗材【%s】【%s】的数量不能为0,请确认", material.get("name").toString(), norms.get("name").toString())); + } + + Integer itemCode = Integer.parseInt(material.get("itemCode").toString()); + if (itemCode == 1) { + // 一物一码 + // 过滤掉空的,并且去重 + List normsCodeList = Arrays.asList(keepFitOrderConsume.getCodeNum().split("\n")).stream() + .filter(str -> StrUtil.isNotEmpty(str)).distinct().collect(Collectors.toList()); + if (keepFitOrderConsume.getOperNumber() != normsCodeList.size()) { + throw new CustomException( + String.format(Locale.ROOT, "耗材【%s】【%s】的条形码数量与明细数量不一致,请确认", material.get("name").toString(), norms.get("name").toString())); + } + allCodeNum += normsCodeList.size(); + keepFitOrderConsume.setNormsCodeList(normsCodeList); + allNormsCodeList.addAll(normsCodeList); + } + } + return allCodeNum; + } + + @Override + public void createPostpose(KeepFitOrder entity, String userId) { + // 保存耗材信息 + keepFitOrderConsumeService.saveList(entity.getId(), entity.getConsumeMationList()); + } + + @Override + public void deletePostpose(String id) { + keepFitOrderConsumeService.deleteByOrderId(id); + } + + @Override + public KeepFitOrder getDataFromDb(String id) { + KeepFitOrder keepFitOrder = super.getDataFromDb(id); + keepFitOrder.setConsumeMationList(keepFitOrderConsumeService.selectByOrderId(id)); + return keepFitOrder; + } + + @Override + public KeepFitOrder selectById(String id) { + KeepFitOrder keepFitOrder = super.selectById(id); + + Map codeNumMation = new HashMap<>(); + codeNumMation.put("name", keepFitOrder.getCodeNum()); + keepFitOrder.setCodeNumMation(codeNumMation); + + // 产品信息 + iMaterialService.setDataMation(keepFitOrder, KeepFitOrder::getMaterialId); + iMaterialService.setDataMation(keepFitOrder.getConsumeMationList(), KeepFitOrderConsume::getMaterialId); + // 规格信息 + iMaterialNormsService.setDataMation(keepFitOrder, KeepFitOrder::getNormsId); + iMaterialNormsService.setDataMation(keepFitOrder.getConsumeMationList(), KeepFitOrderConsume::getNormsId); + // 其他用户信息 + iAuthUserService.setDataMation(keepFitOrder, KeepFitOrder::getCreateId); + iAuthUserService.setDataMation(keepFitOrder, KeepFitOrder::getComplatePayUserId); + iAuthUserService.setDataMation(keepFitOrder, KeepFitOrder::getVerificationUserId); + // 维修技师信息 + if (StrUtil.isNotEmpty(keepFitOrder.getServiceTechnicianId())) { + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(Arrays.asList(keepFitOrder.getServiceTechnicianId())); + keepFitOrder.setServiceTechnicianMation(staffMap.get(keepFitOrder.getServiceTechnicianId())); + } + // 门店 + shopStoreService.setDataMation(keepFitOrder, KeepFitOrder::getStoreId); + // 套餐订单子表信息 + mealOrderChildService.setDataMation(keepFitOrder, KeepFitOrder::getMealOrderChildId); + // 会员信息 + memberService.setDataMation(keepFitOrder, KeepFitOrder::getObjectId); + keepFitOrder.getConsumeMationList().forEach(item -> { + Map codeNumConsumeMation = new HashMap<>(); + codeNumConsumeMation.put("name", item.getCodeNum()); + item.setCodeNumMation(codeNumConsumeMation); + }); + return keepFitOrder; + } + + /** + * 支付订单完成后的回调 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void keepFitOrderNotify(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String outTradeNo = params.get("outTradeNo").toString(); + // 实际支付的订单金额:单位 分 + String totalFee = params.get("totalFee").toString(); + // 转为元 + totalFee = CalculationUtil.divide(totalFee, "100", CommonNumConstants.NUM_TWO); + KeepFitOrder keepFitOrder = queryKeepFitOrderByOddNumber(outTradeNo); + if (keepFitOrder.getState() == KeepFitOrderState.NO_PAYING.getKey()) { + KeepFitOrder entity = selectById(keepFitOrder.getId()); + checkNormsCodeAndOutbound(entity, false); + + String userId = inputObject.getLogParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, keepFitOrder.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getState), KeepFitOrderState.PAY.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getPayPrice), totalFee); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getPayTime), DateUtil.getTimeAndToString()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getComplatePayUserId), userId); + update(updateWrapper); + refreshCache(keepFitOrder.getId()); + } else { + throw new CustomException("订单状态已改变,不允许支付."); + } + } + + private KeepFitOrder queryKeepFitOrderByOddNumber(String oddNumber) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(KeepFitOrder::getOddNumber), oddNumber); + KeepFitOrder keepFitOrder = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(keepFitOrder)) { + throw new CustomException("订单不存在"); + } + return keepFitOrder; + } + + /** + * 单据核销 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void verificationOrder(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + KeepFitOrder keepFitOrder = selectById(id); + if (keepFitOrder.getState() == KeepFitOrderState.FIT_COMPLATE.getKey()) { + String userId = inputObject.getLogParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, keepFitOrder.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getState), KeepFitOrderState.PAY_VERIFICATION.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getVerificationUserId), userId); + update(updateWrapper); + refreshCache(keepFitOrder.getId()); + } else { + throw new CustomException("订单状态已改变,不允许再次核销."); + } + } + + /** + * 完成保养 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void complateKeepFitOrder(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String serviceTechnicianId = params.get("serviceTechnicianId").toString(); + String nextServiceMileage = params.get("nextServiceMileage").toString(); + String nextServiceTime = params.get("nextServiceTime").toString(); + KeepFitOrder keepFitOrder = selectById(id); + if (keepFitOrder.getState() == KeepFitOrderState.PAY.getKey()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, keepFitOrder.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getState), KeepFitOrderState.FIT_COMPLATE.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getServiceTechnicianId), serviceTechnicianId); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getNextServiceMileage), nextServiceMileage); + updateWrapper.set(MybatisPlusUtil.toColumns(KeepFitOrder::getNextServiceTime), nextServiceTime); + update(updateWrapper); + refreshCache(keepFitOrder.getId()); + } else { + throw new CustomException("订单状态已改变,不允许多次完成."); + } + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderState.java new file mode 100644 index 0000000..f4d8e63 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopMealOrderType + * @Description: 套餐订单来源枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/13 17:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopMealOrderState implements SkyeyeEnumClass { + + NO_PAYING(1, "待支付", true, false), + PAY(2, "已支付", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderType.java new file mode 100644 index 0000000..29b411c --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealOrderType.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopMealOrderType + * @Description: 套餐订单来源枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/13 17:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopMealOrderType implements SkyeyeEnumClass { + + MEMBER(1, "用户下单", true, false), + WORK_USER(2, "工作人员下单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealType.java new file mode 100644 index 0000000..98dceca --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/classenum/ShopMealType.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @ClassName: ShopMealType + * @Description: 套餐分类枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/13 17:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopMealType implements SkyeyeEnumClass { + + MAINTENANCE_PACKAGE(1, "保养套餐", true, false), + WARRANTY_PACKAGE(2, "保修套餐", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + + public static String getShowName(Integer type) { + for (ShopMealType value : ShopMealType.values()) { + if (value.getKey().equals(type)) { + return value.getValue(); + } + } + return StringUtils.EMPTY; + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderChildController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderChildController.java new file mode 100644 index 0000000..6b6ea10 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderChildController.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.service.MealOrderChildService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MealOrderChildController + * @Description: 套餐订单所选套餐控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 9:53 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "套餐订单所选套餐", tags = "套餐订单所选套餐", modelName = "套餐订单管理") +public class MealOrderChildController { + + @Autowired + private MealOrderChildService mealOrderChildService; + + /** + * 根据会员/客户id获取已经购买的套餐信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMealMationByObjectId", value = "根据会员/客户id获取已经购买的套餐信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MealController/queryMealMationByObjectId") + public void queryMealMationByObjectId(InputObject inputObject, OutputObject outputObject) { + mealOrderChildService.queryMealMationByObjectId(inputObject, outputObject); + } + + /** + * 根据商品规格以及条形码获取已经购买的套餐信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMealMationByMaterial", value = "根据商品规格以及条形码获取已经购买的套餐信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "会员/客户id", required = "required"), + @ApiImplicitParam(id = "materialId", name = "materialId", value = "商品id", required = "required"), + @ApiImplicitParam(id = "normsId", name = "normsId", value = "规格id", required = "required"), + @ApiImplicitParam(id = "codeNum", name = "codeNum", value = "规格编号")}) + @RequestMapping("/post/MealController/queryMealMationByMaterial") + public void queryMealMationByMaterial(InputObject inputObject, OutputObject outputObject) { + mealOrderChildService.queryMealMationByMaterial(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderController.java new file mode 100644 index 0000000..c63963d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealOrderController.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.MealOrder; +import com.skyeye.meal.service.MealOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MealOrderController + * @Description: 套餐订单管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 19:56 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "套餐订单管理", tags = "套餐订单管理", modelName = "套餐订单管理") +public class MealOrderController { + + @Autowired + private MealOrderService mealOrderService; + + /** + * 获取套餐订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMealOrderList", value = "获取套餐订单信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MealOrderController/queryMealOrderList") + public void queryMealOrderList(InputObject inputObject, OutputObject outputObject) { + mealOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 添加订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertMealOrder", value = "添加订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = MealOrder.class) + @RequestMapping("/post/MealController/insertMealOrder") + public void insertMealOrder(InputObject inputObject, OutputObject outputObject) { + mealOrderService.createEntity(inputObject, outputObject); + } + + /** + * 支付订单完成后的回调 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "mealOrderNotify", value = "支付订单完成后的回调", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "out_trade_no", name = "outTradeNo", value = "商户订单号", required = "required"), + @ApiImplicitParam(id = "total_fee", name = "totalFee", value = "实际支付的订单金额:单位 分", required = "required")}) + @RequestMapping("/post/MealController/mealOrderNotify") + public void mealOrderNotify(InputObject inputObject, OutputObject outputObject) { + mealOrderService.mealOrderNotify(inputObject, outputObject); + } + + /** + * 套餐订单购买详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMealOrderById", value = "套餐订单购买详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "套餐订单id", required = "required")}) + @RequestMapping("/post/MealController/queryMealOrderById") + public void queryMealOrderById(InputObject inputObject, OutputObject outputObject) { + mealOrderService.selectById(inputObject, outputObject); + } + + /** + * 删除套餐订单(待支付状态可以删除) + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMealOrderById", value = "删除套餐订单(待支付状态可以删除)", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "套餐订单id", required = "required")}) + @RequestMapping("/post/MealController/deleteMealOrderById") + public void deleteMealOrderById(InputObject inputObject, OutputObject outputObject) { + mealOrderService.deleteById(inputObject, outputObject); + } + + /** + * 套餐订单状态修改 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateMealOrderState", value = "套餐订单状态修改", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "套餐订单id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "订单状态 1.待支付 2.已支付 线上订单有以下状态: (0.已提交订单 3.已收货 4.已关闭 5.已退款)", required = "required,num")}) + @RequestMapping("/post/MealController/updateMealOrderState") + public void updateMealOrderState(InputObject inputObject, OutputObject outputObject) { + mealOrderService.updateMealOrderState(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealRefundOrderController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealRefundOrderController.java new file mode 100644 index 0000000..1e931ca --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/MealRefundOrderController.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.service.MealRefundOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MealRefundOrderController + * @Description: 套餐退款订单管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 9:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "套餐退款订单管理", tags = "套餐退款订单管理", modelName = "套餐退款订单管理") +public class MealRefundOrderController { + + @Autowired + private MealRefundOrderService mealRefundOrderService; + + /** + * 查询会员套餐退款订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryRefundMealOrderList", value = "查询会员套餐退款订单", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/MealRefundOrderController/queryRefundMealOrderList") + public void queryRefundMealOrderList(InputObject inputObject, OutputObject outputObject) { + mealRefundOrderService.queryPageList(inputObject, outputObject); + } + + /** + * 会员套餐退款申请操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "refundMealOrder", value = "会员套餐退款申请操作", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "mealOrderChildId", name = "mealOrderChildId", value = "套餐订单子单据id", required = "required"), + @ApiImplicitParam(id = "mealRefundReasonId", name = "mealRefundReasonId", value = "退款原因id", required = "required"), + @ApiImplicitParam(id = "storeId", name = "storeId", value = "退款门店id"), + @ApiImplicitParam(id = "refundPrice", name = "refundPrice", value = "退款金额", required = "required,double")}) + @RequestMapping("/post/MealRefundOrderController/refundMealOrder") + public void refundMealOrder(InputObject inputObject, OutputObject outputObject) { + mealRefundOrderService.refundMealOrder(inputObject, outputObject); + } + + /** + * 套餐退款订单提交审批 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "submitMealRefundOrderToApproval", value = "套餐退款订单提交审批", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "approvalId", name = "approvalId", value = "审批人", required = "required")}) + @RequestMapping("/post/MealRefundOrderController/submitToApproval") + public void submitToApproval(InputObject inputObject, OutputObject outputObject) { + mealRefundOrderService.submitToApproval(inputObject, outputObject); + } + + /** + * 撤销套餐退款订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "revokeMealRefundOrder", value = "撤销套餐退款订单", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "processInstanceId", name = "processInstanceId", value = "流程实例id", required = "required")}) + @RequestMapping("/post/MealRefundOrderController/revoke") + public void revoke(InputObject inputObject, OutputObject outputObject) { + mealRefundOrderService.revoke(inputObject, outputObject); + } + + /** + * 删除套餐退款订单 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMealRefundOrderById", value = "删除套餐退款订单", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MealRefundOrderController/deleteMealRefundOrderById") + public void deleteMealRefundOrderById(InputObject inputObject, OutputObject outputObject) { + mealRefundOrderService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/ShopMealController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/ShopMealController.java new file mode 100644 index 0000000..ef0a1c8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/ShopMealController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.ShopMeal; +import com.skyeye.meal.service.ShopMealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopMealController + * @Description: 套餐管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "套餐管理", tags = "套餐管理", modelName = "套餐管理") +public class ShopMealController { + + @Autowired + private ShopMealService shopMealService; + + /** + * 获取套餐信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "meal001", value = "获取套餐信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/ShopMealController/queryMealList") + public void queryMealList(InputObject inputObject, OutputObject outputObject) { + shopMealService.queryPageList(inputObject, outputObject); + } + + /** + * 添加/编辑套餐 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopMeal", value = "添加/编辑套餐", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = ShopMeal.class) + @RequestMapping("/post/ShopMealController/writeShopMeal") + public void writeShopMeal(InputObject inputObject, OutputObject outputObject) { + shopMealService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据id删除套餐信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShopMealById", value = "根据id删除套餐信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopMealController/deleteShopMealById") + public void deleteShopMealById(InputObject inputObject, OutputObject outputObject) { + shopMealService.deleteById(inputObject, outputObject); + } + + /** + * 查看套餐详情 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopMealById", value = "查看套餐详情", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopMealController/queryShopMealById") + public void queryShopMealById(InputObject inputObject, OutputObject outputObject) { + shopMealService.selectById(inputObject, outputObject); + } + + /** + * 根据门店获取套餐信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopMealByStoreId", value = "根据门店获取套餐信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id")}) + @RequestMapping("/post/ShopMealController/queryShopMealByStoreId") + public void queryShopMealByStoreId(InputObject inputObject, OutputObject outputObject) { + shopMealService.queryShopMealByStoreId(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/StatisticsShopController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/StatisticsShopController.java new file mode 100644 index 0000000..5278ede --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/controller/StatisticsShopController.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.service.StatisticsShopService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: StatisticsShopController + * @Description: 商城统计控制层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 23:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商城统计", tags = "商城统计", modelName = "商城模块") +public class StatisticsShopController { + + @Autowired + private StatisticsShopService statisticsShopService; + + /** + * 统计分析 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStatisticsShop", value = "统计分析", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "areaId", name = "areaId", value = "区域id"), + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id"), + @ApiImplicitParam(id = "natureId", name = "natureId", value = "性质id"), + @ApiImplicitParam(id = "startTime", name = "startTime", value = "开始日期", required = "required"), + @ApiImplicitParam(id = "endTime", name = "endTime", value = "结束日期", required = "required")}) + @RequestMapping("/post/StatisticsShopController/queryStatisticsShop") + public void queryStatisticsShop(InputObject inputObject, OutputObject outputObject) { + statisticsShopService.queryStatisticsShop(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderChildDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderChildDao.java new file mode 100644 index 0000000..ea8972c --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderChildDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.meal.entity.MealOrderChild; + +/** + * @ClassName: MealOrderChildDao + * @Description: 套餐订单所关联套餐数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/7 9:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealOrderChildDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderDao.java new file mode 100644 index 0000000..1d7e5ad --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.meal.entity.MealOrder; + +/** + * @ClassName: MealOrderDao + * @Description: 套餐订单管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 19:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealRefundOrderDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealRefundOrderDao.java new file mode 100644 index 0000000..452dbaa --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/MealRefundOrderDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.meal.entity.MealRefundOrder; + +/** + * @ClassName: MealRefundOrderDao + * @Description: 套餐退款订单管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 9:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealRefundOrderDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealAreaDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealAreaDao.java new file mode 100644 index 0000000..eb7290d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealAreaDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.meal.entity.ShopMealArea; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopMealAreaDao + * @Description: 套餐使用区域管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 16:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealAreaDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealConsumeDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealConsumeDao.java new file mode 100644 index 0000000..b5fc6e6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealConsumeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.meal.entity.ShopMealConsume; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopMealConsumeDao + * @Description: 套餐耗材表数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealConsumeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealDao.java new file mode 100644 index 0000000..214bb9a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/ShopMealDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import com.skyeye.meal.entity.ShopMeal; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: ShopMealDao + * @Description: 套餐管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/StatisticsShopDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/StatisticsShopDao.java new file mode 100644 index 0000000..e93aa1f --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/dao/StatisticsShopDao.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.dao; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StatisticsShopDao + * @Description: 商城统计数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/13 19:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StatisticsShopDao { + + String queryMealOrderMemberByNum(Map params); + + String queryMealOrderNum(Map params); + + String queryKeepFitOrderNum(Map params); + + String queryKeepFitOrderPrice(Map params); + + List> queryMonthMealOrderNum(Map params); + + List> queryStoreMealOrderNum(Map params); + + List> queryStoreKeepFitOrderNum(Map params); + + List> queryNatureMealOrderNum(Map params); + + List> queryMonthKeepFitOrderNum(Map params); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrder.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrder.java new file mode 100644 index 0000000..f59433c --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrder.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.store.entity.ShopStore; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MealOrder + * @Description: 套餐订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 20:01 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "shop:mealOrder", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_meal_order") +@ApiModel("套餐订单实体类") +public class MealOrder extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property(value = "单据编号", fuzzyLike = true) + private String oddNumber; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField("payable_price") + @Property(value = "应付金额") + private String payablePrice; + + @TableField("pay_price") + @Property(value = "实付金额") + private String payPrice; + + @TableField("pay_time") + @Property(value = "实付日期") + private String payTime; + + @TableField("state") + @Property(value = "单据状态,参考#ShopMealOrderState") + private Integer state; + + @TableField("type") + @ApiModelProperty(value = "订单来源,参考#ShopMealOrderType", required = "required,num") + private Integer type; + + @TableField("store_id") + @ApiModelProperty(value = "门店ID") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private ShopStore storeMation; + + @TableField("remark") + @ApiModelProperty(value = "备注") + private String remark; + + @TableField("whether_give") + @ApiModelProperty(value = "是否赠送,参考#WhetherEnum", required = "required,num") + private Integer whetherGive; + + @TableField("nature_id") + @ApiModelProperty(value = "套餐订单性质id,参考数据字典") + private String natureId; + + @TableField(exist = false) + @Property(value = "套餐订单性质信息") + private Map natureMation; + + @TableField(exist = false) + @ApiModelProperty(value = "所购买的套餐信息", required = "required") + private List mealList; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrderChild.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrderChild.java new file mode 100644 index 0000000..8de294a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealOrderChild.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: MealOrderChild + * @Description: 套餐订单所选套餐实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 20:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_meal_order_child") +@ApiModel("套餐订单所选套餐实体类") +public class MealOrderChild extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("order_id") + @Property(value = "订单id") + private String orderId; + + @TableField("meal_id") + @ApiModelProperty(value = "套餐ID", required = "required") + private String mealId; + + @TableField(exist = false) + @Property(value = "套餐信息") + private ShopMeal mealMation; + + @TableField("meal_price") + @Property(value = "套餐金额") + private String mealPrice; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @Property(value = "所属第三方业务数据id") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @Property(value = "所属第三方业务数据的key") + private String objectKey; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Map materialMation; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "code_num", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "规格物品编码", fuzzyLike = true) + private String codeNum; + + @TableField(exist = false) + @Property(value = "规格物品编码信息") + private Map codeNumMation; + + @TableField(value = "start_time") + @ApiModelProperty(value = "套餐开始时间") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "套餐结束时间") + private String endTime; + + @TableField(value = "state") + @Property(value = "是否可用,参考#WhetherEnum") + private Integer state; + + @TableField(exist = false) + @Property(value = "是否下达退款单,参考#WhetherEnum") + private Boolean isRefund; + + @TableField(exist = false) + @Property(value = "退款单信息") + private MealRefundOrder mealRefundOrder; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealRefundOrder.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealRefundOrder.java new file mode 100644 index 0000000..90cfa81 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/MealRefundOrder.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.SkyeyeFlowable; +import com.skyeye.store.entity.ShopStore; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: MealRefundOrder + * @Description: 套餐退款订单实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 11:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "shop:mealRefundOrder", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_meal_refund_order") +@ApiModel("套餐退款订单实体类") +public class MealRefundOrder extends SkyeyeFlowable { + + @TableField("meal_order_child_id") + @ApiModelProperty(value = "套餐订单子订单id", required = "required") + private String mealOrderChildId; + + @TableField("refund_reason_id") + @ApiModelProperty(value = "退款原因id,参考数据字典", required = "required") + private String refundReasonId; + + @TableField(exist = false) + @Property(value = "退款原因信息") + private Map refundReasonMation; + + @TableField("meal_single_price") + @Property(value = "套餐耗费金额") + private String mealSinglePrice; + + @TableField("refund_price") + @Property(value = "退款金额") + private String refundPrice; + + @TableField("store_id") + @ApiModelProperty(value = "门店ID") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private ShopStore storeMation; + + @TableField(value = "object_id", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据id", required = "required") + private String objectId; + + @TableField(value = "object_key", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "所属第三方业务数据的key", required = "required") + private String objectKey; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMeal.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMeal.java new file mode 100644 index 0000000..cb1ca8a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMeal.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: ShopMeal + * @Description: 套餐管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:14 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "shop:meal", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_meal") +@ApiModel("套餐实体类") +public class ShopMeal extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "title") + @ApiModelProperty(value = "套餐名称", required = "required", fuzzyLike = true) + private String title; + + @TableField(exist = false) + @Property(value = "套餐名称") + private String name; + + @TableField(value = "logo") + @ApiModelProperty(value = "套餐logo", required = "required") + private String logo; + + @TableField(value = "meal_num") + @ApiModelProperty(value = "套餐可使用次数/年限", required = "required,num") + private Integer mealNum; + + @TableField(value = "meal_explain") + @ApiModelProperty(value = "套餐说明", required = "required", fuzzyLike = true) + private String mealExplain; + + @TableField(value = "type") + @ApiModelProperty(value = "套餐分类,参考#ShopMealType", required = "required,num") + private Integer type; + + @TableField(value = "enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(value = "price") + @ApiModelProperty(value = "指导价", required = "required,double") + private String price; + + @TableField(value = "show_price") + @ApiModelProperty(value = "展示价", required = "required,double") + private String showPrice; + + @TableField(value = "low_price") + @ApiModelProperty(value = "底价", required = "required,double") + private String lowPrice; + + @TableField(exist = false) + @ApiModelProperty(value = "套餐耗材列表", required = "json") + private List mealConsumeList; + + @TableField(exist = false) + @ApiModelProperty(value = "套餐所属区域", required = "required,json") + private List mealAreaList; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealArea.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealArea.java new file mode 100644 index 0000000..407338b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealArea.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.store.entity.ShopArea; +import lombok.Data; + +/** + * @ClassName: MealAreaMation + * @Description: 套餐使用区域实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:38 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_meal_area") +@ApiModel("套餐使用区域实体类") +public class ShopMealArea extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "meal_id") + @Property(value = "套餐ID") + private String mealId; + + @TableField(value = "area_id") + @ApiModelProperty(value = "区域ID", required = "required") + private String areaId; + + @TableField(exist = false) + @Property(value = "区域信息") + private ShopArea areaMation; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealConsume.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealConsume.java new file mode 100644 index 0000000..d9f5506 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/entity/ShopMealConsume.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: MealConsumeMation + * @Description: 套餐耗材实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_meal_consume") +@ApiModel("套餐耗材实体类") +public class ShopMealConsume extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "meal_id") + @Property(value = "套餐ID") + private String mealId; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品ID") + private String materialId; + + @TableField(value = "consume_explain") + @ApiModelProperty(value = "耗材说明", required = "required") + private String consumeExplain; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderChildService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderChildService.java new file mode 100644 index 0000000..0aad701 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderChildService.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.MealOrderChild; + +import java.util.List; + +/** + * @ClassName: MealOrderChildService + * @Description: 套餐订单所选套餐服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 9:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealOrderChildService extends SkyeyeBusinessService { + + String calculationTotalPrice(String objectId, String objectKey, List mealOrderChildList); + + void deleteByOrderId(String orderId); + + List selectByOrderId(String orderId); + + void saveList(String orderId, List mealOrderChildList); + + void queryMealMationByObjectId(InputObject inputObject, OutputObject outputObject); + + void updateStateISUseByOrderId(String orderId); + + void updateStateISNotUseById(String id); + + void queryMealMationByMaterial(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderService.java new file mode 100644 index 0000000..3bb6a41 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealOrderService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.MealOrder; + +/** + * @ClassName: MealOrderService + * @Description: 套餐订单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 19:57 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealOrderService extends SkyeyeBusinessService { + + void mealOrderNotify(InputObject inputObject, OutputObject outputObject); + + void updateMealOrderState(InputObject inputObject, OutputObject outputObject); + + void editOrderStateById(String id, Integer state); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealRefundOrderService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealRefundOrderService.java new file mode 100644 index 0000000..c2282fe --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/MealRefundOrderService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeFlowableService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.MealOrderChild; +import com.skyeye.meal.entity.MealRefundOrder; + +import java.util.List; + +/** + * @ClassName: MealRefundOrderService + * @Description: 套餐退款订单管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 9:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MealRefundOrderService extends SkyeyeFlowableService { + + void refundMealOrder(InputObject inputObject, OutputObject outputObject); + + void setWhetherMealRefundOrder(List mealOrderChildList); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealAreaService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealAreaService.java new file mode 100644 index 0000000..1c40c9e --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealAreaService.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.meal.entity.ShopMealArea; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMealAreaService + * @Description: 套餐使用区域服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/13 22:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealAreaService extends SkyeyeBusinessService { + + void deleteMealAreaByMealId(String mealId); + + void saveShopMealArea(List shopMealAreaList, String mealId); + + List queryMealAreaByMealId(String mealId); + + Map> queryMealAreaByMealId(String... mealId); + + List queryMealAreaByAreaId(String areaId); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealConsumeService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealConsumeService.java new file mode 100644 index 0000000..903c855 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealConsumeService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.meal.entity.ShopMealConsume; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopMealConsumeService + * @Description: 套餐耗材管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/15 8:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealConsumeService extends SkyeyeBusinessService { + + void deleteMealConsumeByMealId(String mealId); + + void saveShopMealConsume(List shopMealConsumeList, String mealId); + + List queryMealConsumeByMealId(String mealId); + + Map> queryMealConsumeByMealId(String... mealId); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealService.java new file mode 100644 index 0000000..6934bc8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/ShopMealService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.meal.entity.ShopMeal; + +/** + * @ClassName: ShopMealService + * @Description: 套餐管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopMealService extends SkyeyeBusinessService { + + void queryShopMealByStoreId(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/StatisticsShopService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/StatisticsShopService.java new file mode 100644 index 0000000..a8d3e59 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/StatisticsShopService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: StatisticsShopService + * @Description: 商城统计服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 23:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StatisticsShopService { + + void queryStatisticsShop(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderChildServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderChildServiceImpl.java new file mode 100644 index 0000000..5876f00 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderChildServiceImpl.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.meal.dao.MealOrderChildDao; +import com.skyeye.meal.entity.MealOrderChild; +import com.skyeye.meal.entity.ShopMeal; +import com.skyeye.meal.service.MealOrderChildService; +import com.skyeye.meal.service.MealOrderService; +import com.skyeye.meal.service.MealRefundOrderService; +import com.skyeye.meal.service.ShopMealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MealOrderChildServiceImpl + * @Description: 套餐订单所选套餐服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/7/25 9:52 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐订单所选套餐", groupName = "套餐订单管理") +public class MealOrderChildServiceImpl extends SkyeyeBusinessServiceImpl implements MealOrderChildService { + + @Autowired + private ShopMealService shopMealService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private MealOrderService mealOrderService; + + @Autowired + private MealRefundOrderService mealRefundOrderService; + + @Override + public String calculationTotalPrice(String objectId, String objectKey, List mealOrderChildList) { + String payablePrice = CommonNumConstants.NUM_ZERO.toString(); + List mealIds = mealOrderChildList.stream().map(MealOrderChild::getMealId).distinct().collect(Collectors.toList()); + Map shopMealMap = shopMealService.selectMapByIds(mealIds); + for (MealOrderChild bean : mealOrderChildList) { + bean.setObjectId(objectId); + bean.setObjectKey(objectKey); + ShopMeal shopMeal = shopMealMap.get(bean.getMealId()); + if (ObjectUtil.isEmpty(shopMeal) || StrUtil.isEmpty(shopMeal.getId())) { + throw new CustomException("套餐不存在,请刷新后重试."); + } + bean.setMealPrice(shopMeal.getPrice()); + payablePrice = CalculationUtil.add(payablePrice, shopMeal.getPrice(), CommonNumConstants.NUM_TWO); + } + return payablePrice; + } + + @Override + public void deleteByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getOrderId), orderId); + remove(queryWrapper); + } + + @Override + public List selectByOrderId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getOrderId), orderId); + return list(queryWrapper); + } + + @Override + public void saveList(String orderId, List mealOrderChildList) { + deleteByOrderId(orderId); + if (CollectionUtil.isNotEmpty(mealOrderChildList)) { + for (MealOrderChild mealOrderChild : mealOrderChildList) { + mealOrderChild.setOrderId(orderId); + mealOrderChild.setState(WhetherEnum.DISABLE_USING.getKey()); + } + createEntity(mealOrderChildList, StrUtil.EMPTY); + } + } + + @Override + public void queryMealMationByObjectId(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getObjectId), commonPageInfo.getObjectId()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(MealOrderChild::getStartTime)); + List mealOrderChildList = list(queryWrapper); + shopMealService.setDataMation(mealOrderChildList, MealOrderChild::getMealId); + // 产品信息 + iMaterialService.setDataMation(mealOrderChildList, MealOrderChild::getMaterialId); + // 规格信息 + iMaterialNormsService.setDataMation(mealOrderChildList, MealOrderChild::getNormsId); + // 设置是否下达退款单 + mealRefundOrderService.setWhetherMealRefundOrder(mealOrderChildList); + outputObject.setBeans(mealOrderChildList); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void updateStateISUseByOrderId(String orderId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getOrderId), orderId); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrderChild::getState), WhetherEnum.ENABLE_USING.getKey()); + update(updateWrapper); + } + + @Override + public void updateStateISNotUseById(String id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrderChild::getState), WhetherEnum.DISABLE_USING.getKey()); + update(updateWrapper); + // 刷新缓存 + MealOrderChild mealOrderChild = selectById(id); + mealOrderService.refreshCache(mealOrderChild.getOrderId()); + } + + @Override + public void queryMealMationByMaterial(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String objectId = params.get("objectId").toString(); + String materialId = params.get("materialId").toString(); + String normsId = params.get("normsId").toString(); + String codeNum = params.get("codeNum").toString(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getObjectId), objectId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getMaterialId), materialId); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getNormsId), normsId); + if (StrUtil.isNotEmpty(codeNum)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getCodeNum), codeNum); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrderChild::getState), WhetherEnum.ENABLE_USING.getKey()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(MealOrderChild::getStartTime)); + List mealOrderChildList = list(queryWrapper); + shopMealService.setDataMation(mealOrderChildList, MealOrderChild::getMealId); + // 产品信息 + iMaterialService.setDataMation(mealOrderChildList, MealOrderChild::getMaterialId); + // 规格信息 + iMaterialNormsService.setDataMation(mealOrderChildList, MealOrderChild::getNormsId); + outputObject.setBeans(mealOrderChildList); + outputObject.settotal(mealOrderChildList.size()); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderServiceImpl.java new file mode 100644 index 0000000..36ab8c9 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealOrderServiceImpl.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.meal.classenum.ShopMealOrderState; +import com.skyeye.meal.dao.MealOrderDao; +import com.skyeye.meal.entity.MealOrder; +import com.skyeye.meal.entity.MealOrderChild; +import com.skyeye.meal.service.MealOrderChildService; +import com.skyeye.meal.service.MealOrderService; +import com.skyeye.meal.service.ShopMealService; +import com.skyeye.service.MemberService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: MealOrderServiceImpl + * @Description: 套餐订单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/6 19:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐订单管理", groupName = "套餐订单管理") +public class MealOrderServiceImpl extends SkyeyeBusinessServiceImpl implements MealOrderService { + + @Autowired + private ShopMealService shopMealService; + + @Autowired + private MealOrderChildService mealOrderChildService; + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private ShopStoreService shopStoreService; + + @Autowired + private MemberService memberService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "Store")) { + // 门店下的订单 + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrder::getStoreId), commonPageInfo.getHolderId()); + } else if (StrUtil.equals(commonPageInfo.getType(), "All")) { + // 所有订单 + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + shopStoreService.setMationForMap(beans, "storeId", "storeMation"); + iSysDictDataService.setNameForMap(beans, "natureId", "natureName"); + memberService.setMationForMap(beans, "objectId", "objectMation"); + return beans; + } + + @Override + public void createPrepose(MealOrder entity) { + entity.setState(ShopMealOrderState.NO_PAYING.getKey()); + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + entity.setOddNumber(oddNumber); + entity.setPayPrice(null); + entity.setPayTime(null); + // 计算应付金额 + String payablePrice = mealOrderChildService.calculationTotalPrice(entity.getObjectId(), entity.getObjectKey(), entity.getMealList()); + entity.setPayablePrice(payablePrice); + } + + @Override + public void createPostpose(MealOrder entity, String userId) { + // 保存订单与套餐的关系表 + mealOrderChildService.saveList(entity.getId(), entity.getMealList()); + } + + @Override + public void deletePostpose(String id) { + mealOrderChildService.deleteByOrderId(id); + } + + @Override + public MealOrder getDataFromDb(String id) { + MealOrder mealOrder = super.getDataFromDb(id); + mealOrder.setMealList(mealOrderChildService.selectByOrderId(id)); + return mealOrder; + } + + @Override + public MealOrder selectById(String id) { + MealOrder mealOrder = super.selectById(id); + iSysDictDataService.setDataMation(mealOrder, MealOrder::getNatureId); + iAuthUserService.setDataMation(mealOrder, MealOrder::getCreateId); + mealOrder.getMealList().forEach(mealOrderChild -> { + Map codeNumMation = new HashMap<>(); + codeNumMation.put("name", mealOrderChild.getCodeNum()); + mealOrderChild.setCodeNumMation(codeNumMation); + }); + + shopMealService.setDataMation(mealOrder.getMealList(), MealOrderChild::getMealId); + // 产品信息 + iMaterialService.setDataMation(mealOrder.getMealList(), MealOrderChild::getMaterialId); + // 规格信息 + iMaterialNormsService.setDataMation(mealOrder.getMealList(), MealOrderChild::getNormsId); + // 会员信息 + memberService.setDataMation(mealOrder, MealOrder::getObjectId); + // 门店信息 + shopStoreService.setDataMation(mealOrder, MealOrder::getStoreId); + return mealOrder; + } + + /** + * 支付订单完成后的回调 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void mealOrderNotify(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String outTradeNo = params.get("outTradeNo").toString(); + // 实际支付的订单金额:单位 分 + String totalFee = params.get("totalFee").toString(); + // 转为元 + totalFee = CalculationUtil.divide(totalFee, "100", CommonNumConstants.NUM_TWO); + MealOrder mealOrder = queryMealOrderByOddNumber(outTradeNo); + if (mealOrder.getState() == ShopMealOrderState.NO_PAYING.getKey()) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, mealOrder.getId()); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrder::getState), ShopMealOrderState.PAY.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrder::getPayPrice), totalFee); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrder::getPayTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + // 更新套餐子订单状态为可以使用 + mealOrderChildService.updateStateISUseByOrderId(mealOrder.getId()); + refreshCache(mealOrder.getId()); + } else { + throw new CustomException("订单状态已改变,不允许支付."); + } + } + + private MealOrder queryMealOrderByOddNumber(String oddNumber) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealOrder::getOddNumber), oddNumber); + MealOrder mealOrder = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(mealOrder)) { + throw new CustomException("订单不存在"); + } + return mealOrder; + } + + @Override + public void deletePreExecution(MealOrder entity) { + if (entity.getState() != ShopMealOrderState.NO_PAYING.getKey()) { + throw new CustomException("该订单状态不允许删除."); + } + } + + /** + * 套餐订单状态修改 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void updateMealOrderState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + Integer state = Integer.parseInt(params.get("state").toString()); + editOrderStateById(id, state); + } + + @Override + public void editOrderStateById(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(MealOrder::getState), state); + update(updateWrapper); + refreshCache(id); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealRefundOrderServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealRefundOrderServiceImpl.java new file mode 100644 index 0000000..18cae9a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/MealRefundOrderServiceImpl.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeFlowableServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.FlowableStateEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.flowable.classenum.FormSubType; +import com.skyeye.exception.CustomException; +import com.skyeye.meal.dao.MealRefundOrderDao; +import com.skyeye.meal.entity.MealOrderChild; +import com.skyeye.meal.entity.MealRefundOrder; +import com.skyeye.meal.service.MealOrderChildService; +import com.skyeye.meal.service.MealRefundOrderService; +import com.skyeye.service.MemberService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: MealRefundOrderServiceImpl + * @Description: 套餐退款订单管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 9:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐退款订单管理", groupName = "套餐退款订单管理", flowable = true) +public class MealRefundOrderServiceImpl extends SkyeyeFlowableServiceImpl implements MealRefundOrderService { + + @Autowired + private MealOrderChildService mealOrderChildService; + + @Autowired + private ShopStoreService shopStoreService; + + @Autowired + private MemberService memberService; + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.equals(commonPageInfo.getType(), "Store")) { + // 门店下的退款订单 + queryWrapper.eq(MybatisPlusUtil.toColumns(MealRefundOrder::getStoreId), commonPageInfo.getHolderId()); + } else if (StrUtil.equals(commonPageInfo.getType(), "My")) { + // 我的退款订单 + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealRefundOrder::getObjectId), userId); + } else if (StrUtil.equals(commonPageInfo.getType(), "All")) { + // 所有退款订单 + } + return queryWrapper; + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iSysDictDataService.setNameForMap(beans, "refundReasonId", "refundReasonName"); + shopStoreService.setMationForMap(beans, "storeId", "storeMation"); + memberService.setMationForMap(beans, "objectId", "objectMation"); + return beans; + } + + @Override + public MealRefundOrder selectById(String id) { + MealRefundOrder mealRefundOrder = super.selectById(id); + iSysDictDataService.setDataMation(mealRefundOrder, MealRefundOrder::getRefundReasonId); + // 会员信息 + memberService.setDataMation(mealRefundOrder, MealRefundOrder::getObjectId); + // 门店信息 + shopStoreService.setDataMation(mealRefundOrder, MealRefundOrder::getStoreId); + return mealRefundOrder; + } + + /** + * 会员套餐退款申请操作 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void refundMealOrder(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String mealOrderChildId = params.get("mealOrderChildId").toString(); + String mealRefundReasonId = params.get("mealRefundReasonId").toString(); + String refundPrice = params.get("refundPrice").toString(); + String storeId = params.get("storeId").toString(); + + List stateList = Arrays.asList(FlowableStateEnum.IN_EXAMINE.getKey(), FlowableStateEnum.PASS.getKey()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MealRefundOrder::getState), stateList); + queryWrapper.eq(MybatisPlusUtil.toColumns(MealRefundOrder::getMealOrderChildId), mealOrderChildId); + List list = list(queryWrapper); + if (CollectionUtil.isNotEmpty(list)) { + throw new CustomException("该套餐存在待审核或已审核的退款申请,请勿重复申请."); + } + // 获取套餐订单子单据信息 + MealOrderChild mealOrderChild = mealOrderChildService.selectById(mealOrderChildId); + if (ObjectUtil.isEmpty(mealOrderChild) || StrUtil.isEmpty(mealOrderChild.getId())) { + outputObject.setreturnMessage("套餐单据信息为空,请确认."); + return; + } + MealRefundOrder mealRefundOrder = new MealRefundOrder(); + mealRefundOrder.setMealOrderChildId(mealOrderChildId); + mealRefundOrder.setRefundReasonId(mealRefundReasonId); + mealRefundOrder.setRefundPrice(refundPrice); + mealRefundOrder.setMealSinglePrice(CalculationUtil.subtract(mealOrderChild.getMealPrice(), refundPrice, CommonNumConstants.NUM_TWO)); + mealRefundOrder.setStoreId(storeId); + mealRefundOrder.setFormSubType(FormSubType.DRAFT.getKey()); + mealRefundOrder.setObjectId(mealOrderChild.getObjectId()); + mealRefundOrder.setObjectKey(mealOrderChild.getObjectKey()); + String userId = inputObject.getLogParams().get("id").toString(); + createEntity(mealRefundOrder, userId); + } + + @Override + public void setWhetherMealRefundOrder(List mealOrderChildList) { + if (CollectionUtil.isEmpty(mealOrderChildList)) { + return; + } + List mealOrderChildIds = mealOrderChildList.stream().map(MealOrderChild::getId).collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(MealRefundOrder::getMealOrderChildId), mealOrderChildIds); + List mealRefundOrderList = list(queryWrapper); + if (CollectionUtil.isEmpty(mealRefundOrderList)) { + return; + } + Map mealRefundOrderMap = mealRefundOrderList.stream().collect(Collectors.toMap(MealRefundOrder::getMealOrderChildId, e -> e)); + for (MealOrderChild mealOrderChild : mealOrderChildList) { + if (ObjectUtil.isNotEmpty(mealRefundOrderMap.get(mealOrderChild.getId()))) { + mealOrderChild.setIsRefund(true); + mealOrderChild.setMealRefundOrder(mealRefundOrderMap.get(mealOrderChild.getId())); + } + } + } + + @Override + public void approvalEndIsSuccess(MealRefundOrder entity) { + // 设置套餐订单子单据状态为不可使用 + mealOrderChildService.updateStateISNotUseById(entity.getMealOrderChildId()); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealAreaServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealAreaServiceImpl.java new file mode 100644 index 0000000..887ab23 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealAreaServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.meal.dao.ShopMealAreaDao; +import com.skyeye.meal.entity.ShopMealArea; +import com.skyeye.meal.service.ShopMealAreaService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMealAreaServiceImpl + * @Description: 套餐使用区域服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/13 22:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐使用区域管理", groupName = "套餐使用区域管理", manageShow = false) +public class ShopMealAreaServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMealAreaService { + + @Override + public void deleteMealAreaByMealId(String mealId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMealArea::getMealId), mealId); + remove(queryWrapper); + } + + @Override + public void saveShopMealArea(List shopMealAreaList, String mealId) { + deleteMealAreaByMealId(mealId); + if (CollectionUtil.isNotEmpty(shopMealAreaList)) { + shopMealAreaList.forEach(bean -> { + bean.setMealId(mealId); + }); + createEntity(shopMealAreaList, StrUtil.EMPTY); + } + } + + @Override + public List queryMealAreaByMealId(String mealId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMealArea::getMealId), mealId); + return list(queryWrapper); + } + + @Override + public Map> queryMealAreaByMealId(String... mealId) { + List mealIdList = Arrays.asList(mealId); + if (CollectionUtil.isEmpty(mealIdList)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMealArea::getMealId), mealIdList); + List list = list(queryWrapper); + Map> listMap = list.stream() + .collect(Collectors.groupingBy(ShopMealArea::getMealId)); + return listMap; + } + + @Override + public List queryMealAreaByAreaId(String areaId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMealArea::getAreaId), areaId); + return list(queryWrapper); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealConsumeServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealConsumeServiceImpl.java new file mode 100644 index 0000000..c15a148 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealConsumeServiceImpl.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.meal.dao.ShopMealConsumeDao; +import com.skyeye.meal.entity.ShopMealConsume; +import com.skyeye.meal.service.ShopMealConsumeService; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMealConsumeServiceImpl + * @Description: 套餐耗材管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/15 8:32 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐耗材管理", groupName = "套餐耗材管理", manageShow = false) +public class ShopMealConsumeServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMealConsumeService { + + @Override + public void deleteMealConsumeByMealId(String mealId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMealConsume::getMealId), mealId); + remove(queryWrapper); + } + + @Override + public void saveShopMealConsume(List shopMealConsumeList, String mealId) { + deleteMealConsumeByMealId(mealId); + if (CollectionUtil.isNotEmpty(shopMealConsumeList)) { + shopMealConsumeList.forEach(bean -> { + bean.setMealId(mealId); + }); + createEntity(shopMealConsumeList, StrUtil.EMPTY); + } + } + + @Override + public List queryMealConsumeByMealId(String mealId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMealConsume::getMealId), mealId); + return list(queryWrapper); + } + + @Override + public Map> queryMealConsumeByMealId(String... mealId) { + List mealIdList = Arrays.asList(mealId); + if (CollectionUtil.isEmpty(mealIdList)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMealConsume::getMealId), mealIdList); + List shopMealConsumeList = list(queryWrapper); + Map> listMap = shopMealConsumeList.stream() + .collect(Collectors.groupingBy(ShopMealConsume::getMealId)); + return listMap; + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealServiceImpl.java new file mode 100644 index 0000000..5af34c6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/ShopMealServiceImpl.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.meal.dao.ShopMealDao; +import com.skyeye.meal.entity.ShopMeal; +import com.skyeye.meal.entity.ShopMealArea; +import com.skyeye.meal.entity.ShopMealConsume; +import com.skyeye.meal.service.ShopMealAreaService; +import com.skyeye.meal.service.ShopMealConsumeService; +import com.skyeye.meal.service.ShopMealService; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.service.ShopAreaService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopMealServiceImpl + * @Description: 套餐管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/5 15:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "套餐管理", groupName = "套餐管理") +public class ShopMealServiceImpl extends SkyeyeBusinessServiceImpl implements ShopMealService { + + @Autowired + private ShopStoreService shopStoreService; + + @Autowired + private ShopMealAreaService shopMealAreaService; + + @Autowired + private ShopAreaService shopAreaService; + + @Autowired + private ShopMealConsumeService shopMealConsumeService; + + @Override + public void setCommonPageInfoOtherInfo(CommonPageInfo commonPageInfo) { + super.setCommonPageInfoOtherInfo(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getObjectId())) { + // 如果门店id不为空,则获取门店所在区域的套餐 + ShopStore shopStore = shopStoreService.selectById(commonPageInfo.getObjectId()); + List shopMealAreas = shopMealAreaService.queryMealAreaByAreaId(shopStore.getShopAreaId()); + List mealIds = shopMealAreas.stream().map(ShopMealArea::getMealId).collect(Collectors.toList()); + commonPageInfo.setObjectIdList(mealIds); + } + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (!StrUtil.equals(commonPageInfo.getType(), "All")) { + if (CollectionUtil.isNotEmpty(commonPageInfo.getObjectIdList())) { + queryWrapper.in(MybatisPlusUtil.toColumns(ShopMeal::getId), commonPageInfo.getObjectIdList()); + } + } + return queryWrapper; + } + + @Override + public void writePostpose(ShopMeal entity, String userId) { + super.writePostpose(entity, userId); + // 保存套餐耗材信息 + shopMealConsumeService.saveShopMealConsume(entity.getMealConsumeList(), entity.getId()); + // 保存套餐使用区域 + shopMealAreaService.saveShopMealArea(entity.getMealAreaList(), entity.getId()); + } + + @Override + public void deletePostpose(String id) { + // 删除套餐耗材信息 + shopMealConsumeService.deleteMealConsumeByMealId(id); + // 删除套餐使用区域 + shopMealAreaService.deleteMealAreaByMealId(id); + } + + @Override + public ShopMeal getDataFromDb(String id) { + ShopMeal shopMeal = super.getDataFromDb(id); + // 套餐耗材信息 + shopMeal.setMealConsumeList(shopMealConsumeService.queryMealConsumeByMealId(shopMeal.getId())); + // 套餐使用区域信息 + shopMeal.setMealAreaList(shopMealAreaService.queryMealAreaByMealId(shopMeal.getId())); + return shopMeal; + } + + @Override + public List getDataFromDb(List idList) { + List shopMealList = super.getDataFromDb(idList); + // 套餐耗材信息 + Map> mealConsumeMap = shopMealConsumeService.queryMealConsumeByMealId(idList.toArray(new String[]{})); + // 套餐使用区域信息 + Map> mealAreaMap = shopMealAreaService.queryMealAreaByMealId(idList.toArray(new String[]{})); + for (ShopMeal shopMeal : shopMealList) { + shopMeal.setMealConsumeList(mealConsumeMap.get(shopMeal.getId())); + shopMeal.setMealAreaList(mealAreaMap.get(shopMeal.getId())); + } + return shopMealList; + } + + @Override + public ShopMeal selectById(String id) { + ShopMeal shopMeal = super.selectById(id); + shopAreaService.setDataMation(shopMeal.getMealAreaList(), ShopMealArea::getAreaId); + shopMeal.setName(shopMeal.getTitle()); + return shopMeal; + } + + @Override + public List selectByIds(String... ids) { + List shopMealList = super.selectByIds(ids); + shopMealList.forEach(shopMeal -> { + shopMeal.setName(shopMeal.getTitle()); + }); + return shopMealList; + } + + @Override + public void queryShopMealByStoreId(InputObject inputObject, OutputObject outputObject) { + String storeId = inputObject.getParams().get("storeId").toString(); + if (StrUtil.isEmpty(storeId)) { + return; + } + ShopStore shopStore = shopStoreService.selectById(storeId); + // 获取门店所在区域的套餐 + List shopMealAreas = shopMealAreaService.queryMealAreaByAreaId(shopStore.getShopAreaId()); + if (CollectionUtil.isEmpty(shopMealAreas)) { + return; + } + List mealIds = shopMealAreas.stream().map(ShopMealArea::getMealId).collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, mealIds); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopMeal::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List shopMealList = list(queryWrapper); + shopMealList.forEach(shopMeal -> { + shopMeal.setName(shopMeal.getTitle()); + }); + outputObject.setBeans(shopMealList); + outputObject.settotal(shopMealList.size()); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/StatisticsShopServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/StatisticsShopServiceImpl.java new file mode 100644 index 0000000..32e85d8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/meal/service/impl/StatisticsShopServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.meal.service.impl; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.meal.dao.StatisticsShopDao; +import com.skyeye.eve.service.ISysDictDataService; +import com.skyeye.meal.service.StatisticsShopService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StatisticsShopServiceImpl + * @Description: 商城统计服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/12 23:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class StatisticsShopServiceImpl implements StatisticsShopService { + + @Autowired + private StatisticsShopDao statisticsShopDao; + + @Autowired + private ISysDictDataService iSysDictDataService; + + /** + * 统计分析 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStatisticsShop(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + Map result = new HashMap<>(); + // 获取指定日期范围内的购买套餐(已支付,已收货)的会员数 + String mealOrderMemberByNum = statisticsShopDao.queryMealOrderMemberByNum(params); + result.put("mealOrderMemberByNum", mealOrderMemberByNum); + // 获取指定日期范围内的购买套餐(已支付,已收货)的数量 + String mealOrderNum = statisticsShopDao.queryMealOrderNum(params); + result.put("mealOrderNum", mealOrderNum); + // 获取指定日期范围内的保养订单(保养完成,已核销)的数量 + String keepFitOrderNum = statisticsShopDao.queryKeepFitOrderNum(params); + result.put("keepFitOrderNum", keepFitOrderNum); + // 获取指定日期范围内的保养订单(保养完成,已核销)的金额 + String keepFitOrderPrice = statisticsShopDao.queryKeepFitOrderPrice(params); + result.put("keepFitOrderPrice", keepFitOrderPrice); + String startTime = params.get("startTime").toString(); + String endTime = params.get("endTime").toString(); + List month = DateUtil.getMonth(startTime, endTime); + params.put("month", month); + // 按年月获取指定日期范围内的购买套餐(已支付,已收货)的数量 + List> monthMealOrderNum = statisticsShopDao.queryMonthMealOrderNum(params); + result.put("monthMealOrderNum", monthMealOrderNum); + // 按年月获取指定日期范围内的购买套餐(已支付,已收货)的数量 + List> monthKeepFitOrderNum = statisticsShopDao.queryMonthKeepFitOrderNum(params); + result.put("monthKeepFitOrderNum", monthKeepFitOrderNum); + // 按年月获取指定日期范围内门店的购买套餐(已支付,已收货)的数量 + List> storeMealOrderNum = statisticsShopDao.queryStoreMealOrderNum(params); + result.put("storeMealOrderNum", storeMealOrderNum); + // 按年月获取指定日期范围内门店的保养订单(保养完成,已核销)的数量 + List> storeKeepFitOrderNum = statisticsShopDao.queryStoreKeepFitOrderNum(params); + result.put("storeKeepFitOrderNum", storeKeepFitOrderNum); + // 按年月获取指定日期范围内性质的套餐订单(已支付,已收货)的数量 + List> natureMealOrderNum = statisticsShopDao.queryNatureMealOrderNum(params); + iSysDictDataService.setNameForMap(natureMealOrderNum, "natureId", "name"); + result.put("natureMealOrderNum", natureMealOrderNum); + + outputObject.setBean(result); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/config/PayProperties.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/config/PayProperties.java new file mode 100644 index 0000000..1dc4b27 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/config/PayProperties.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.config; + +import lombok.Data; +import org.hibernate.validator.constraints.URL; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotEmpty; + +/** + * @ClassName: PayProperties + * @Description: 支付回调配置 + * @author: skyeye云系列--卫志强 + * @date: 2024/11/21 9:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@ConfigurationProperties(prefix = "skyeye.pay") +@Validated +@Data +public class PayProperties { + + private static final String ORDER_NO_PREFIX = "P"; + private static final String REFUND_NO_PREFIX = "R"; + + private static final String WALLET_PAY_APP_KEY_DEFAULT = "wallet"; + + /** + * 支付回调地址 + *

+ * 实际上,对应的 PayNotifyController 的 notifyOrder 方法的 URL + *

+ * 回调顺序:支付渠道(支付宝支付、微信支付) => pay 的 orderNotifyUrl 地址 => 业务的 PayAppDO.orderNotifyUrl 地址 + */ + @NotEmpty(message = "支付回调地址不能为空") + @URL(message = "支付回调地址的格式必须是 URL") + private String orderNotifyUrl; + + /** + * 退款回调地址 + *

+ * 实际上,对应的 PayNotifyController 的 notifyRefund 方法的 URL + *

+ * 回调顺序:支付渠道(支付宝支付、微信支付) => pay 的 refundNotifyUrl 地址 => 业务的 PayAppDO.notifyRefundUrl 地址 + */ + @NotEmpty(message = "支付回调地址不能为空") + @URL(message = "支付回调地址的格式必须是 URL") + private String refundNotifyUrl; + + /** + * 支付订单 no 的前缀 + */ + @NotEmpty(message = "支付订单 no 的前缀不能为空") + private String orderNoPrefix = ORDER_NO_PREFIX; + + /** + * 退款订单 no 的前缀 + */ + @NotEmpty(message = "退款订单 no 的前缀不能为空") + private String refundNoPrefix = REFUND_NO_PREFIX; + + /** + * 钱包支付应用 AppKey + */ + @NotEmpty(message = "钱包支付应用 AppKey 不能为空") + private String walletPayAppKey = WALLET_PAY_APP_KEY_DEFAULT; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderCommentController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderCommentController.java new file mode 100644 index 0000000..a50001d --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderCommentController.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.conroller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.order.entity.OrderComment; +import com.skyeye.order.service.OrderCommentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OrderCommentController + * @Description: 商品订单评价管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商品订单评价管理", tags = "商品订单评价管理", modelName = "商品订单评价管理") +public class OrderCommentController { + + @Autowired + private OrderCommentService orderCommentService; + + /** + * 新增商品订单评价信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertOrderComment", value = "新增商品订单评价信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = OrderComment.class) + @RequestMapping("/post/OrderCommentController/insertOrderComment") + public void insertOrderComment(InputObject inputObject, OutputObject outputObject) { + orderCommentService.createEntity(inputObject, outputObject); + } + + /** + * 根据id删除商品订单评价信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteOrderCommentById", value = "根据id删除商品订单评价信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderCommentController/deleteOrderCommentById") + public void deleteOrderCommentById(InputObject inputObject, OutputObject outputObject) { + orderCommentService.deleteById(inputObject, outputObject); + } + + /** + * 根据id查询商品订单评价信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectOrderCommentById", value = "根据id查询商品订单评价信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderCommentController/selectOrderCommentById") + public void selectOrderCommentById(InputObject inputObject, OutputObject outputObject) { + orderCommentService.selectById(inputObject, outputObject); + } + + /** + * 分页查询商品订单评价信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOrderCommentPageList", value = "分页查询商品订单评价信息", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OrderCommentController/queryOrderCommentPageList") + public void queryOrderCommentPageList(InputObject inputObject, OutputObject outputObject) { + orderCommentService.queryOrderCommentPageList(inputObject, outputObject); + } + + /** + * 分页查询商品订单评价信息PC + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOrderCommentPageListPC", value = "分页查询商品订单评价信息PC", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OrderCommentController/queryOrderCommentPageListPC") + public void queryOrderCommentPageListPC(InputObject inputObject, OutputObject outputObject) { + orderCommentService.queryPageList(inputObject,outputObject); + } + + /** + * 分页查询自己的商品订单评价信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyOrderCommentList", value = "分页查询自己的商品订单评价信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OrderCommentController/queryMyOrderCommentList") + public void queryMyOrderCommentList(InputObject inputObject, OutputObject outputObject) { + orderCommentService.queryMyOrderCommentList(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderController.java new file mode 100644 index 0000000..c8bebf6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/conroller/OrderController.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.conroller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.order.entity.Order; +import com.skyeye.order.service.OrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: OrderController + * @Description: 商品订单管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "商品订单管理", tags = "商品订单管理", modelName = "商品订单管理") +public class OrderController { + + @Autowired + private OrderService orderService; + + /** + * 新增商品订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertOrder", value = "新增商品订单信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Order.class) + @RequestMapping("/post/OrderController/insertOrder") + public void insertOrder(InputObject inputObject, OutputObject outputObject) { + orderService.createEntity(inputObject, outputObject); + } + + /** + * 分页获取商品订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOrderPageListPC", value = "分页获取商品订单信息(后台管理)", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OrderController/queryOrderPageListPC") + public void queryOrderPageListPC(InputObject inputObject, OutputObject outputObject) { + orderService.queryPageList(inputObject, outputObject); + } + + /** + * 订单调价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "changeOrderAdjustPrice", value = "订单调价", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "adjustPrice", name = "adjustPrice", value = "调整的价格,不可为负数", required = "required")}) + @RequestMapping("/post/OrderController/changeOrderAdjustPrice") + public void changeOrderAdjustPrice(InputObject inputObject, OutputObject outputObject) { + orderService.changeOrderAdjustPrice(inputObject, outputObject); + } + + /** + * 分页获取商品订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryOrderPageList", value = "分页获取商品订单信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/OrderController/queryOrderPageList") + public void queryOrderList(InputObject inputObject, OutputObject outputObject) { + orderService.queryOrderPageList(inputObject, outputObject); + } + + /** + * 批量删除商品订单信息 未知,可能没用到,预留 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteOrderByIds", value = "批量删除商品订单信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/OrderController/deleteOrderByIds") + public void deleteOrderByIds(InputObject inputObject, OutputObject outputObject) { + orderService.deleteByIds(inputObject, outputObject); + } + + /** + * 根据id查询商品订单信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectOrderById", value = "根据id查询商品订单信息", method = "POST", allUse = "2") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderController/selectOrderById") + public void selectOrderById(InputObject inputObject, OutputObject outputObject) { + orderService.selectById(inputObject, outputObject); + } + + /** + * 商品订单取消 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "cancelOrder", value = "商品订单取消", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "cancelType", name = "cancelType", value = "取消类型", required = "required")}) + @RequestMapping("/post/OrderController/cancelOrder") + public void cancelOrder(InputObject inputObject, OutputObject outputObject) { + orderService.cancelOrder(inputObject, outputObject); + } + + /** + * 商品订单完成 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "finishOrder", value = "商品订单完成", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderController/finishOrder") + public void finishOrder(InputObject inputObject, OutputObject outputObject) { + orderService.finishOrder(inputObject, outputObject); + } + + /** + * 商品订单支付 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "payOrder", value = "商品订单支付", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "channelCode", name = "channelCode", value = "支付渠道编码", required = "required"), + @ApiImplicitParam(id = "channelExtras", name = "channelExtras", value = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数", required = "json")}) + @RequestMapping("/post/OrderController/payOrder") + public void payOrder(InputObject inputObject, OutputObject outputObject) { + orderService.payOrder(inputObject, outputObject); + } + + /** + * 商品订单发货 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deliverGoodsByOrderId", value = "商品订单发货", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderController/deliverGoodsByOrderId") + public void deliverGoodsByOrderId(InputObject inputObject, OutputObject outputObject) { + orderService.deliverGoodsByOrderId(inputObject, outputObject); + } + + /** + * 生成支付订单的二维码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "generatePayOrderRrCode", value = "生成支付订单的二维码", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "channelCode", name = "channelCode", value = "支付渠道编码", required = "required")}) + @RequestMapping("/post/OrderController/generatePayOrderRrCode") + public void generatePayOrderRrCode(InputObject inputObject, OutputObject outputObject) { + orderService.generatePayOrderRrCode(inputObject, outputObject); + } + + /** + * 后台修改支付状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateOrderToPayState", value = "后台修改支付状态", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/OrderController/updateOrderToPayState") + public void updateOrderToPayState(InputObject inputObject, OutputObject outputObject) { + orderService.updateOrderToPayState(inputObject, outputObject); + } + + /** + * 修改订单签收状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateOrderItemState", value = "修改订单签收状态", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "orderItemId", name = "orderItemId", value = "子单Id", required = "required")}) + @RequestMapping("/post/OrderController/updateOrderItemState") + public void updateOrderItemState(InputObject inputObject, OutputObject outputObject) { + orderService.updateOrderItemState(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderCommentDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderCommentDao.java new file mode 100644 index 0000000..5051b24 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderCommentDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.order.entity.OrderComment; + +/** + * @ClassName: OrderCommentDao + * @Description: 订单评价管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderCommentDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderDao.java new file mode 100644 index 0000000..4a886fb --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.order.entity.Order; + +/** + * @ClassName: OrderDao + * @Description: 订单表数据处理层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderItemDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderItemDao.java new file mode 100644 index 0000000..1020994 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/dao/OrderItemDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.order.entity.OrderItem; + +/** + * @ClassName: OrderItemDao + * @Description: 订单评论数据持久层 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderItemDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/Order.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/Order.java new file mode 100644 index 0000000..8f12916 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/Order.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.entity.features.AreaInfo; +import com.skyeye.order.enums.*; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: Order + * @Description: 商品订单管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +//@RedisCacheField(name = "shop:order") +@TableName("shop_order") +@ApiModel("商品订单管理实体类") +public class Order extends AreaInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id") + private String id; + + @TableField("odd_number") + @Property(value = "订单编号", fuzzyLike = true) + private String oddNumber; + + @TableField("type") + @ApiModelProperty(value = "订单类型", required = "required",enumClass = ShopOrderType.class) + private Integer type; + + @TableField("terminal") + @ApiModelProperty(value = "订单来源", required = "required", enumClass = ShopOrderTerminal.class) + private Integer terminal; + + @TableField("user_ip") + @Property(value = "用户ip") + private String userIp; + + @TableField("state") + @Property(value = "状态",enumClass = ShopOrderState.class) + private Integer state; + + @TableField("count") + @Property(value = "商品的总数量") + private Integer count; + + @TableField("finish_time") + @Property(value = "订单完成时间") + private String finishTime; + + @TableField("cancel_time") + @Property(value = "订单取消时间") + private String cancelTime; + + @TableField("cancel_type") + @Property(value = "取消类型",enumClass = ShopOrderCancelType.class) + private Integer cancelType; + + @TableField("comment_state") + @Property(value = "是否评价", enumClass = ShopOrderCommentState.class) + private Integer commentState; + + @TableField("brokerage_user_id") + @ApiModelProperty(value = "分销用户id") + private String brokerageUserId; + + @TableField("pay_time") + @Property(value = "付款时间") + private String payTime; + + @TableField("pay_type") + @Property(value = "付款类型") + private String payType; + + @TableField("total_price") + @Property(value = "商品总价,单位:分") + private String totalPrice; + + @TableField("discount_price") + @Property(value = "优惠金额,单位:分") + private String discountPrice; + + @TableField("delivery_price") + @Property(value = "运费金额,单位:分") + private String deliveryPrice; + + @TableField("adjust_price") + @ApiModelProperty(value = "订单调价,单位:分,正数,加价;负数,减价") + private String adjustPrice; + + @TableField("pay_price") + @Property(value = "应付金额(总),单位:分") + private String payPrice; + + @TableField("delivery_type") + @ApiModelProperty(value = "配送方式") + private Integer deliveryType; + + @TableField("tms_order_id") + @ApiModelProperty(value = "物流单id") + private String tmsOrderId; + + @TableField("receive_time") + @Property(value = "收货时间") + private String receiveTime; + + @TableField("address_id") + @ApiModelProperty(value = "收货地址id", required = "required") + private String addressId; + + @TableField(exist = false) + @Property(value = "收货地址信息") + private Map addressMation; + + @TableField("receiver_name") + @Property(value = "收件人姓名") + private String receiverName; + + @TableField("receiver_mobile") + @Property(value = "收件人手机") + private String receiverMobile; + + @TableField("pick_up_store_id") + @ApiModelProperty(value = "delivery_type=自提时,自提门店id") + private String pickUpStoreId; + + @TableField("pick_up_verify_code") + @ApiModelProperty(value = "自提核销码") + private String pickUpVerifyCode; + + @TableField("coupon_use_id") + @ApiModelProperty(value = "用户领取的优惠券id") + private String couponUseId; + + @TableField(exist = false) + @Property(value = "用户领取的优惠券信息") + private Map couponUseMation; + + @TableField("coupon_price") + @Property(value = "优惠劵减免金额,单位:分") + private String couponPrice; + + @TableField("use_point") + @Property(value = "使用的积分") + private Integer usePoint; + + @TableField("point_price") + @Property(value = "积分抵扣的金额,单位:分") + private String pointPrice; + + @TableField("give_point") + @ApiModelProperty(value = "赠送的积分") + private Integer givePoint; + + @TableField("vip_price") + @Property(value = "VIP 减免金额,单位:分") + private String vipPrice; + + @TableField("seckill_activity_id") + @ApiModelProperty(value = "秒杀活动id") + private String seckillActivityId; + + @TableField("bargain_activity_id") + @ApiModelProperty(value = "砍价活动id") + private String bargainActivityId; + + @TableField("bargain_record_id") + @ApiModelProperty(value = "砍价记录id") + private String bargainRecordId; + + @TableField("combination_activity_id") + @ApiModelProperty(value = "拼团活动id") + private String combinationActivityId; + + @TableField("combination_record_id") + @ApiModelProperty(value = "拼团记录id") + private String combinationRecordId; + + @TableField("user_remark") + @ApiModelProperty(value = "用户备注") + private String userRemark; + + @TableField("remark") + @ApiModelProperty(value = "商家备注") + private String remark; + + @TableField(exist = false) + @ApiModelProperty(value = "子单列表", required = "required,json") + private List orderItemList; + + @TableField("channel_fee_rate") + @Property(value = "渠道手续费,单位:百分比") + private Double channelFeeRate; + + @TableField("channel_fee_price") + @Property(value = "渠道手续金额,单位:分") + private Integer channelFeePrice; + + @TableField("extension_id") + @Property(value = "支付成功的订单拓展单编号") + private String extensionId; + + @TableField("extension_no") + @Property(value = "支付成功的外部订单号") + private String extensionNo; + + @TableField("create_name") + @ApiModelProperty(value = "创建人") + private String createName; +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderComment.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderComment.java new file mode 100644 index 0000000..11ae8fa --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderComment.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.order.enums.OrderCommentType; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OrderComment + * @Description: 商品订单评价管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName("shop_order_comment") +@ApiModel("商品订单评价管理实体类") +public class OrderComment extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id") + private String id; + + @TableField(value = "parent_id") + @ApiModelProperty(value = "父id") + private String parentId; + + @TableField(value = "norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField(value = "material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Map materialMation; + + @TableField(value = "store_id") + @ApiModelProperty(value = "店铺id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + + @TableField(exist = false) + @Property(value = "子单信息") + private Map orderItemMation; + + @TableField(value = "order_id") + @ApiModelProperty(value = "订单id", required = "required") + private String orderId; + + @TableField(value = "order_item_id") + @ApiModelProperty(value = "订单子单id", required = "required") + private String orderItemId; + + @TableField(value = "type") + @ApiModelProperty(value = "类型",enumClass = OrderCommentType.class) + private Integer type; + + @TableField(value = "start") + @ApiModelProperty(value = "星级(1-5)") + private Integer start; + + @TableField(value = "is_comment") + @ApiModelProperty(value = "是否评价",enumClass = WhetherEnum.class) + private Integer isComment; + + @TableField(value = "context") + @ApiModelProperty(value = "评价内容", required = "required") + private String context; + + @TableField(exist = false) + @Property(value = "客户追评") + private Map additionalReview; + + @TableField(exist = false) + @Property(value = "商家回复") + private List> merchantReply; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderItem.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderItem.java new file mode 100644 index 0000000..97e5c2a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/entity/OrderItem.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.order.enums.ShopOrderItemState; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: OrderItem + * @Description: 商品订单单子项管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName("shop_order_item") +@ApiModel("商品订单单子项管理实体类") +public class OrderItem extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id") + private String id; + + @TableField("parent_id") + @ApiModelProperty(value = "订单id") + private String parentId; + + @TableField("store_id") + @Property(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; + + @TableField("material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @Property(value = "商品信息") + private Map materialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @Property(value = "规格信息") + private Map normsMation; + + @TableField("material_store_id") + @ApiModelProperty(value = "商品与门店的关系id", required = "required") + private String materialStoreId; + + @TableField(exist = false) + @Property(value = "商品与门店的关系信息") + private Map shopMaterial; + + @TableField("count") + @ApiModelProperty(value = "购买数量", required = "required") + private Integer count; + + @TableField("comment_state") + @Property(value = "是否评价", enumClass = WhetherEnum.class) + private Integer commentState; + + @TableField("price") + @Property(value = "商品原价(单),单位:分") + private String price; + + @TableField("discount_price") + @Property(value = "优惠金额(总),单位:分") + private String discountPrice; + + @TableField("delivery_price") + @Property(value = "运费金额(总),单位:分") + private String deliveryPrice; + + @TableField("adjust_price") + @ApiModelProperty(value = "订单调价(总),单位:分") + private String adjustPrice; + + @TableField("pay_price") + @Property(value = "应付金额(总),单位:分") + private String payPrice; + + @TableField("coupon_use_id") + @ApiModelProperty(value = "用户领取的优惠券id") + private String couponUseId; + + @TableField(exist = false) + @Property(value = "用户领取的优惠券信息") + private Map couponUseMation; + + @TableField("coupon_price") + @Property(value = "优惠劵减免金额,单位:分") + private String couponPrice; + + @TableField("use_point") + @ApiModelProperty(value = "使用的积分") + private Integer usePoint; + + @TableField("point_price") + @ApiModelProperty(value = "积分抵扣的金额,单位:分") + private String pointPrice; + + @TableField("give_point") + @ApiModelProperty(value = "赠送的积分") + private Integer givePoint; + + @TableField("vip_price") + @ApiModelProperty(value = "VIP 减免金额,单位:分") + private String vipPrice; + + @TableField("order_item_state") + @ApiModelProperty(value = "订单子单状态",enumClass= ShopOrderItemState.class) + private Integer orderItemState; + + @TableField(exist = false) + @Property(value = "是否已经追评") + private Boolean isAdditionalReview; + +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/OrderCommentType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/OrderCommentType.java new file mode 100644 index 0000000..3c404bb --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/OrderCommentType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: OrderCommentType + * @Description: 订单评论类型枚举 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum OrderCommentType implements SkyeyeEnumClass { + CUSTOMERFiRST(0, "客户评价", true, false), + CUSTOMERLATER(1, "客户追评", true, false), + MERCHANT(2, "商家回复", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCancelType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCancelType.java new file mode 100644 index 0000000..00f92b5 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCancelType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderCancelType + * @Description: 订单取消类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderCancelType implements SkyeyeEnumClass { + + PAY_TIMEOUT(1, "超时未支付", true, false), + AFTER_SALE_CLOSE(2, "退款关闭", true, false), + MEMBER_CANCEL(3, "买家取消", true, false), + COMBINATION_CLOSE(4, "拼团关闭", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCommentState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCommentState.java new file mode 100644 index 0000000..40425e4 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderCommentState.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderCommentState + * @Description: 订单评价类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderCommentState implements SkyeyeEnumClass { + + UNFINISHED(0, "未评价", true, false), + PORTION(1, "部分评价", true, false), + FINISHED(2, "已全部评价", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderItemState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderItemState.java new file mode 100644 index 0000000..ce72e9a --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderItemState.java @@ -0,0 +1,30 @@ +package com.skyeye.order.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderCancelType + * @Description: 订单取消类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderItemState { + DELIVERED(1, "已签收",true,false), + FINISHED(2, "已完成",true,false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderState.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderState.java new file mode 100644 index 0000000..03c74a8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderState.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderState + * @Description: 订单状态 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:33 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderState implements SkyeyeEnumClass { + + UNSUBMIT(0, "未提交", true, false), + SUBMIT(1, "已提交", true, false), + UNPAID(2, "待支付", true, false), + FAIRPAID(3, "支付失败", true, false), + CANCELED(4, "已取消", true, false), + UNDELIVERED(5, "待发货", true, false), + DELIVERED(6, "已发货", true, false), + TRANSPORTING(7, "运输中", true, false), + SIGN(8, "已签收", true, false), + COMPLETED(9, "已完成", true, false), + UNEVALUATE(10, "待评价", true, false), + EVALUATED(11, "已评价", true, false), + REFUNDING(12, "退款中", true, false), + REFUND(13, "已退款", true, false), + SALESRETURNING(14, "退货中", true, false), + SALESRETURNED(15, "已退货", true, false), + EXCHANGEING(16, "换货中", true, false), + EXCHANGED(17, "已换货", true, false), + PARTIALLYDONE(18,"部分完成",true,false), + PARTIALEVALUATION(19,"部分评价",true,false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderTerminal.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderTerminal.java new file mode 100644 index 0000000..2770756 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderTerminal.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderTerminal + * @Description: 订单来源 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:30 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderTerminal implements SkyeyeEnumClass { + + UNKNOWN(0, "未知", true, false), + WECHAT_MINI_PROGRAM(1, "微信小程序", true, false), + WECHAT_WAP(2, "微信公众号", true, false), + H5(3, "H5 网页", true, false), + APP(4, "手机 App", true, false), + PC(5, "PC端", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderType.java new file mode 100644 index 0000000..23b69bb --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/enums/ShopOrderType.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.enums; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: ShopOrderType + * @Description: 商品订单类型 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:28 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum ShopOrderType implements SkyeyeEnumClass { + + NORMAL(0, "普通订单", true, false), + SECKILL(1, "秒杀订单", true, false), + BARGAIN(2, "砍价订单", true, false), + COMBINATION(3, "拼团订单", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderCommentService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderCommentService.java new file mode 100644 index 0000000..54a9927 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderCommentService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.order.entity.OrderComment; +import com.skyeye.order.entity.OrderItem; + +import java.util.List; + +/** + * @ClassName: OrderCommentService + * @Description: 商品订单评论管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderCommentService extends SkyeyeBusinessService { + void queryOrderCommentPageList(InputObject inputObject, OutputObject outputObject); + + List queryListByOrderItemIdAndType(List orderItemIds, Integer key); + + void queryMyOrderCommentList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderItemService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderItemService.java new file mode 100644 index 0000000..2f078a2 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderItemService.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.order.entity.Order; +import com.skyeye.order.entity.OrderItem; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: OrderItemService + * @Description: 商品订单评论管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderItemService extends SkyeyeBusinessService { + + void deleteByPerentIds(List ids); + + List queryListByStateAndOrderId(String orderId, Integer state); + + Map> queryListByParentId(List idList); + + void setValueAndCreateEntity(Order order, String userId); + + void updateCommentStateById(String id); + + List queryOrderItemByParentId(String orderId); + + void UpdateOrderItemState(String orderItemId); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderService.java new file mode 100644 index 0000000..4642dba --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/OrderService.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.order.entity.Order; + +import java.util.List; + +/** + * @ClassName: OrderService + * @Description: 商品订单管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface OrderService extends SkyeyeBusinessService { + void cancelOrder(InputObject inputObject, OutputObject outputObject); + + void finishOrder(InputObject inputObject, OutputObject outputObject); + + void payOrder(InputObject inputObject, OutputObject outputObject); + + void deliverGoodsByOrderId(InputObject inputObject, OutputObject outputObject); + + void updateCommonState(String id, Integer state); + + void queryOrderPageList(InputObject inputObject, OutputObject outputObject); + + void generatePayOrderRrCode(InputObject inputObject, OutputObject outputObject); + + void changeOrderAdjustPrice(InputObject inputObject, OutputObject outputObject); + + void updateOrderToPayState(InputObject inputObject, OutputObject outputObject); + + void setOrderCancle(String orderId); + + void updateOrderItemState(InputObject inputObject, OutputObject outputObject); + + void updateOrderState(String orderId, Integer partiallydoneKey); + + List queryOrderList(String orderId); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderCommentServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderCommentServiceImpl.java new file mode 100644 index 0000000..3dc0bf2 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderCommentServiceImpl.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.order.dao.OrderCommentDao; +import com.skyeye.order.entity.OrderComment; +import com.skyeye.order.entity.OrderItem; +import com.skyeye.order.enums.OrderCommentType; +import com.skyeye.order.enums.ShopOrderCommentState; +import com.skyeye.order.enums.ShopOrderState; +import com.skyeye.order.service.OrderCommentService; +import com.skyeye.order.service.OrderItemService; +import com.skyeye.order.service.OrderService; +import com.skyeye.service.MemberService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @ClassName: OrderCommentServiceImpl + * @Description: 商品订单评价管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品订单评价管理", groupName = "商品订单评价管理") +public class OrderCommentServiceImpl extends SkyeyeBusinessServiceImpl implements OrderCommentService { + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private OrderService orderService; + + @Autowired + private OrderItemService orderItemService; + + @Autowired + private MemberService memberService; + + @Autowired + private ShopStoreService shopStoreService; + + @Override + public void validatorEntity(OrderComment orderComment) { + Integer commentType = orderComment.getType(); + if (commentType != OrderCommentType.MERCHANT.getKey() + && commentType != OrderCommentType.CUSTOMERLATER.getKey() + && commentType != OrderCommentType.CUSTOMERFiRST.getKey()) { + throw new CustomException("type值非法"); + } + if (commentType == OrderCommentType.MERCHANT.getKey() || + commentType == OrderCommentType.CUSTOMERLATER.getKey()) { + if (StrUtil.isEmpty(orderComment.getParentId())) { + throw new CustomException("商家回复评价和客户追评,父级评价id不能为空."); + } + } + if (commentType == OrderCommentType.CUSTOMERFiRST.getKey()) { + if (StrUtil.isNotEmpty(orderComment.getParentId())) { + throw new CustomException("客户的评价无需父级id"); + } + } + } + + @Override + public void createPrepose(OrderComment entity) { + OrderItem orderItem = orderItemService.selectById(entity.getOrderItemId()); + if (StrUtil.isEmpty(orderItem.getId())) { + throw new CustomException("所评价的子订单不存在"); + } + // 客户评价判断 + if (orderItem.getCommentState() == WhetherEnum.DISABLE_USING.getKey()) {// 子订单未评价 + if (entity.getType() == OrderCommentType.CUSTOMERLATER.getKey()) { + throw new CustomException("客户追评,需先进行首评。"); + } + if (entity.getType() == OrderCommentType.CUSTOMERFiRST.getKey()) {// 客户首评 + Integer start = entity.getStart(); + if (ObjectUtil.isEmpty(entity.getStart())) { + throw new CustomException("首评的星级不能为空"); + } + if (start < 0 || start > 5) { + throw new CustomException("评价星级为1-5"); + } + } + } else if (orderItem.getCommentState() == WhetherEnum.ENABLE_USING.getKey()) {// 子订单已评价 + if (entity.getType() == OrderCommentType.CUSTOMERFiRST.getKey()) {// 再次进行首评 + throw new CustomException("首评只能评价一次。"); + } + if (entity.getType() == OrderCommentType.CUSTOMERLATER.getKey()) {// 追评 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderComment::getOrderItemId), entity.getOrderItemId()) + .eq(MybatisPlusUtil.toColumns(OrderComment::getCreateId), InputObject.getLogParamsStatic().get("id").toString()) + .and(wrap -> { + String parentId = MybatisPlusUtil.toColumns(OrderComment::getParentId); + wrap.isNotNull(parentId).ne(parentId, StrUtil.EMPTY); + }); + OrderComment one = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(one)) {// 客户已追评 + throw new CustomException("追评只能追评一次"); + } + entity.setStart(null); + } + } + entity.setStoreId(ObjectUtil.isEmpty(orderItem) ? "" : orderItem.getStoreId());// 设置门店id + if (entity.getType() == OrderCommentType.CUSTOMERFiRST.getKey() || + entity.getType() == OrderCommentType.CUSTOMERLATER.getKey()) {// 顾客新增的评价,商家均未回复 + entity.setIsComment(WhetherEnum.DISABLE_USING.getKey()); + } + } + + @Override + public void createPostpose(OrderComment orderComment, String userId) { + if (orderComment.getType() == OrderCommentType.MERCHANT.getKey()) {// 商家回复时,修改客户评价状态为已评价 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, orderComment.getParentId()); + updateWrapper.set(MybatisPlusUtil.toColumns(OrderComment::getIsComment), WhetherEnum.ENABLE_USING.getKey()); + update(updateWrapper); + } else if (orderComment.getType() == OrderCommentType.CUSTOMERFiRST.getKey()) {// 客户首评 + orderItemService.updateCommentStateById(orderComment.getOrderItemId());// 修改此子订单的评价状态为已评价 + List orderItemList = orderItemService.queryListByStateAndOrderId(orderComment.getOrderId(), WhetherEnum.DISABLE_USING.getKey()); + boolean allMatch = orderItemList.stream() + .allMatch(Orderitem -> Orderitem.getCommentState() == WhetherEnum.ENABLE_USING.getKey()); + if (allMatch) { + orderService.updateCommonState(orderComment.getOrderId(), ShopOrderCommentState.FINISHED.getKey()); + orderService.updateOrderState(orderComment.getOrderId(), ShopOrderState.EVALUATED.getKey()); + } else { + orderService.updateCommonState(orderComment.getOrderId(), ShopOrderCommentState.PORTION.getKey()); + orderService.updateOrderState(orderComment.getOrderId(), ShopOrderState.PARTIALEVALUATION.getKey()); + } + } + } + + @Override + public OrderComment selectById(String id) { + OrderComment orderComment = super.selectById(id); + if (ObjectUtil.isEmpty(orderComment)) { + throw new CustomException("信息不存在"); + } + iMaterialService.setDataMation(orderComment, OrderComment::getMaterialId); + iMaterialNormsService.setDataMation(orderComment, OrderComment::getNormsId); + memberService.setDataMation(orderComment, OrderComment::getCreateId); + shopStoreService.setDataMation(orderComment, OrderComment::getStoreId); + refreshCache(id); + return orderComment; + } + + public List> queryPageDataList(InputObject inputObject) { + List> mapList = super.queryPageDataList(inputObject); + iMaterialService.setMationForMap(mapList, "materialId", "materialMation"); + iMaterialNormsService.setMationForMap(mapList, "normsId", "normsMation"); + memberService.setMationForMap(mapList, "createId", "createMation"); + shopStoreService.setMationForMap(mapList, "storeId", "storeMation"); + return mapList; + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + String typeId = commonPageInfo.getTypeId(); + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + queryWrapper.and(wrap -> { + wrap.eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.CUSTOMERFiRST.getKey()) + .or().eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.CUSTOMERLATER.getKey()); + }); + if (StrUtil.isNotEmpty(typeId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderComment::getStoreId), typeId); + } + return queryWrapper; + } + + @Override + public void queryOrderCommentPageList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String typeId = commonPageInfo.getTypeId(); + String objectId = commonPageInfo.getObjectId(); + // 查首评论 + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.and(wrap -> { + wrap.eq(MybatisPlusUtil.toColumns(OrderComment::getMaterialId), typeId) // 商品id + .eq(MybatisPlusUtil.toColumns(OrderComment::getParentId), "") + .or().eq(MybatisPlusUtil.toColumns(OrderComment::getOrderItemId), typeId)// 订单子单id + .or().eq(MybatisPlusUtil.toColumns(OrderComment::getOrderId), typeId);// 订单id + }).orderByDesc(MybatisPlusUtil.toColumns(OrderComment::getCreateTime)); + if (StrUtil.isNotEmpty(objectId)) { + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderComment::getNormsId), objectId); + } + List listFirst = list(queryWrapper); + if (CollectionUtil.isEmpty(listFirst)) { + return; + } + setValue(listFirst); + List firstId = listFirst.stream().map(OrderComment::getId).collect(Collectors.toList()); + QueryWrapper queryWrapperLater = new QueryWrapper<>();// 追评 + queryWrapperLater + .in(MybatisPlusUtil.toColumns(OrderComment::getParentId), firstId) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.CUSTOMERLATER.getKey()) + .orderByDesc(MybatisPlusUtil.toColumns(OrderComment::getCreateTime)); + List listLater = list(queryWrapperLater); + setValue(listLater); + // 商家回复 + List idList = Stream.of(listFirst.stream(), listLater.stream()).flatMap(s -> s).map(OrderComment::getId).collect(Collectors.toList()); + QueryWrapper queryWrapperMerchant = new QueryWrapper<>(); + queryWrapperMerchant.in(MybatisPlusUtil.toColumns(OrderComment::getParentId), idList) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.MERCHANT.getKey()); + List marchantList = list(queryWrapperMerchant); + setValue(marchantList); + setAdditionalReviewAndMerchantReply(listFirst, listLater, marchantList); + outputObject.setBeans(listFirst); + outputObject.settotal(pages.getTotal()); + + } + + @Override + public List queryListByOrderItemIdAndType(List orderItemIds, Integer type) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(OrderComment::getOrderItemId), orderItemIds) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), type); + List list = list(queryWrapper); + return CollectionUtil.isEmpty(list) ? new ArrayList<>() : list; + } + + @Override + public void queryMyOrderCommentList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapperFirst = new QueryWrapper<>();// 客户首评 + queryWrapperFirst + .eq(MybatisPlusUtil.toColumns(OrderComment::getCreateId), inputObject.getLogParams().get("id").toString()) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.CUSTOMERFiRST.getKey()) + .orderByDesc(MybatisPlusUtil.toColumns(OrderComment::getCreateTime)); + List listFirst = list(queryWrapperFirst); + setValue(listFirst); + if (CollectionUtil.isEmpty(listFirst)) { + return; + } + QueryWrapper queryWrapperLater = new QueryWrapper<>();// 追评 + queryWrapperLater + .eq(MybatisPlusUtil.toColumns(OrderComment::getCreateId), inputObject.getLogParams().get("id").toString()) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.CUSTOMERLATER.getKey()) + .orderByDesc(MybatisPlusUtil.toColumns(OrderComment::getCreateTime)); + List listLater = list(queryWrapperLater); + setValue(listLater); + // 商家回复 + List idList = Stream.of(listFirst.stream(), listLater.stream()).flatMap(s -> s).map(OrderComment::getId).collect(Collectors.toList()); + QueryWrapper queryWrapperMerchant = new QueryWrapper<>(); + queryWrapperMerchant.in(MybatisPlusUtil.toColumns(OrderComment::getParentId), idList) + .eq(MybatisPlusUtil.toColumns(OrderComment::getType), OrderCommentType.MERCHANT.getKey()); + List marchantList = list(queryWrapperMerchant); + setValue(marchantList); + setAdditionalReviewAndMerchantReply(listFirst, listLater, marchantList); + outputObject.setBeans(listFirst); + outputObject.settotal(pages.getTotal()); + } + + private void setValue(List list) { + iMaterialService.setDataMation(list, OrderComment::getMaterialId); + iMaterialNormsService.setDataMation(list, OrderComment::getNormsId); + memberService.setDataMation(list, OrderComment::getCreateId); + shopStoreService.setDataMation(list, OrderComment::getStoreId); + orderItemService.setDataMation(list, OrderComment::getOrderItemId); + } + + private void setAdditionalReviewAndMerchantReply(List orderCommentCustomer, List orderCommentLater, List orderCommentMerchant) { + // 追评放商家回复 + Map> merchantMapList = orderCommentMerchant.stream().collect(Collectors.groupingBy(OrderComment::getParentId)); + for (OrderComment orderComment : orderCommentLater) { + if (merchantMapList.containsKey(orderComment.getId())) { + List> merchantReplyList = merchantMapList.get(orderComment.getId()).stream() + .map(BeanUtil::beanToMap).collect(Collectors.toList()); + orderComment.setMerchantReply(merchantReplyList); + } + } + // 首评放追评和商家回复 + Map> laterMap = orderCommentLater.stream() + .collect(Collectors.toMap(OrderComment::getParentId, o -> JSONUtil.toBean(JSONUtil.toJsonStr(o), null), (key1, key2) -> key2)); + for (OrderComment orderComment : orderCommentCustomer) { + String id = orderComment.getId(); + if (laterMap.containsKey(id)) {// 追评 + orderComment.setAdditionalReview(laterMap.get(id)); + } + if (merchantMapList.containsKey(id)) {// 商家回复 + List> merchantReplyList = merchantMapList.get(id).stream() + .map(BeanUtil::beanToMap).collect(Collectors.toList()); + orderComment.setMerchantReply(merchantReplyList); + } + } + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderItemServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderItemServiceImpl.java new file mode 100644 index 0000000..ecd6eed --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderItemServiceImpl.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.order.dao.OrderItemDao; +import com.skyeye.order.entity.Order; +import com.skyeye.order.entity.OrderComment; +import com.skyeye.order.entity.OrderItem; +import com.skyeye.order.enums.OrderCommentType; +import com.skyeye.order.service.OrderCommentService; +import com.skyeye.order.service.OrderItemService; +import com.skyeye.order.service.OrderService; +import com.skyeye.rest.shopmaterialnorms.sevice.IShopMaterialNormsService; +import com.skyeye.store.service.ShopStoreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: OrderItemServiceImpl + * @Description: 商品订单子单项管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品订单子单项管理", groupName = "商品订单子单项管理") +public class OrderItemServiceImpl extends SkyeyeBusinessServiceImpl implements OrderItemService { + + @Autowired + private IShopMaterialNormsService iShopMaterialNormsService; + + @Autowired + private ShopStoreService shopStoreService; + + @Autowired + private OrderCommentService orderCommentService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private OrderService orderService; + + @Override + public void deleteByPerentIds(List ids) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(OrderItem::getParentId), ids); + remove(queryWrapper); + } + + @Override + public List queryListByStateAndOrderId(String orderId, Integer state) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderItem::getParentId), orderId); + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderItem::getCommentState), state); + List list = list(queryWrapper); + return CollectionUtil.isEmpty(list) ? new ArrayList<>() : list; + } + + @Override + public Map> queryListByParentId(List idList) { + if (CollectionUtil.isEmpty(idList)) { + return new HashMap<>(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(OrderItem::getParentId), idList); + List mapList = list(queryWrapper); + if (CollectionUtil.isEmpty(mapList)) { + return new HashMap<>(); + } + List orderItemIds = mapList.stream().map(OrderItem::getId).collect(Collectors.toList()); + List orderCommentList = orderCommentService.queryListByOrderItemIdAndType(orderItemIds, OrderCommentType.CUSTOMERLATER.getKey()); + List commentIdList = orderCommentList.stream().map(OrderComment::getOrderItemId).collect(Collectors.toList()); + for (OrderItem map : mapList) { + if (commentIdList.contains(map.getId())) { + map.setIsAdditionalReview(true); + } else { + map.setIsAdditionalReview(false); + } + } + shopStoreService.setDataMation(mapList, OrderItem::getStoreId); + iMaterialNormsService.setDataMation(mapList, OrderItem::getNormsId); + List materialStoreIds = mapList.stream().map(OrderItem::getMaterialStoreId).distinct().collect(Collectors.toList()); + List> materialByIds = iShopMaterialNormsService.queryShopMaterialByIds(materialStoreIds);// erp-shop-material 拿价钱logo + Map> materialStoreMap = materialByIds.stream() + .distinct().collect(Collectors.toMap(map -> { + Map shopMaterialStore = JSONUtil.toBean(map.get("shopMaterialStore").toString(), null); + return shopMaterialStore.get("id").toString(); + }, map -> map)); + mapList.forEach(map -> { + map.setShopMaterial(materialStoreMap.containsKey(map.getMaterialStoreId()) ? materialStoreMap.get(map.getMaterialStoreId()) : new HashMap<>()); + }); + Map> result = mapList.stream().collect(Collectors.groupingBy(OrderItem::getParentId)); + return result; + } + + @Override + public void setValueAndCreateEntity(Order order, String userId) { + List materialStoreIds = order.getOrderItemList().stream().map(OrderItem::getMaterialStoreId).distinct().collect(Collectors.toList()); + // shopMaterial -> shopMaterialStore -> storeId + List> materialByIds = iShopMaterialNormsService.queryShopMaterialByIds(materialStoreIds);// erp-shop-material + Map materialStoreMap = materialByIds.stream() + .distinct().collect(Collectors.toMap(map -> { + Map shopMaterialStore = JSONUtil.toBean(map.get("shopMaterialStore").toString(), null); + return shopMaterialStore.get("id").toString(); + }, map -> { + Map shopMaterialStore = JSONUtil.toBean(map.get("shopMaterialStore").toString(), null); + return shopMaterialStore.get("storeId").toString(); + })); + for (OrderItem orderItem : order.getOrderItemList()) { + orderItem.setCommentState(WhetherEnum.DISABLE_USING.getKey()); + orderItem.setParentId(order.getId()); + orderItem.setStoreId(materialStoreMap.containsKey(orderItem.getMaterialStoreId()) ? materialStoreMap.get(orderItem.getMaterialStoreId()) : ""); + } + super.createEntity(order.getOrderItemList(), userId); + } + + @Override + public void updateCommentStateById(String id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id) + .set(MybatisPlusUtil.toColumns(OrderItem::getCommentState), WhetherEnum.ENABLE_USING.getKey()); + update(updateWrapper); + } + + @Override + public List queryOrderItemByParentId(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(OrderItem::getParentId), orderId); + return list(queryWrapper); + } + + @Override + public void UpdateOrderItemState(String orderItemId) { + OrderItem orderItem = selectById(orderItemId); + if (orderItem.getOrderItemState()==CommonNumConstants.NUM_TWO) { + throw new CustomException("该订单已收货"); + } + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, orderItemId); + updateWrapper.set(MybatisPlusUtil.toColumns(OrderItem::getOrderItemState), CommonNumConstants.NUM_TWO); + update(updateWrapper); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..320bbcb --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/order/service/impl/OrderServiceImpl.java @@ -0,0 +1,644 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.order.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.QuartzConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.coupon.entity.CouponUse; +import com.skyeye.coupon.entity.CouponUseMaterial; +import com.skyeye.coupon.enums.CouponUseState; +import com.skyeye.coupon.enums.PromotionDiscountType; +import com.skyeye.coupon.enums.PromotionMaterialScope; +import com.skyeye.coupon.service.CouponUseMaterialService; +import com.skyeye.coupon.service.CouponUseService; +import com.skyeye.eve.rest.quartz.SysQuartzMation; +import com.skyeye.eve.service.IAreaService; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.exception.CustomException; +import com.skyeye.order.config.PayProperties; +import com.skyeye.order.dao.OrderDao; +import com.skyeye.order.entity.Order; +import com.skyeye.order.entity.OrderItem; +import com.skyeye.order.enums.ShopOrderCancelType; +import com.skyeye.order.enums.ShopOrderCommentState; +import com.skyeye.order.enums.ShopOrderItemState; +import com.skyeye.order.enums.ShopOrderState; +import com.skyeye.order.service.OrderItemService; +import com.skyeye.order.service.OrderService; +import com.skyeye.rest.pay.service.IPayService; +import com.skyeye.rest.shopmaterialnorms.sevice.IShopMaterialNormsService; +import com.skyeye.store.entity.ShopAddress; +import com.skyeye.store.service.ShopAddressService; +import com.skyeye.store.service.ShopTradeCartService; +import com.skyeye.xxljob.ShopXxlJob; +import com.xxl.job.core.util.IpUtil; +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 java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: OrderServiceImpl + * @Description: 商品订单管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/9/8 10:39 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "商品订单管理", groupName = "商品订单管理") +public class OrderServiceImpl extends SkyeyeBusinessServiceImpl implements OrderService { + + @Autowired + private OrderItemService orderItemService; + + @Autowired + private IAreaService iAreaService; + + @Autowired + private IShopMaterialNormsService iShopMaterialNormsService; + + @Autowired + private CouponUseService couponUseService; + + @Autowired + private IPayService iPayService; + + @Autowired + private ShopAddressService shopAddressService; + + @Autowired + private PayProperties payProperties; + + @Autowired + private CouponUseMaterialService couponUseMaterialService; + + @Autowired + private IQuartzService iQuartzService; + + @Autowired + private ShopTradeCartService shopTradeCartService; + + private static Logger log = LoggerFactory.getLogger(ShopXxlJob.class); + + @Override + public void createPrepose(Order order) { + if (order == null&& ObjUtil.isEmpty(order)) { + throw new CustomException("订单对象不能为空"); + } + // 订单编号 + Map business = BeanUtil.beanToMap(order); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getClass().getName(), business); + order.setOddNumber(oddNumber); + order.setCount(CommonNumConstants.NUM_ZERO);// 商品总数 + order.setCommentState(ShopOrderCommentState.UNFINISHED.getKey());// 评价状态 + order.setTotalPrice("0"); + order.setDiscountPrice("0"); + order.setDeliveryPrice("0"); + order.setPayPrice("0"); + // 收货人信息 + ShopAddress shopAddress = shopAddressService.selectById(order.getAddressId()); + order.setReceiverName(shopAddress.getName()); + order.setReceiverMobile(shopAddress.getMobile()); + // 调价 + order.setAdjustPrice("0"); + // 子单的优惠券操作 + checkAndSetItemCouponUse(order); + // ip + order.setUserIp(IpUtil.getLocalAddress().toString()); + order.setState(ShopOrderState.UNPAID.getKey()); + // 物流联通后,此项需要修改 + checkAndSetDeliveryPrice(order); + // 积分操作方法, 此方法未进行任何操作,可对此方法进行任何操作 + checkAndSetVariable(order); + // 活动信息及积分操作方法 + checkAndSetActive(order); + } + + private void checkAndSetItemCouponUse(Order order) {// 子单的优惠券操作 + List orderItemList = order.getOrderItemList(); + if (orderItemList == null || orderItemList.isEmpty()) { + throw new CustomException("订单子项列表不能为空"); + } + // 设置商品信息、商品规格信息和优惠券信息 + List normsIdList = orderItemList.stream().map(OrderItem::getNormsId).collect(Collectors.toList()); + List> normsListMap = iShopMaterialNormsService.queryShopMaterialByNormsIdList(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIdList)); + Map normsPriceMap = normsListMap.stream() + .collect(Collectors.toMap(map -> map.get("normsId").toString(), map -> map.get("salePrice").toString())); + for (OrderItem orderItem : orderItemList) {// 计算每一个子单的总价 + if (!normsPriceMap.containsKey(orderItem.getNormsId())) { + throw new CustomException("商城不存在normsId: " + orderItem.getNormsId()); + } + // 获取子单单价 元 -> 分 + String salePrice = CalculationUtil.multiply(normsPriceMap.get(orderItem.getNormsId()), "100"); + // 设置子单总价 + String price = CalculationUtil.multiply(String.valueOf(orderItem.getCount()), salePrice, CommonNumConstants.NUM_SIX); + orderItem.setPrice(price); + orderItem.setPayPrice(price); + orderItem.setDiscountPrice("0"); + // 总单商品数量、子单状态、总单原价、总单应付金额 + order.setCount(order.getCount() + orderItem.getCount()); + orderItem.setCommentState(ShopOrderCommentState.UNFINISHED.getKey()); + order.setTotalPrice(CalculationUtil.add(order.getTotalPrice(), orderItem.getPrice(), CommonNumConstants.NUM_SIX)); + order.setPayPrice(CalculationUtil.add(order.getPayPrice(), orderItem.getPayPrice(), CommonNumConstants.NUM_SIX)); + } + checkCouponUseMaterial(order);// 将总单的couponUserId赋值到对应子单 + } + + private void checkAndSetDeliveryPrice(Order order) { + order.setDeliveryPrice(StrUtil.isEmpty(order.getDeliveryPrice()) ? "0" : order.getDeliveryPrice()); + } + + private void checkAndSetVariable(Order order) { + } + + private void checkAndSetActive(Order order) { + } + + private void checkCouponUseMaterial(Order order) { + String couponUseId = order.getCouponUseId();//优惠券id + double totalPrice = Double.parseDouble(order.getTotalPrice());//总单原价 + if (StrUtil.isEmpty(couponUseId)) {//没有使用优惠券 + return; + } + CouponUse couponUse = couponUseService.selectById(couponUseId);//优惠券信息 + if (ObjectUtil.isEmpty(couponUse)) { + throw new CustomException("优惠券不存在"); + } else if (couponUse.getState() != CouponUseState.UNUSED.getKey()) { + throw new CustomException("该优惠券已使用或已过期"); + } else if (Double.parseDouble(couponUse.getUsePrice()) > totalPrice) { + throw new CustomException("优惠券不满足使用金额"); + } + List orderItemList = order.getOrderItemList();//子单列表 + OrderItem orderItem = null;//优惠券使用商品 + if (Objects.equals(couponUse.getProductScope(), PromotionMaterialScope.ALL.getKey())) {// 全部商品 + orderItem = orderItemList.stream().max(Comparator.comparing(OrderItem::getPrice)).orElse(null);// 获取优惠券使用商品列表中,价格最高的商品 + setOrderAndOrderItem(couponUse, order, orderItem);// 操作订单和子单的优惠券 + } else if (Objects.equals(couponUse.getProductScope(), PromotionMaterialScope.SPU.getKey())) {// 指定商品 + List couponUseMaterialIds = couponUseMaterialService.queryListByCouponIds(Collections.singletonList(couponUseId)) + .stream().map(CouponUseMaterial::getMaterialId).collect(Collectors.toList());// 收集子单商品id + List newOrderItemList = new ArrayList<>(); + for (OrderItem item : orderItemList) {// 筛选出优惠券可用的商品 + if (couponUseMaterialIds.contains(item.getMaterialId())) { + newOrderItemList.add(item); + } + } + if (CollectionUtil.isEmpty(newOrderItemList)) { + throw new CustomException("商品列表不存在满足优惠券的使用对象"); + } + orderItem = newOrderItemList.stream().max(Comparator.comparing(OrderItem::getPrice)).orElse(null);// 获取优惠券使用商品列表中,价格最高的商品 + setOrderAndOrderItem(couponUse, order, orderItem);// 操作订单和子单的优惠券 + } + } + + private void setOrderAndOrderItem(CouponUse couponUse, Order order, OrderItem targetOrderItem) { + if (targetOrderItem == null) { + throw new CustomException("目标订单子项不能为空"); + } + if (Objects.equals(couponUse.getDiscountType(), PromotionDiscountType.PERCENT.getKey())) {// 百分比折扣 + for (OrderItem item : order.getOrderItemList()) {// 找到目标子单 + if (item.getNormsId().equals(targetOrderItem.getNormsId())) { + item.setCouponUseId(order.getCouponUseId()); + couponUseService.UpdateUsedCount(order.getCouponUseId());// 修改优惠券使用次数 + // 操作优惠券 + String discountPercentInt = CalculationUtil.divide(couponUse.getDiscountPercent().toString(), "100", CommonNumConstants.NUM_SIX); + // 百分比的折后价 + String percentPrice = CalculationUtil.multiply(targetOrderItem.getPrice(), discountPercentInt, CommonNumConstants.NUM_SIX); + // 百分比折扣的优惠价格 + String percentDiscountPrice = CalculationUtil.subtract(targetOrderItem.getPrice(), percentPrice, CommonNumConstants.NUM_SIX); + // 折扣上限 + String discountLimitPrice = couponUse.getDiscountLimitPrice(); + // 折扣上限的折后价 + String limitPrice = CalculationUtil.subtract(targetOrderItem.getPrice(), discountLimitPrice, CommonNumConstants.NUM_SIX); + // 是否超过折扣上限 + String highPrice = CalculationUtil.getMax(percentDiscountPrice, discountLimitPrice, CommonNumConstants.NUM_SIX); + // 设置应支付价格和优惠价格 + if (Double.parseDouble(highPrice) == Double.parseDouble(discountLimitPrice)) { // 未超过优惠价 + item.setPayPrice(percentPrice); + item.setCouponPrice(percentDiscountPrice); + // 修改总单总价 + order.setPayPrice(CalculationUtil.subtract(order.getPayPrice(), percentDiscountPrice, CommonNumConstants.NUM_SIX)); + order.setCouponPrice(percentDiscountPrice); + } else {// 超过优惠价 + item.setPayPrice(limitPrice); + item.setCouponPrice(discountLimitPrice); + // 修改总单总价 + order.setPayPrice(CalculationUtil.subtract(order.getPayPrice(), discountLimitPrice, CommonNumConstants.NUM_SIX)); + order.setCouponPrice(discountLimitPrice); + } + break; + } + } + } else {// 满减 直接在总单减去价格,子单不做处理 + couponUseService.UpdateUsedCount(order.getCouponUseId());// 修改优惠券使用次数 + String discountPrice = couponUse.getDiscountPrice(); + // 折后价 + String afterPrice = CalculationUtil.subtract(order.getTotalPrice(), discountPrice, CommonNumConstants.NUM_SIX); + order.setPayPrice(afterPrice); + order.setCouponPrice(discountPrice); + } + } + + @Override + public void createPostpose(Order order, String userId) { + orderItemService.setValueAndCreateEntity(order, userId); + couponUseService.updateState(order.getCouponUseId());// 更新用户领取的优惠券状态 + log.info("订单id:"+order.getId()+"创建定时任务-- 开始"); + startUpTaskQuartz(order.getId(), order.getOddNumber(), DateUtil.getTimeAndToString()); + log.info("订单id:"+order.getId()+"创建定时任务-- 结束"); + shopTradeCartService.deleteMySelect(userId); + } + + private void startUpTaskQuartz(String name, String title, String delayedTime) { + /// 处理日期 此处delayedTime为当前日期 + Date stringToDate = DateUtil.getPointTime(delayedTime, DateUtil.YYYY_MM_DD_HH_MM_SS); + Date afterOneDay = DateUtil.getAfDate(stringToDate, 1, "d"); + DateFormat df = new SimpleDateFormat(DateUtil.YYYY_MM_DD_HH_MM_SS); + String lastTime = df.format(afterOneDay); + // 正式准备启动定时任务 + SysQuartzMation sysQuartzMation = new SysQuartzMation(); + sysQuartzMation.setName(name); + sysQuartzMation.setTitle(title); + sysQuartzMation.setDelayedTime(lastTime); + sysQuartzMation.setGroupId(QuartzConstants.QuartzMateMationJobType.SHOP_ORDER_CREATE.getTaskType()); + iQuartzService.startUpTaskQuartz(sysQuartzMation); + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List stateList = new ArrayList<>(); + switch (commonPageInfo.getType()) { + case "1": // 未支付 + stateList = Arrays.asList(new Integer[]{ShopOrderState.UNPAID.getKey()}); + break; + case "2": // 待收货 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.UNDELIVERED.getKey(),// 待发货 + ShopOrderState.DELIVERED.getKey(), // 已发货 + ShopOrderState.TRANSPORTING.getKey()});//运输中 + break; + case "3":// 已完成 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.SIGN.getKey(), // 已签收 + ShopOrderState.COMPLETED.getKey(), // 已完成 + ShopOrderState.UNEVALUATE.getKey(), // 待评价 + ShopOrderState.EVALUATED.getKey(),// 已评价 + ShopOrderState.PARTIALLYDONE.getKey(),//部分完成 + ShopOrderState.PARTIALEVALUATION.getKey()});//部分评价 + break; + case "4":// 已取消 + stateList = Arrays.asList(new Integer[]{ShopOrderState.CANCELED.getKey()}); + break; + case "5":// 处理中 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.REFUNDING.getKey(), // 退款中 + ShopOrderState.SALESRETURNING.getKey(),//退货中 + ShopOrderState.EXCHANGEING.getKey()});//换货中 + break; + case "6": // 申请记录 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.REFUND.getKey(), // 已退款 + ShopOrderState.SALESRETURNED.getKey(),//已退货 + ShopOrderState.EXCHANGED.getKey()});//已换货 + } + QueryWrapper wrapper = super.getQueryWrapper(commonPageInfo); + if (CollectionUtil.isNotEmpty(stateList)) { // 状态列表为空时,则查询全部订单 + wrapper.in(MybatisPlusUtil.toColumns(Order::getState), stateList); + } + wrapper.orderByDesc(MybatisPlusUtil.toColumns(Order::getCreateTime)); + List list = list(wrapper); + if (CollectionUtil.isEmpty(list)) { + return CollectionUtil.newArrayList(); + } + List idList = list.stream().map(Order::getId).collect(Collectors.toList()); + Map> mapByIds = orderItemService.queryListByParentId(idList); + for (Order order : list) { + order.setOrderItemList(mapByIds.containsKey(order.getId()) ? mapByIds.get(order.getId()) : new ArrayList<>()); + } + iAreaService.setDataMation(list, Order::getProvinceId); + iAreaService.setDataMation(list, Order::getCityId); + iAreaService.setDataMation(list, Order::getAreaId); + iAreaService.setDataMation(list, Order::getTownshipId); + shopAddressService.setDataMation(list, Order::getAddressId); + // 分页查询时获取数据 + return JSONUtil.toList(JSONUtil.toJsonStr(list), null); + } + + @Override + public void queryOrderPageList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + List stateList = new ArrayList<>(); + switch (StrUtil.isEmpty(commonPageInfo.getType()) ? "0" : commonPageInfo.getType()) { + // todo 未提交、已提交和支付失败三个枚举未现 + case "1": // 未支付 + stateList = Arrays.asList(new Integer[]{ShopOrderState.UNPAID.getKey()}); + break; + case "2": // 待收货 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.UNDELIVERED.getKey(),// 待发货 + ShopOrderState.DELIVERED.getKey(), // 已发货 + ShopOrderState.TRANSPORTING.getKey()});//运输中 + break; + case "3":// 已完成 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.SIGN.getKey(), // 已签收 + ShopOrderState.COMPLETED.getKey(), // 已完成 + ShopOrderState.UNEVALUATE.getKey(), // 待评价 + ShopOrderState.EVALUATED.getKey(),// 已评价 + ShopOrderState.PARTIALLYDONE.getKey(),//部分完成 + ShopOrderState.PARTIALEVALUATION.getKey()});//部分评价 + break; + case "4":// 已取消 + stateList = Arrays.asList(new Integer[]{ShopOrderState.CANCELED.getKey()}); + break; + case "5":// 处理中 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.REFUNDING.getKey(), // 退款中 + ShopOrderState.SALESRETURNING.getKey(),//退货中 + ShopOrderState.EXCHANGEING.getKey()});//换货中 + break; + case "6": // 申请记录 + stateList = Arrays.asList(new Integer[]{ + ShopOrderState.REFUND.getKey(), // 已退款 + ShopOrderState.SALESRETURNED.getKey(),//已退货 + ShopOrderState.EXCHANGED.getKey()});//已换货 + } + QueryWrapper wrapper = new QueryWrapper<>(); + if (CollectionUtil.isNotEmpty(stateList)) { // 状态列表为空时,则查询全部订单 + wrapper.in(MybatisPlusUtil.toColumns(Order::getState), stateList); + } + String userId = InputObject.getLogParamsStatic().get("id").toString(); + wrapper.eq(MybatisPlusUtil.toColumns(Order::getCreateId), userId);// 查询自己的订单 + wrapper.orderByDesc(MybatisPlusUtil.toColumns(Order::getCreateTime)); + List list = list(wrapper); + if (CollectionUtil.isEmpty(list)) { + return; + } + List idList = list.stream().map(Order::getId).collect(Collectors.toList()); + Map> mapByIds = orderItemService.queryListByParentId(idList); + for (Order order : list) { + order.setOrderItemList(mapByIds.containsKey(order.getId()) ? mapByIds.get(order.getId()) : new ArrayList<>()); + } + iAreaService.setDataMation(list, Order::getProvinceId); + iAreaService.setDataMation(list, Order::getCityId); + iAreaService.setDataMation(list, Order::getAreaId); + iAreaService.setDataMation(list, Order::getTownshipId); + shopAddressService.setDataMation(list, Order::getAddressId); + outputObject.setBeans(JSONUtil.toList(JSONUtil.toJsonStr(list), null)); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void changeOrderAdjustPrice(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + int adjustPrice = Integer.parseInt(params.get("adjustPrice").toString()); + if (adjustPrice < CommonNumConstants.NUM_ZERO) { + throw new CustomException("所调价格不可为负数"); + } + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, params.get("id").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getAdjustPrice), adjustPrice); + update(updateWrapper); + refreshCache(params.get("id").toString()); + } + + @Override + public void updateOrderToPayState(InputObject inputObject, OutputObject outputObject) { + String orderId = inputObject.getParams().get("id").toString(); + //获取订单当前状态 + Order order = selectById(orderId); + Integer state = order.getState(); + if(ShopOrderState.UNSUBMIT.getKey()==state|| + ShopOrderState.SUBMIT.getKey()==state|| + ShopOrderState.UNPAID.getKey()==state|| + ShopOrderState.FAIRPAID.getKey()==state|| + ShopOrderState.CANCELED.getKey()==state + ){ + throw new CustomException("不可修改"); + } + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, orderId); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.UNDELIVERED.getKey()); + refreshCache(orderId); + } + + @Override + public void deletePostpose(List ids) { + orderItemService.deleteByPerentIds(ids); + } + + @Override + public Order selectById(String id) { + Order order = super.selectById(id); + Map> orderItemList = orderItemService.queryListByParentId(Collections.singletonList(id)); + order.setOrderItemList(orderItemList.get(order.getId())); + iAreaService.setDataMation(order, Order::getProvinceId); + iAreaService.setDataMation(order, Order::getCityId); + iAreaService.setDataMation(order, Order::getAreaId); + iAreaService.setDataMation(order, Order::getTownshipId); + shopAddressService.setDataMation(order, Order::getAddressId); + refreshCache(id); + return order; + } + + @Override + public void cancelOrder(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, params.get("id")); + Order one = getOne(updateWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("订单不存在"); + } + // 可取消的订单状态:未提交(0)、已提交(1)、待支付(2)、待发货(5) + if (Objects.equals(one.getState(), ShopOrderState.UNSUBMIT.getKey()) || + Objects.equals(one.getState(), ShopOrderState.SUBMIT.getKey()) || + Objects.equals(one.getState(), ShopOrderState.UNPAID.getKey()) || + Objects.equals(one.getState(), ShopOrderState.UNDELIVERED.getKey())) { + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.CANCELED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getCancelType), params.get("cancelType")); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getCancelTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + log.info("订单id" + one.getId() + "取消订单--取消定时任务-- 开始"); + iQuartzService.stopAndDeleteTaskQuartz(one.getId());// 删除任务 + log.info("订单id" + one.getId() + "取消订单--取消定时任务-- 结束"); + refreshCache(params.get("id").toString()); + } else { + throw new CustomException("订单不可取消"); + } + } + + @Override + public void finishOrder(InputObject inputObject, OutputObject outputObject) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, inputObject.getParams().get("id")); + Order one = getOne(updateWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("订单不存在"); + } + List stateList = Arrays.asList(ShopOrderState.SIGN.getKey(), ShopOrderState.UNEVALUATE.getKey(), ShopOrderState.EVALUATED.getKey()); + if (stateList.contains(one.getState())) {// 处于签收、待评价、已评价状态时,才可以完成订单 + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.COMPLETED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getFinishTime), DateUtil.getTimeAndToString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getReceiveTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(one.getId()); + } else { + throw new CustomException("不可完成订单。"); + } + } + + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void payOrder(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String channelCode = params.get("channelCode").toString(); + String channelExtras = params.get("channelExtras").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, id); + Order one = getOne(queryWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("订单不存在"); + } + if (!Objects.equals(one.getState(), ShopOrderState.UNPAID.getKey())) { + throw new CustomException("该订单不可支付。"); + } + Map payRresult = iPayService.payment(BeanUtil.beanToMap(one), channelCode, "", channelExtras, payProperties.getOrderNotifyUrl()).getBean(); + Map payChannel = JSONUtil.toBean(payRresult.get("payChannel").toString(), null); + Map payOrderRespDTO = JSONUtil.toBean(payRresult.get("payOrderRespDTO").toString(), null); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.UNDELIVERED.getKey()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getPayType), channelCode); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getPayTime), payOrderRespDTO.get("successTime").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getChannelFeeRate), payChannel.get("feeRate").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getChannelFeePrice), CalculationUtil.multiply( + one.getPayPrice(), payChannel.get("feeRate").toString())); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getExtensionId), payOrderRespDTO.get("id").toString()); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getExtensionNo), payOrderRespDTO.get("no").toString()); + update(updateWrapper); + refreshCache(id); + log.info("订单id" + one.getId() + "支付成功--删除定时任务-- 开始"); + iQuartzService.stopAndDeleteTaskQuartz(id);// 删除定时任务 + log.info("订单id" + one.getId() + "支付成功--删除定时任务-- 结束"); + } + + @Override + public void deliverGoodsByOrderId(InputObject inputObject, OutputObject outputObject) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, inputObject.getParams().get("id")); + Order one = getOne(updateWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("订单不存在"); + } + if (!Objects.equals(one.getState(), ShopOrderState.UNDELIVERED.getKey())) { + throw new CustomException("该订单当前不可发货。"); + } + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.DELIVERED.getKey()); + update(updateWrapper); + refreshCache(one.getId()); + } + + @Override + public void updateCommonState(String id, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getCommentState), state); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void generatePayOrderRrCode(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + String channelCode = params.get("channelCode").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, id); + Order one = getOne(queryWrapper); + if (ObjectUtil.isEmpty(one)) { + throw new CustomException("订单不存在"); + } + if (!Objects.equals(one.getState(), ShopOrderState.UNPAID.getKey())) { + throw new CustomException("该订单不可支付。"); + } + Map qrCodeResult = iPayService.generatePayRrCode(BeanUtil.beanToMap(one), channelCode, IpUtil.getLocalAddress().toString(), payProperties.getOrderNotifyUrl()); + outputObject.setBean(qrCodeResult); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public void setOrderCancle(String orderId) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, orderId); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), ShopOrderState.CANCELED.getKey()) + .set(MybatisPlusUtil.toColumns(Order::getCancelType), ShopOrderCancelType.PAY_TIMEOUT.getKey()) + .set(MybatisPlusUtil.toColumns(Order::getCancelTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + refreshCache(orderId); + } + + @Override + public void updateOrderItemState(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String orderId = map.get("id").toString(); + String orderItemId = map.get("orderItemId").toString(); + orderItemService.UpdateOrderItemState(orderItemId); + List orderItemList = orderItemService.queryOrderItemByParentId(orderId); + boolean allTwo = orderItemList.stream().map(OrderItem::getOrderItemState) + .allMatch(orderItemState -> orderItemState == ShopOrderItemState.FINISHED.getKey()); + if (allTwo) { + updateOrderState(orderId, ShopOrderState.COMPLETED.getKey()); + } else { + updateOrderState(orderId, ShopOrderState.PARTIALLYDONE.getKey()); + } + } + + @Override + public void updateOrderState(String orderId, Integer partiallydoneKey) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, orderId); + updateWrapper.set(MybatisPlusUtil.toColumns(Order::getState), partiallydoneKey); + update(updateWrapper); + } + + @Override + public List queryOrderList(String orderId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Order::getId),orderId); + return list(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressController.java new file mode 100644 index 0000000..43f8964 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressController.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopAddress; +import com.skyeye.store.service.ShopAddressService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopAddressController + * @Description: 收件地址管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "收件地址管理", tags = "收件地址管理", modelName = "收件地址管理") +public class ShopAddressController { + + @Autowired + private ShopAddressService shopAddressService; + + /** + * 新增/编辑收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeShopAddress", value = "新增/编辑收件地址信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopAddress.class) + @RequestMapping("/post/ShopAddressController/writeShopAddress") + public void writeShopAddress(InputObject inputObject, OutputObject outputObject) { + shopAddressService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShopAddressByIds", value = "批量删除收件地址信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/ShopAddressController/deleteShopAddressByIds") + public void deleteShopAddressByIds(InputObject inputObject, OutputObject outputObject) { + shopAddressService.deleteByIds(inputObject, outputObject); + } + + /** + * 根据id查询收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectShopAddressById", value = "根据id查询收件地址信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopAddressController/selectShopAddressById") + public void selectShopAddressByIds(InputObject inputObject, OutputObject outputObject) { + shopAddressService.selectById(inputObject, outputObject); + } + + /** + * 获取收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyShopAddress", value = "获取收件地址信息", method = "POST", allUse = "2") + @RequestMapping("/post/ShopAddressController/queryMyShopAddress") + public void queryMyShopAddress(InputObject inputObject, OutputObject outputObject) { + shopAddressService.queryList(inputObject, outputObject); + } + + /** + * 获取默认收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryDefaultShopAddress", value = "获取默认收件地址信息", method = "POST", allUse = "2") + @RequestMapping("/post/ShopAddressController/queryDefaultShopAddress") + public void queryDefaultShopAddress(InputObject inputObject, OutputObject outputObject) { + shopAddressService.queryDefaultShopAddress(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressLabelController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressLabelController.java new file mode 100644 index 0000000..7fbad4c --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopAddressLabelController.java @@ -0,0 +1,50 @@ +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopAddressLabel; +import com.skyeye.store.service.ShopAddressLabelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Api(value = "收件地址标签管理", tags = "收件地址标签管理", modelName = "收件地址标签管理") +public class ShopAddressLabelController { + + @Autowired + private ShopAddressLabelService shopAddressLabelService; + + @ApiOperation(id = "writeShopAddressLabel", value = "新增/编辑收件地址标签信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopAddressLabel.class) + @RequestMapping("/post/ShopAddressLabelController/writeShopAddressLabel") + public void writeShopAddressLabel(InputObject inputObject, OutputObject outputObject) { + shopAddressLabelService.saveOrUpdateEntity(inputObject, outputObject); + } + + @ApiOperation(id = "deleteShopAddressLabelByIds", value = "批量删除收件地址标签信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/ShopAddressLabelController/deleteShopAddressLabelByIds") + public void deleteShopAddressLabelByIds(InputObject inputObject, OutputObject outputObject) { + shopAddressLabelService.deleteByIds(inputObject, outputObject); + } + + @ApiOperation(id = "queryShopAddressLabelList", value = "获取自己的收件地址标签信息", method = "POST", allUse = "2") + @RequestMapping("/post/ShopAddressLabelController/queryShopAddressLabelList") + public void queryShopAddressLabelList(InputObject inputObject, OutputObject outputObject) { + shopAddressLabelService.queryList(inputObject, outputObject); + } + @ApiOperation(id = "selectShopAddressLabelById", value = "根据id查询收件地址标签信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopAddressLabelController/selectShopAddressLabelById") + public void selectShopAddressLabelById(InputObject inputObject, OutputObject outputObject) { + shopAddressLabelService.selectById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopTradeCartController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopTradeCartController.java new file mode 100644 index 0000000..66203e7 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/ShopTradeCartController.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopTradeCart; +import com.skyeye.store.service.ShopTradeCartService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: ShopAreaController + * @Description: 购物车管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "购物车管理", tags = "购物车管理", modelName = "购物车管理") +public class ShopTradeCartController { + + @Autowired + private ShopTradeCartService shopTradeCartService; + + /** + * 获取购物车信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryShopTradeCartList", value = "根据状态获取购物车信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "selected", name = "selected", value = "选中状态,参考#WhetherEnum")}) + @RequestMapping("/post/ShopTradeCartController/queryShopTradeCartList") + public void queryShopTradeCartList(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.queryShopTradeCartList(inputObject, outputObject); + } + + /** + * 新增购物车信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertShopTradeCart", value = "新增购物车信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = ShopTradeCart.class) + @RequestMapping("/post/ShopTradeCartController/insertShopTradeCart") + public void insertShopTradeCart(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.createEntity(inputObject, outputObject); + } + + /** + * 批量删除购物车信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteShopTradCartByIds", value = "批量删除购物车信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号隔开", required = "required")}) + @RequestMapping("/post/ShopTradeCartController/deleteShopTradCartByIds") + public void deleteShopTradCartByIds(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.deleteByIds(inputObject, outputObject); + } + + /** + * 更新购物车商品数量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "changeCount", value = "更新购物车商品数量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "sign", name = "sign", value = "修改标志0为减少,1为增加", required = "required")}) + @RequestMapping("/post/ShopTradeCartController/changeCount") + public void changeCount(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.changeCount(inputObject, outputObject); + } + + /** + * 更新购物车商品选中 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "changeSelected", value = "更新购物车商品选中", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/ShopTradeCartController/changeSelected") + public void changeSelected(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.changeSelected(inputObject, outputObject); + } + + /** + * 批量更新购物车商品选中/不选中 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "batchChangeSelectedStatus", value = "批量更新购物车商品选中/不选中", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id,多个id用逗号隔开", required = "required"), + @ApiImplicitParam(id = "selected", name = "selected", value = "状态,参考#WhetherEnum", required = "required,num")}) + @RequestMapping("/post/ShopTradeCartController/batchChangeSelectedStatus") + public void batchChangeSelectedStatus(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.batchChangeSelectedStatus(inputObject, outputObject); + } + + /** + * 重置购物车信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "resetShopTradeCart", value = "重置购物车信息", method = "POST", allUse = "2") + @RequestMapping("/post/ShopTradeCartController/resetShopTradeCart") + public void resetShopTradeCart(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.resetShopTradeCart(inputObject, outputObject); + } + + /** + * 计算购物车总价 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "calculateTotalPrices", value = "计算购物车总价", method = "POST", allUse = "2") + @RequestMapping("/post/ShopTradeCartController/calculateTotalPrices") + public void calculateTotalPrices(InputObject inputObject, OutputObject outputObject) { + shopTradeCartService.calculateTotalPrices(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/StoreIntercourseController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/StoreIntercourseController.java new file mode 100644 index 0000000..4837ae0 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/controller/StoreIntercourseController.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.entity.intercourse.StoreIntercourseQueryDo; +import com.skyeye.store.service.StoreIntercourseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: StoreIntercourseController + * @Description: 门店往来管理 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/10 21:53 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店往来管理", tags = "门店往来管理", modelName = "商城模块") +public class StoreIntercourseController { + + @Autowired + private StoreIntercourseService storeIntercourseService; + + /** + * 获取指定门店的支出/收入往来的数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStoreIntercourseList", value = "获取指定门店的支出/收入往来的数据", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = StoreIntercourseQueryDo.class) + @RequestMapping("/post/StoreIntercourseController/queryStoreIntercourseList") + public void queryStoreIntercourseList(InputObject inputObject, OutputObject outputObject) { + storeIntercourseService.queryStoreIntercourseList(inputObject, outputObject); + } + + /** + * 编辑指定门店的支出/收入往来的状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editStoreIntercourseState", value = "编辑指定门店的支出/收入往来的状态", method = "PUT", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "往来数据id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "状态 1.待套餐购买门店确认 2.待保养门店确认 3.已确认", required = "required,num")}) + @RequestMapping("/post/StoreIntercourseController/editStoreIntercourseState") + public void editStoreIntercourseState(InputObject inputObject, OutputObject outputObject) { + storeIntercourseService.editStoreIntercourseState(inputObject, outputObject); + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressDao.java new file mode 100644 index 0000000..45f0743 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.store.entity.ShopAddress; + +/** + * @ClassName: ShopAddressDao + * @Description: 收件地址管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopAddressDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressLabelDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressLabelDao.java new file mode 100644 index 0000000..2b36ea0 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopAddressLabelDao.java @@ -0,0 +1,7 @@ +package com.skyeye.store.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.store.entity.ShopAddressLabel; + +public interface ShopAddressLabelDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopTradeCartDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopTradeCartDao.java new file mode 100644 index 0000000..19718fd --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/ShopTradeCartDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.store.entity.ShopTradeCart; + +/** + * @ClassName: ShopTradeCartDao + * @Description: 购物车管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopTradeCartDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/StoreIntercourseDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/StoreIntercourseDao.java new file mode 100644 index 0000000..206fab6 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/dao/StoreIntercourseDao.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.dao; + +import com.skyeye.entity.intercourse.StoreIntercourseQueryDo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StoreIntercourseDao + * @Description: 门店往来管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/10 21:54 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StoreIntercourseDao { + + List> queryStoreIntercourseByDay(@Param("day") String day); + + void insertStoreIntercourse(List> shopStoreIntercourseMationList); + + List> queryStoreIntercourseList(StoreIntercourseQueryDo storeIntercourseQuery); + + Map queryStoreIntercourseById(@Param("id") String id); + + void editStoreIntercourseState(@Param("id") String id, @Param("state") Integer state); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddress.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddress.java new file mode 100644 index 0000000..20f84ac --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddress.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.AreaInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ShopAddress + * @Description: 收件地址实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "shop:address", cacheTime = RedisConstants.THIRTY_DAY_SECONDS) +@TableName(value = "shop_address") +@ApiModel("收件地址管理实体类") +public class ShopAddress extends AreaInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("name") + @ApiModelProperty(value = "收件人名称", required = "required") + private String name; + + @TableField("mobile") + @ApiModelProperty(value = "手机号", required = "required") + private String mobile; + + @TableField(value = "label_id") + @ApiModelProperty(value = "地址标签id") + private String labelId; + + @TableField(exist = false) + @Property(value = "地址标签id") + private Map labelMation; + + @TableField("is_default") + @ApiModelProperty(value = "是否是默认地址", required = "required,num", enumClass = WhetherEnum.class) + private Integer isDefault; +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddressLabel.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddressLabel.java new file mode 100644 index 0000000..47507a8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopAddressLabel.java @@ -0,0 +1,23 @@ +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +@Data +@TableName(value = "shop_address_label") +@ApiModel("收件地址标签管理实体类") +public class ShopAddressLabel extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("content") + @ApiModelProperty(value = "标签内容", required = "required", fuzzyLike = true) + private String content; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopTradeCart.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopTradeCart.java new file mode 100644 index 0000000..a2e04a3 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/entity/ShopTradeCart.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ShopTradeCart + * @Description: 品牌管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:12 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_trade_cart") +@ApiModel("购物车管理实体类") +public class ShopTradeCart extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("store_id") + @ApiModelProperty(value = "门店id", required = "required") + private String storeId; + + @TableField(exist = false) + @ApiModelProperty(value = "门店信息") + private Map storeMation; + + @TableField("material_id") + @ApiModelProperty(value = "商品id", required = "required") + private String materialId; + + @TableField(exist = false) + @ApiModelProperty(value = "商品信息") + private Map materialMation; + + @TableField(exist = false) + @ApiModelProperty(value = "商城商品信息") + private Map shopMaterialMation; + + @TableField("norms_id") + @ApiModelProperty(value = "规格id", required = "required") + private String normsId; + + @TableField(exist = false) + @ApiModelProperty(value = "規格信息") + private Map normsMation; + + @TableField("count") + @ApiModelProperty(value = "数量", required = "required") + private Integer count; + + @TableField("selected") + @ApiModelProperty(value = "是否选中", required = "required,num", enumClass = WhetherEnum.class) + private Integer selected; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressLabelService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressLabelService.java new file mode 100644 index 0000000..66a96ae --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressLabelService.java @@ -0,0 +1,7 @@ +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.store.entity.ShopAddressLabel; + +public interface ShopAddressLabelService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressService.java new file mode 100644 index 0000000..30cbe32 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopAddressService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopAddress; + +/** + * @ClassName: ShopAddressService + * @Description: 收件地址管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopAddressService extends SkyeyeBusinessService { + void queryDefaultShopAddress(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopTradeCartService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopTradeCartService.java new file mode 100644 index 0000000..a49d1ef --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/ShopTradeCartService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.store.entity.ShopTradeCart; + +/** + * @ClassName: ShopTradeCartService + * @Description: 购物车管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ShopTradeCartService extends SkyeyeBusinessService { + void changeSelected(InputObject inputObject, OutputObject outputObject); + + void changeCount(InputObject inputObject, OutputObject outputObject); + + void resetShopTradeCart(InputObject inputObject, OutputObject outputObject); + + void calculateTotalPrices(InputObject inputObject, OutputObject outputObject); + + void queryShopTradeCartList(InputObject inputObject, OutputObject outputObject); + + void batchChangeSelectedStatus(InputObject inputObject, OutputObject outputObject); + + void deleteMySelect(String userId); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/StoreIntercourseService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/StoreIntercourseService.java new file mode 100644 index 0000000..45a63bf --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/StoreIntercourseService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service; + +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StoreIntercourseService + * @Description: 门店往来管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/10 21:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StoreIntercourseService { + + List> queryStoreIntercourseByDay(String day); + + void insertStoreIntercourse(List> shopStoreIntercourseMationList); + + void queryStoreIntercourseList(InputObject inputObject, OutputObject outputObject); + + void editStoreIntercourseState(InputObject inputObject, OutputObject outputObject); + + List> queryStoreIntercourseListByDay(String day); +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressLabelServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressLabelServiceImpl.java new file mode 100644 index 0000000..37dba71 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressLabelServiceImpl.java @@ -0,0 +1,49 @@ +package com.skyeye.store.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.store.dao.ShopAddressLabelDao; +import com.skyeye.store.entity.ShopAddressLabel; +import com.skyeye.store.service.ShopAddressLabelService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +@SkyeyeService(name = "收件地址标签管理", groupName = "收件地址标签管理") +public class ShopAddressLabelServiceImpl extends SkyeyeBusinessServiceImpl implements ShopAddressLabelService { + + @Override + public void validatorEntity(ShopAddressLabel shopAddressLabel) { + super.validatorEntity(shopAddressLabel); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + //更新时排除本身 + if (StrUtil.isNotEmpty(shopAddressLabel.getId())) { + queryWrapper.ne(CommonConstants.ID, shopAddressLabel.getId()); + } + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopAddressLabel::getCreateId), userId); + List list = list(queryWrapper); + //排除重复的标签 + for (ShopAddressLabel addressLabel : list) { + if (addressLabel.getContent().equals(shopAddressLabel.getContent())) { + throw new RuntimeException("标签重复"); + } + } + } + + @Override + public List> queryDataList(InputObject inputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopAddressLabel::getCreateId), inputObject.getLogParams().get("id").toString()); + List list = list(queryWrapper); + return JSONUtil.toList(JSONUtil.toJsonStr(list), null); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressServiceImpl.java new file mode 100644 index 0000000..a9fa4c5 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopAddressServiceImpl.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.service.IAreaService; +import com.skyeye.store.dao.ShopAddressDao; +import com.skyeye.store.entity.ShopAddress; +import com.skyeye.store.entity.ShopAddressLabel; +import com.skyeye.store.service.ShopAddressLabelService; +import com.skyeye.store.service.ShopAddressService; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopAddressServiceImpl + * @Description: 收件地址管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "收件地址管理", groupName = "收件地址管理") +public class ShopAddressServiceImpl extends SkyeyeBusinessServiceImpl implements ShopAddressService { + + @Autowired + private IAreaService iAreaService; + + @Autowired + private ShopAddressLabelService shopAddressLabelService; + + @Override + public void writePostpose(ShopAddress shopAddress, String userId) { + if (WhetherEnum.ENABLE_USING.getKey().equals(shopAddress.getIsDefault())) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.ne(CommonConstants.ID, shopAddress.getId()); + updateWrapper.eq(MybatisPlusUtil.toColumns(ShopAddress::getCreateId), userId); + updateWrapper.eq(MybatisPlusUtil.toColumns(ShopAddress::getIsDefault), WhetherEnum.ENABLE_USING.getKey()); + ShopAddress one = getOne(updateWrapper); + if (ObjectUtil.isEmpty(one)) { + return; + } + updateWrapper.set(MybatisPlusUtil.toColumns(ShopAddress::getIsDefault), WhetherEnum.DISABLE_USING.getKey()); + update(updateWrapper); + refreshCache(one.getId()); + } + } + + @Override + public ShopAddress selectById(String id) { + ShopAddress shopAddress = super.selectById(id); + iAreaService.setDataMation(shopAddress, ShopAddress::getProvinceId); + iAreaService.setDataMation(shopAddress, ShopAddress::getCityId); + iAreaService.setDataMation(shopAddress, ShopAddress::getAreaId); + iAreaService.setDataMation(shopAddress, ShopAddress::getTownshipId); + shopAddressLabelService.setDataMation(shopAddress, ShopAddress::getLabelId); + return shopAddress; + } + @Override + public void queryDefaultShopAddress(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopAddress::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopAddress::getIsDefault), WhetherEnum.ENABLE_USING.getKey()); + ShopAddress one = getOne(queryWrapper); + if (ObjectUtil.isEmpty(one)) { + return; + } + iAreaService.setDataMation(one, ShopAddress::getProvinceId); + iAreaService.setDataMation(one, ShopAddress::getCityId); + iAreaService.setDataMation(one, ShopAddress::getAreaId); + iAreaService.setDataMation(one, ShopAddress::getTownshipId); + shopAddressLabelService.setDataMation(one, ShopAddress::getLabelId); + outputObject.setBean(one); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + @Override + public List> queryDataList(InputObject inputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopAddress::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(ShopAddress::getCreateTime)); + List list = list(queryWrapper); + if (CollectionUtil.isEmpty(list)) { + return new ArrayList<>(); + } + iAreaService.setDataMation(list, ShopAddress::getProvinceId); + iAreaService.setDataMation(list, ShopAddress::getCityId); + iAreaService.setDataMation(list, ShopAddress::getAreaId); + iAreaService.setDataMation(list, ShopAddress::getTownshipId); + shopAddressLabelService.setDataMation(list, ShopAddress::getLabelId); + return JSONUtil.toList(JSONUtil.toJsonStr(list), null); + } +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopTradeCartServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopTradeCartServiceImpl.java new file mode 100644 index 0000000..605af4b --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/ShopTradeCartServiceImpl.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.IMaterialNormsService; +import com.skyeye.erp.service.IMaterialService; +import com.skyeye.exception.CustomException; +import com.skyeye.rest.shopmaterialnorms.sevice.IShopMaterialNormsService; +import com.skyeye.store.dao.ShopTradeCartDao; +import com.skyeye.store.entity.ShopStore; +import com.skyeye.store.entity.ShopTradeCart; +import com.skyeye.store.service.ShopStoreService; +import com.skyeye.store.service.ShopTradeCartService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: ShopTradeCartServiceImpl + * @Description: 购物车管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:07 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "购物车管理", groupName = "购物车管理") +public class ShopTradeCartServiceImpl extends SkyeyeBusinessServiceImpl implements ShopTradeCartService { + + @Autowired + private IMaterialService iMaterialService; + + @Autowired + private IMaterialNormsService iMaterialNormsService; + + @Autowired + private IShopMaterialNormsService iShopMaterialNormsService; + + @Autowired + private ShopStoreService shopStoreService; + + @Override + public void validatorEntity(ShopTradeCart shopTradeCart) { + super.validatorEntity(shopTradeCart); + if (shopTradeCart.getCount() <= CommonNumConstants.NUM_ZERO) { + throw new CustomException("商品数量不能小于1"); + } + } + + @Override + public void queryShopTradeCartList(InputObject inputObject, OutputObject outputObject) { + String selected = inputObject.getParams().get("selected").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + // 查询用户购物车列表 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId), userId); + if (StrUtil.isNotEmpty(selected)) { + wrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getSelected), selected); + } + wrapper.orderByDesc(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateTime)); + List beans = list(wrapper); + iMaterialNormsService.setDataMation(beans, ShopTradeCart::getNormsId); + if (CollectionUtil.isNotEmpty(beans)) { + // 收集规格id列表,获得规格信息 + List normsIdList = beans.stream().map(ShopTradeCart::getNormsId).collect(Collectors.toList()); + List> normsListMap = iShopMaterialNormsService + .queryShopMaterialByNormsIdList(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIdList)); + // 设置商城的销售价格 + Map collect = normsListMap.stream() + .collect(Collectors.toMap(bean -> bean.get("normsId").toString(), bean -> bean.get("salePrice").toString())); + + // 设置商城商品信息 + List materialIdList = beans.stream().map(ShopTradeCart::getMaterialId).collect(Collectors.toList()); + List> shopMaterialList = iShopMaterialNormsService + .queryShopMaterialByMaterialIdList(Joiner.on(CommonCharConstants.COMMA_MARK).join(materialIdList)); + Map> shopMaterialListMap = shopMaterialList.stream() + .collect(Collectors.toMap(bean -> bean.get("materialId").toString(), bean -> bean)); + beans.forEach(bean -> { + String normsId = bean.getNormsId(); + String salePrice = collect.get(normsId); + if (CollectionUtil.isNotEmpty(bean.getNormsMation())) { + bean.getNormsMation().put("salePrice", salePrice); + } + bean.setShopMaterialMation(shopMaterialListMap.get(bean.getMaterialId())); + }); + } + iMaterialService.setDataMation(beans, ShopTradeCart::getMaterialId); + // 查询店铺信息 + List storeIdList = beans.stream().map(ShopTradeCart::getStoreId).collect(Collectors.toList()); + List shopStoreList = shopStoreService.selectByIds(storeIdList.toArray(new String[]{})); + Map shopStoreMap = shopStoreList.stream().collect(Collectors.toMap(ShopStore::getId, ShopStore::getName)); + outputObject.setBeans(beans); + outputObject.setCustomBean("AllShopStoreInfo", shopStoreMap); + } + + @Override + public String createEntity(ShopTradeCart shopTradeCart, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getMaterialId), shopTradeCart.getMaterialId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getNormsId), shopTradeCart.getNormsId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId),userId); + ShopTradeCart one = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(one)) { + shopTradeCart.setId(one.getId()); + shopTradeCart.setCount(one.getCount() + shopTradeCart.getCount()); + return super.updateEntity(shopTradeCart, userId); + } + return super.createEntity(shopTradeCart, userId); + } + + @Override + public void changeSelected(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String id = inputObject.getParams().get("id").toString(); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + ShopTradeCart one = getOne(updateWrapper); + if (!userId.equals(one.getCreateId())) { + throw new CustomException("无权限!"); + } + updateWrapper.set(MybatisPlusUtil.toColumns(ShopTradeCart::getSelected), + Objects.equals(one.getSelected(), WhetherEnum.ENABLE_USING.getKey()) + ? WhetherEnum.DISABLE_USING.getKey() : WhetherEnum.ENABLE_USING.getKey()); + update(updateWrapper); + } + + @Override + public void batchChangeSelectedStatus(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String idsStr = params.get("ids").toString(); + List ids = Arrays.stream(idsStr.split(CommonCharConstants.COMMA_MARK)).filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + Integer selected = Integer.parseInt(params.get("selected").toString()); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in(CommonConstants.ID, ids); + updateWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId), userId); + updateWrapper.set(MybatisPlusUtil.toColumns(ShopTradeCart::getSelected), selected); + update(updateWrapper); + } + + @Override + public void deleteMySelect(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getSelected), WhetherEnum.ENABLE_USING.getKey()) + .eq(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId), userId); + remove(queryWrapper); + } + + @Override + public void changeCount(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + Integer sign = Integer.parseInt(params.get("sign").toString()); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + ShopTradeCart one = getOne(updateWrapper); + Integer count = one.getCount(); + if (Objects.equals(sign, CommonNumConstants.NUM_ONE)) { + updateWrapper.set(MybatisPlusUtil.toColumns(ShopTradeCart::getCount), count + CommonNumConstants.NUM_ONE); + } else { + if (count <= CommonNumConstants.NUM_ONE) { + throw new CustomException("商品数量不能小于1"); + } + updateWrapper.set(MybatisPlusUtil.toColumns(ShopTradeCart::getCount), count - CommonNumConstants.NUM_ONE); + } + update(updateWrapper); + } + + @Override + public void resetShopTradeCart(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId), userId); + remove(queryWrapper); + } + + @Override + public void calculateTotalPrices(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.in(MybatisPlusUtil.toColumns(ShopTradeCart::getCreateId), userId); + // 查询选中的商品 + wrapper.eq(MybatisPlusUtil.toColumns(ShopTradeCart::getSelected), WhetherEnum.ENABLE_USING.getKey()); + List beans = list(wrapper); + //设置返回值 + Map result = new HashMap<>(); + final String[] allPrice = {"0"}; + if (CollectionUtil.isNotEmpty(beans)) { + Map countMap = beans.stream().collect(Collectors + .toMap(ShopTradeCart::getNormsId, shopTradeCart -> shopTradeCart.getCount().toString())); + // 收集规格id列表,获得规格信息 + List normsIdList = beans.stream().map(ShopTradeCart::getNormsId).collect(Collectors.toList()); + List> normsListMap = iShopMaterialNormsService + .queryShopMaterialByNormsIdList(Joiner.on(CommonCharConstants.COMMA_MARK).join(normsIdList)); + // 计算价格 + normsListMap.forEach(map -> { + String id = map.get("normsId").toString(); + String count = countMap.get(id); + String salePrice = map.get("salePrice").toString(); + String flagPrice = CalculationUtil.multiply(count, salePrice, CommonNumConstants.NUM_TWO); + allPrice[0] = CalculationUtil.add(allPrice[0], flagPrice); + }); + } + result.put("allPrice", Joiner.on(CommonCharConstants.COMMA_MARK).join(allPrice)); + outputObject.setBean(result); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/StoreIntercourseServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/StoreIntercourseServiceImpl.java new file mode 100644 index 0000000..e6303a9 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/store/service/impl/StoreIntercourseServiceImpl.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.store.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.store.dao.StoreIntercourseDao; +import com.skyeye.entity.intercourse.StoreIntercourseQueryDo; +import com.skyeye.store.service.StoreIntercourseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StoreIntercourseServiceImpl + * @Description: 门店往来管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/10 21:55 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +public class StoreIntercourseServiceImpl implements StoreIntercourseService { + + @Autowired + private StoreIntercourseDao storeIntercourseDao; + + public enum State { + WAIT_MEAL_BY_STORE(1, "待套餐购买门店确认"), + WAIT_KEEPFIT_STORE(2, "待保养门店确认"), + CONFIRMED(3, "已确认"); + private int state; + private String name; + + State(int state, String name) { + this.state = state; + this.name = name; + } + + public int getState() { + return state; + } + + public String getName() { + return name; + } + } + + /** + * 获取指定日期的支出/收入往来的数据 + * + * @param day 指定日期 + * @return 指定日期的支出/收入往来的数据 + */ + @Override + public List> queryStoreIntercourseByDay(String day) { + List> storeIntercourseList = storeIntercourseDao.queryStoreIntercourseByDay(day); + return storeIntercourseList; + } + + /** + * 新增支出/收入往来的数据 + * + * @param shopStoreIntercourseMationList + */ + @Override + public void insertStoreIntercourse(List> shopStoreIntercourseMationList) { + shopStoreIntercourseMationList.forEach(bean -> { + bean.put("id", ToolUtil.getSurFaceId()); + }); + storeIntercourseDao.insertStoreIntercourse(shopStoreIntercourseMationList); + } + + /** + * 获取指定门店的支出/收入往来的数据 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStoreIntercourseList(InputObject inputObject, OutputObject outputObject) { + StoreIntercourseQueryDo storeIntercourseQuery = inputObject.getParams(StoreIntercourseQueryDo.class); + Page pages = PageHelper.startPage(storeIntercourseQuery.getPage(), storeIntercourseQuery.getLimit()); + List> beans = storeIntercourseDao.queryStoreIntercourseList(storeIntercourseQuery); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 编辑指定门店的支出/收入往来的状态 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void editStoreIntercourseState(InputObject inputObject, OutputObject outputObject) { + Map params = inputObject.getParams(); + String id = params.get("id").toString(); + Integer state = Integer.parseInt(params.get("state").toString()); + Map storeIntercourse = storeIntercourseDao.queryStoreIntercourseById(id); + // 获取当前的状态 + Integer currentState = Integer.parseInt(storeIntercourse.get("state").toString()); + if (currentState == State.WAIT_MEAL_BY_STORE.getState() && state == State.WAIT_KEEPFIT_STORE.getState()) { + // 当前状态为【待套餐购买门店确认】,可以修改为【待保养门店确认】 + } else if (currentState == State.WAIT_KEEPFIT_STORE.getState() && state == State.CONFIRMED.getState()) { + // 当前状态为【待保养门店确认】,可以修改为【已确认】 + } else { + outputObject.setreturnMessage("Status to change, please refresh the page."); + return; + } + storeIntercourseDao.editStoreIntercourseState(id, state); + } + + /** + * 获取已统计信息中,指定日期的支出/收入往来的数据 + * + * @param day 指定日期 + * @return 指定日期的支出/收入往来的数据 + */ + @Override + public List> queryStoreIntercourseListByDay(String day) { + StoreIntercourseQueryDo storeIntercourseQuery = new StoreIntercourseQueryDo(); + storeIntercourseQuery.setDay(day); + List> storeIntercourseList = storeIntercourseDao.queryStoreIntercourseList(storeIntercourseQuery); + return storeIntercourseList; + } + +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/type/controller/StoreTypeController.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/controller/StoreTypeController.java new file mode 100644 index 0000000..2382275 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/controller/StoreTypeController.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.type.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.type.entity.StoreType; +import com.skyeye.type.service.StoreTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: StoreTypeController + * @Description: 门店商品分类管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "门店商品分类管理", tags = "门店商品分类管理", modelName = "门店商品分类管理") +public class StoreTypeController { + + @Autowired + private StoreTypeService storeTypeService; + + /** + * 新增/编辑门店商品分类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeStoreType", value = "新增/编辑门店商品分类信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = StoreType.class) + @RequestMapping("/post/StoreTypeController/writeStoreType") + public void writeStoreType(InputObject inputObject, OutputObject outputObject) { + storeTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 批量删除收件地址信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteStoreTypeByIds", value = "批量删除门店商品分类信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id列表,多个id用逗号分隔", required = "required")}) + @RequestMapping("/post/StoreTypeController/deleteStoreTypeByIds") + public void deleteStoreTypeByIds(InputObject inputObject, OutputObject outputObject) { + storeTypeService.deleteByIds(inputObject, outputObject); + } + + /** + * 获取门店商品分类信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStoreTypeList", value = "获取门店商品分类信息列表", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "storeId", name = "storeId", value = "门店id")}) + @RequestMapping("/post/StoreTypeController/queryStoreTypeList") + public void queryStoreTypeList(InputObject inputObject, OutputObject outputObject) { + storeTypeService.queryList(inputObject, outputObject); + } + + /** + * 分页获取门店商品分类信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryStoreTypePageList", value = "分页获取门店商品分类信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/StoreTypeController/queryStoreTypePageList") + public void queryStoreTypePageList(InputObject inputObject, OutputObject outputObject) { + storeTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id获取门店商品分类信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectStoreTypeById", value = "根据id获取门店商品分类信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/StoreTypeController/selectStoreTypeById") + public void selectStoreTypeById(InputObject inputObject, OutputObject outputObject) { + storeTypeService.selectById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/type/dao/StoreTypeDao.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/dao/StoreTypeDao.java new file mode 100644 index 0000000..2373851 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/dao/StoreTypeDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.type.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.type.entity.StoreType; + +/** + * @ClassName: StoreTypeDao + * @Description: 门店商品分类管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StoreTypeDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/type/entity/StoreType.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/entity/StoreType.java new file mode 100644 index 0000000..992c589 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/entity/StoreType.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.type.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: StoreType + * @Description: 门店商品分类实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "shop_store_type") +@ApiModel(value = "门店商品分类管理实体类") +public class StoreType extends BaseGeneralInfo { + + @TableField(value = "logo") + @ApiModelProperty(value = "logo", required = "required") + private String logo; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required") + private Integer orderBy; + + @TableField("enabled") + @ApiModelProperty(value = "启用状态1是0否", required = "required", enumClass = WhetherEnum.class) + private Integer enabled; + + @TableField(value = "store_id") + @ApiModelProperty(value = "门店id") + private String storeId; + + @TableField(exist = false) + @Property(value = "门店信息") + private Map storeMation; +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/StoreTypeService.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/StoreTypeService.java new file mode 100644 index 0000000..b694f76 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/StoreTypeService.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.type.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.type.entity.StoreType; + +/** + * @ClassName: StoreTypeService + * @Description: 门店商品分类管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface StoreTypeService extends SkyeyeBusinessService { +} diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/impl/StoreTypeServiceImpl.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/impl/StoreTypeServiceImpl.java new file mode 100644 index 0000000..bf61503 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/type/service/impl/StoreTypeServiceImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.type.service.impl; + +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.store.service.ShopStoreService; +import com.skyeye.type.dao.StoreTypeDao; +import com.skyeye.type.entity.StoreType; +import com.skyeye.type.service.StoreTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: StoreTypeServiceImpl + * @Description: 门店商品分类管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/2/4 10:06 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "门店商品分类管理", groupName = "门店商品分类管理") +public class StoreTypeServiceImpl extends SkyeyeBusinessServiceImpl implements StoreTypeService { + + @Autowired + private ShopStoreService shopStoreService; + + @Override + public List> queryDataList(InputObject inputObject) { + Map params = inputObject.getParams(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(StoreType::getStoreId), params.get("storeId").toString()); + queryWrapper.eq(MybatisPlusUtil.toColumns(StoreType::getEnabled), WhetherEnum.ENABLE_USING.getKey()); + List beans = list(queryWrapper); + shopStoreService.setDataMation(beans, StoreType::getStoreId); + return JSONUtil.toList(JSONUtil.toJsonStr(beans), null); + } + + @Override + public QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String objectId = commonPageInfo.getObjectId(); + queryWrapper.eq(MybatisPlusUtil.toColumns(StoreType::getStoreId), objectId); + return queryWrapper; + } +} \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/java/com/skyeye/xxljob/ShopXxlJob.java b/skyeye-shop/shop-store/src/main/java/com/skyeye/xxljob/ShopXxlJob.java new file mode 100644 index 0000000..39aac07 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/java/com/skyeye/xxljob/ShopXxlJob.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import cn.hutool.json.JSONUtil; +import com.skyeye.coupon.service.CouponService; +import com.skyeye.coupon.service.CouponUseService; +import com.skyeye.eve.service.IQuartzService; +import com.skyeye.order.service.OrderService; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @ClassName: ShopXxlJob + * @Description: 优惠券过期记录 + * @author: skyeye云系列--卫志强 + * @date: 2023/10/11 19:20 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class ShopXxlJob { + + @Autowired + private CouponService couponService; + + @Autowired + private CouponUseService couponUseService; + + @Autowired + private OrderService orderService; + + @Autowired + private IQuartzService iQuartzService; + + private static Logger log = LoggerFactory.getLogger(ShopXxlJob.class); + + @XxlJob("setShopCouponStateService") + public void setShopCouponStateService() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String couponId = paramMap.get("objectId");// 优惠券id + try { + log.info("优惠券id(couponId)" + couponId + "---修改优惠券的状态---开始"); + couponService.setStateByCoupon(couponId);// 修改优惠券的状态 + log.info("优惠券id(couponId)" + couponId + "---修改优惠券的状态---结束"); + log.info("优惠券id(couponId)" + couponId + "---修改领取的优惠券的状态---开始"); + couponUseService.setCouponUseStateByDate(couponId);// 修改领取的优惠券的状态 + log.info("优惠券id(couponId)" + couponId + "---修改领取的优惠券的状态---结束"); + } finally { + log.info("优惠券id(couponId)" + couponId + "---删除任务---开始"); + iQuartzService.stopAndDeleteTaskQuartz(couponId);// 删除任务 + log.info("优惠券id(couponId)" + couponId + "---删除任务---结束"); + } + } + + @XxlJob("setShopCouponUseStateService") + public void setShopCouponUseStateService() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String userId = paramMap.get("userId"); + String couponUseId = paramMap.get("objectId");// 领取的优惠券id + try { + log.info("领取优惠券的id(couponUseId)" + couponUseId + "---修改领取的优惠券的状态---开始"); + couponUseService.setCouponUseStateByTerm(userId, couponUseId);// 修改领取的优惠券的状态} + log.info("领取优惠券的id(couponUseId)" + couponUseId + "---修改领取的优惠券的状态---结束"); + } finally { + log.info("领取优惠券的id(couponUseId)" + couponUseId + "---删除任务---开始"); + iQuartzService.stopAndDeleteTaskQuartz(couponUseId);// 删除任务 + log.info("领取优惠券的id(couponUseId)" + couponUseId + "---删除任务---结束"); + } + } + + @XxlJob("createOrderNotPay") + public void createOrderNotPay() { + String param = XxlJobHelper.getJobParam(); + Map paramMap = JSONUtil.toBean(param, null); + String orderId = paramMap.get("objectId");// 订单的主键id + try { + log.info("订单的主键id(orderId)" + orderId + "---修改订单的状态为取消---开始"); + orderService.setOrderCancle(orderId);// 修改订单的状态为取消 + log.info("订单的主键id(orderId)" + orderId + "---修改订单的状态为取消---结束"); + } finally { + log.info("订单的主键id(orderId)" + orderId + "---删除任务---开始"); + iQuartzService.stopAndDeleteTaskQuartz(orderId);// 删除任务 + log.info("订单的主键id(orderId)" + orderId + "---删除任务---结束"); + } + } +} diff --git a/skyeye-shop/shop-store/src/main/resources/mapper/meal/StatisticsShopMapper.xml b/skyeye-shop/shop-store/src/main/resources/mapper/meal/StatisticsShopMapper.xml new file mode 100644 index 0000000..04b7dd8 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/resources/mapper/meal/StatisticsShopMapper.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-store/src/main/resources/mapper/store/StoreIntercourseMapper.xml b/skyeye-shop/shop-store/src/main/resources/mapper/store/StoreIntercourseMapper.xml new file mode 100644 index 0000000..21ac903 --- /dev/null +++ b/skyeye-shop/shop-store/src/main/resources/mapper/store/StoreIntercourseMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + INSERT INTO shop_store_intercourse + (id, keepfi_store_id, meal_by_store_id, meal_all_single_price, intercourse_time, state) + VALUES + + (#{item.id}, #{item.keepfitStoreId}, #{item.mealByStoreId}, #{item.mealAllSinglePrice}, #{item.createTime}, #{item.state}) + + + + + + + + + UPDATE shop_store_intercourse + + state = #{state}, + + WHERE id = #{id} + + + \ No newline at end of file diff --git a/skyeye-shop/shop-web/.gitignore b/skyeye-shop/shop-web/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/skyeye-shop/shop-web/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/skyeye-shop/shop-web/pom.xml b/skyeye-shop/shop-web/pom.xml new file mode 100644 index 0000000..ab98b74 --- /dev/null +++ b/skyeye-shop/shop-web/pom.xml @@ -0,0 +1,101 @@ + + + + skyeye-shop + com.skyeye + 0.0.1-SNAPSHOT + + 4.0.0 + + shop-web + + + 8 + 8 + + + + + + + com.skyeye + shop-member + 0.0.1-SNAPSHOT + + + + + com.skyeye + shop-store + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-shop/shop-web/src/main/java/com/SkyShopApplication.java b/skyeye-shop/shop-web/src/main/java/com/SkyShopApplication.java new file mode 100644 index 0000000..6defc00 --- /dev/null +++ b/skyeye-shop/shop-web/src/main/java/com/SkyShopApplication.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import com.skyeye.order.config.PayProperties; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableDiscoveryClient +@EnableFeignClients +@EnableConfigurationProperties(PayProperties.class) +public class SkyShopApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyShopApplication.class, args); + } + +} diff --git a/skyeye-shop/shop-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-shop/shop-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..b95d73d --- /dev/null +++ b/skyeye-shop/shop-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.github.yulichang.injector.MPJSqlInjector; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + GlobalConfig globalConfig = new GlobalConfig(); + globalConfig.setSqlInjector(new MPJSqlInjector()); + sqlSessionFactoryBean.setGlobalConfig(globalConfig); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-shop/shop-web/src/main/java/com/skyeye/xxljob/ShopStoreIntercourseQuartz.java b/skyeye-shop/shop-web/src/main/java/com/skyeye/xxljob/ShopStoreIntercourseQuartz.java new file mode 100644 index 0000000..30a2183 --- /dev/null +++ b/skyeye-shop/shop-web/src/main/java/com/skyeye/xxljob/ShopStoreIntercourseQuartz.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import com.alibaba.fastjson.JSON; +import com.skyeye.common.util.DateAfterSpacePointTime; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.jedis.util.RedisLock; +import com.skyeye.store.service.StoreIntercourseService; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ShopStoreIntercourseQuartz + * @Description: 门店昨日支出/收入往来计算 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/10 21:13 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class ShopStoreIntercourseQuartz { + + private static Logger log = LoggerFactory.getLogger(ShopStoreIntercourseQuartz.class); + + @Autowired + private StoreIntercourseService storeIntercourseService; + + private static final String LOCK_KEY = "calcShopStoreIntercourse"; + + /** + * 定时器计算门店昨日支出/收入往来信息,每天凌晨两点执行一次 + */ + @XxlJob("shopStoreIntercourseQuartz") + public void calcShopStoreIntercourse() { + log.info("定时器计算门店昨日支出/收入往来信息执行 start"); + RedisLock lock = new RedisLock(LOCK_KEY); + try { + if (!lock.lock()) { + // 加锁失败 + return; + } + // 得到昨天的时间 + String yesterdayTime = DateAfterSpacePointTime.getSpecifiedTime( + DateAfterSpacePointTime.ONE_DAY.getType(), DateUtil.getTimeAndToString(), DateUtil.YYYY_MM_DD, DateAfterSpacePointTime.AroundType.BEFORE); + log.info("yesterdayTime is {}.", yesterdayTime); + // 判断昨天的数据是否已经统计过并入库,如果已经统计过,则不会进行下一次的统计 + List> yesterdayData = storeIntercourseService.queryStoreIntercourseListByDay(yesterdayTime); + if (!CollectionUtils.isEmpty(yesterdayData)) { + log.info("已统计过昨日数据,不再进行统计"); + return; + } + log.info("开始统计"); + // 获取昨天的往来数据信息 + yesterdayData = storeIntercourseService.queryStoreIntercourseByDay(yesterdayTime); + yesterdayData.forEach(bean -> { + if (ToolUtil.isBlank(bean.get("mealByStoreId").toString())) { + bean.put("state", 2); + } else { + bean.put("state", 1); + } + }); + log.info("解析数据为 {}.", JSON.toJSONString(yesterdayData)); + if (!CollectionUtils.isEmpty(yesterdayData)) { + storeIntercourseService.insertStoreIntercourse(yesterdayData); + } + log.info("保存数据完成"); + } catch (Exception e) { + log.warn("calcShopStoreIntercourse error.", e); + } finally { + lock.unlock(); + } + log.info("定时器计算门店昨日支出/收入往来信息 end"); + } + +} diff --git a/skyeye-shop/shop-web/src/main/resources/banner.txt b/skyeye-shop/shop-web/src/main/resources/banner.txt new file mode 100644 index 0000000..f7e3a9f --- /dev/null +++ b/skyeye-shop/shop-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev shop-web.jar >> /opt/service/project/nohup-shop.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-shop/shop-web/src/main/resources/bootstrap.yml b/skyeye-shop/shop-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..91283e8 --- /dev/null +++ b/skyeye-shop/shop-web/src/main/resources/bootstrap.yml @@ -0,0 +1,48 @@ + +server: + port: 8082 + +spring: + application: + name: skyeye-shop-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # 总工程服务 + skyeye-pro: skyeye-pro-${spring.profiles.active} + # ERP相关的服务 + skyeye-erp: skyeye-erp-${spring.profiles.active} + +skyeye: + pay: + order-notify-url: http://XXX/admin-api/pay/notify/order # 支付渠道的【支付】回调地址 + refund-notify-url: http://XXX/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 diff --git a/skyeye-shop/shop-web/src/main/resources/log4j.properties b/skyeye-shop/shop-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-shop/shop-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-tms/.gitignore b/skyeye-tms/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-tms/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-tms/pom.xml b/skyeye-tms/pom.xml new file mode 100644 index 0000000..a5c93ff --- /dev/null +++ b/skyeye-tms/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + pom + + tms-common + tms-pro + tms-web + + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-tms + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/skyeye-tms/tms-common/.gitignore b/skyeye-tms/tms-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-tms/tms-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-tms/tms-common/pom.xml b/skyeye-tms/tms-common/pom.xml new file mode 100644 index 0000000..3d25703 --- /dev/null +++ b/skyeye-tms/tms-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-tms + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + tms-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-tms/tms-pro/.gitignore b/skyeye-tms/tms-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-tms/tms-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-tms/tms-pro/pom.xml b/skyeye-tms/tms-pro/pom.xml new file mode 100644 index 0000000..d1782a1 --- /dev/null +++ b/skyeye-tms/tms-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-tms + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + tms-pro + + + + + com.skyeye + tms-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/controller/BillingAddressController.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/controller/BillingAddressController.java new file mode 100644 index 0000000..b61a84d --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/controller/BillingAddressController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.address.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.address.entity.BillingAddress; +import com.skyeye.tms.address.service.BillingAddressService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BillingAddressController + * @Description: 计费地址控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 15:36 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "计费地址", tags = "计费地址", modelName = "计费地址") +public class BillingAddressController { + + @Autowired + private BillingAddressService billingAddressService; + + /** + * 获取计费地址列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryBillingAddressList", value = "获取计费地址列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BillingAddressController/queryBillingAddressList") + public void queryBillingAddressList(InputObject inputObject, OutputObject outputObject) { + billingAddressService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改计费地址 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeBillingAddress", value = "新增/编辑计费地址", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = BillingAddress.class) + @RequestMapping("/post/BillingAddressController/writeBillingAddress") + public void writeBillingAddress(InputObject inputObject, OutputObject outputObject) { + billingAddressService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除计费地址 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteBillingAddressById", value = "根据ID删除计费地址", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/BillingAddressController/deleteBillingAddressById") + public void deleteBillingAddressById(InputObject inputObject, OutputObject outputObject) { + billingAddressService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的计费地址 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledBillingAddressList", value = "获取已启用的计费地址", method = "GET", allUse = "2") + @RequestMapping("/post/TmsBillingAddressTypeController/queryEnabledBillingAddressList") + public void queryEnabledBillingAddressList(InputObject inputObject, OutputObject outputObject) { + billingAddressService.queryEnabledBillingAddressList(inputObject, outputObject); + } + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/dao/BillingAddressDao.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/dao/BillingAddressDao.java new file mode 100644 index 0000000..8104cee --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/dao/BillingAddressDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.address.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tms.address.entity.BillingAddress; + +/** + * @ClassName: BillingAddressDao + * @Description: 计费地址数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 15:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BillingAddressDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/entity/BillingAddress.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/entity/BillingAddress.java new file mode 100644 index 0000000..d711e13 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/entity/BillingAddress.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.address.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.AreaInfo; +import lombok.Data; + +/** + * @ClassName: BillingAddress + * @Description: 计费地址实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 15:27 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "tms:billingAddress", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "tms_billing_address", autoResultMap = true) +@ApiModel("计费地址实体类") +public class BillingAddress extends AreaInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "`name`") + @ApiModelProperty(value = "名称", required = "required", fuzzyLike = true) + private String name; + + @TableField(value = "longitude") + @ApiModelProperty(value = "经度") + private String longitude; + + @TableField(value = "latitude") + @ApiModelProperty(value = "纬度") + private String latitude; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/BillingAddressService.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/BillingAddressService.java new file mode 100644 index 0000000..fc697a3 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/BillingAddressService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.address.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.address.entity.BillingAddress; + +/** + * @ClassName: BillingAddressService + * @Description: 计费地址服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 15:34 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BillingAddressService extends SkyeyeBusinessService { + + void queryEnabledBillingAddressList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/impl/BillingAddressServiceImpl.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/impl/BillingAddressServiceImpl.java new file mode 100644 index 0000000..c8ba019 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/address/service/impl/BillingAddressServiceImpl.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.address.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tms.address.dao.BillingAddressDao; +import com.skyeye.tms.address.entity.BillingAddress; +import com.skyeye.tms.address.service.BillingAddressService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: BillingAddressServiceImpl + * @Description: 计费地址服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 15:35 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "计费地址", groupName = "计费地址") +public class BillingAddressServiceImpl extends SkyeyeBusinessServiceImpl implements BillingAddressService { + + @Override + public void queryEnabledBillingAddressList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(BillingAddress::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List billingAddressList = list(queryWrapper); + outputObject.setBeans(billingAddressList); + outputObject.settotal(billingAddressList.size()); + } + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarAttribute.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarAttribute.java new file mode 100644 index 0000000..dfcbe95 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarAttribute.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CarAttribute + * @Description: 车辆属性枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CarAttribute implements SkyeyeEnumClass { + + FIXED(1, "固定", true, true), + SELF_OPERATED(2, "自营", true, false), + FIXED_LEASE_IN(3, "固定租入", true, false), + TEMPORARY_RENTAL(4, "临时租入", true, false), + AFFILIATION(5, "挂靠", true, false), + FIXED_LEASE_OUT(6, "固定租出", true, false), + TEMPORARY_LEASE_OUT(7, "临时租出", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarState.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarState.java new file mode 100644 index 0000000..30339f0 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/classenum/CarState.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: CarState + * @Description: 车辆当前状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:18 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CarState implements SkyeyeEnumClass { + + AVAILABLE(1, "可用", true, true), + DISPATCHED(2, "已调度", true, false), + IN_TRANSIT(3, "在途", true, false), + MAINTENANCE_UPKEEP(4, "维修保养", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/controller/CarController.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/controller/CarController.java new file mode 100644 index 0000000..8b16a32 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/controller/CarController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.car.entity.Car; +import com.skyeye.tms.car.service.CarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CarController + * @Description: 车辆管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆管理", tags = "车辆管理", modelName = "车辆管理") +public class CarController { + + @Autowired + private CarService carService; + + /** + * 获取车辆列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCarList", value = "获取车辆列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CarController/queryCarList") + public void queryCarList(InputObject inputObject, OutputObject outputObject) { + carService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改车辆 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeCar", value = "新增/编辑车辆", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = Car.class) + @RequestMapping("/post/CarController/writeCar") + public void writeCar(InputObject inputObject, OutputObject outputObject) { + carService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除车辆 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCarById", value = "根据ID删除车辆", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CarController/deleteCarById") + public void deleteCarById(InputObject inputObject, OutputObject outputObject) { + carService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的车辆 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledCarList", value = "获取已启用的车辆", method = "GET", allUse = "2") + @RequestMapping("/post/TmsCarTypeController/queryEnabledCarList") + public void queryEnabledCarList(InputObject inputObject, OutputObject outputObject) { + carService.queryEnabledCarList(inputObject, outputObject); + } + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/dao/CarDao.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/dao/CarDao.java new file mode 100644 index 0000000..e904f19 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/dao/CarDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tms.car.entity.Car; + +/** + * @ClassName: CarDao + * @Description: 车辆管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CarDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/entity/Car.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/entity/Car.java new file mode 100644 index 0000000..f61f7ca --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/entity/Car.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.tms.cartype.entity.TmsCarType; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Car + * @Description: 车辆管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 11:59 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField("plate") +@RedisCacheField(name = "tms:car", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "tms_car") +@ApiModel("车辆管理实体类") +public class Car extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("odd_number") + @Property(value = "车辆编号", fuzzyLike = true) + private String oddNumber; + + @TableField(exist = false) + @Property(value = "名称") + private String name; + + @TableField("plate") + @ApiModelProperty(value = "车牌号", required = "required", fuzzyLike = true) + private String plate; + + @TableField(value = "logo") + @ApiModelProperty(value = "车辆图片") + private String logo; + + @TableField(value = "type_id") + @ApiModelProperty(value = "车辆类型id", required = "required") + private String typeId; + + @TableField(exist = false) + @Property(value = "车辆类型信息") + private TmsCarType typeMation; + + @TableField(value = "attribute_id") + @ApiModelProperty(value = "车辆属性,参考#CarAttribute", required = "required") + private Integer attributeId; + + @TableField(value = "state") + @ApiModelProperty(value = "当前状态,参考#CarState", required = "required") + private Integer state; + + @TableField(value = "common_driver_id") + @ApiModelProperty(value = "常用司机id") + private String commonDriverId; + + @TableField(exist = false) + @Property(value = "常用司机信息") + private Map commonDriverMation; + + @TableField(value = "auxiliary_driver_id") + @ApiModelProperty(value = "辅助司机id") + private String auxiliaryDriverId; + + @TableField(exist = false) + @Property(value = "辅助司机信息") + private Map auxiliaryDriverMation; + + @TableField(value = "settlement_method") + @ApiModelProperty(value = "结算方式,参考财务-财务账号") + private String settlementMethod; + + @TableField(exist = false) + @Property(value = "结算方式信息") + private Map settlementMethodMation; + + @TableField(value = "load_capacity_ton") + @ApiModelProperty(value = "核准载重(吨)", defaultValue = "0") + private String loadCapacityTon; + + @TableField(value = "load_capacity_cbm") + @ApiModelProperty(value = "核准载重体积(CBM)", defaultValue = "0") + private String loadCapacityCbm; + + @TableField(value = "plate_color_id") + @ApiModelProperty(value = "车辆颜色,数据字典") + private String plateColorId; + + @TableField(value = "buy_time") + @ApiModelProperty(value = "购买日期") + private String buyTime; + + @TableField(value = "vehicle_model") + @ApiModelProperty(value = "车辆型号") + private String vehicleModel; + + @TableField(value = "engine_number") + @ApiModelProperty(value = "发动机号") + private String engineNumber; + + @TableField(value = "frame_number") + @ApiModelProperty(value = "车架号") + private String frameNumber; + + @TableField(value = "category_id") + @ApiModelProperty(value = "货车类别,数据字典") + private String categoryId; + + @TableField(value = "cabinet_id") + @ApiModelProperty(value = "柜型,数据字典") + private String cabinetId; + + @TableField(value = "object_id") + @ApiModelProperty(value = "所属车队(供应商id)") + private String objectId; + + @TableField(value = "object_key") + @ApiModelProperty(value = "所属车队(供应商key)") + private String objectKey; + + @TableField(exist = false) + @Property(value = "所属车队(供应商信息)") + private Map objectMation; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/CarService.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/CarService.java new file mode 100644 index 0000000..bc483e2 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/CarService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.car.entity.Car; + +/** + * @ClassName: CarService + * @Description: 车辆管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CarService extends SkyeyeBusinessService { + + void queryEnabledCarList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/impl/CarServiceImpl.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/impl/CarServiceImpl.java new file mode 100644 index 0000000..f52f551 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/car/service/impl/CarServiceImpl.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.car.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.erp.service.ISupplierService; +import com.skyeye.exception.CustomException; +import com.skyeye.ifs.service.IAccountService; +import com.skyeye.tms.car.dao.CarDao; +import com.skyeye.tms.car.entity.Car; +import com.skyeye.tms.car.service.CarService; +import com.skyeye.tms.cartype.service.TmsCarTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: CarServiceImpl + * @Description: 车辆管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/9 12:01 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "车辆管理", groupName = "车辆管理") +public class CarServiceImpl extends SkyeyeBusinessServiceImpl implements CarService { + + @Autowired + private IAccountService iAccountService; + + @Autowired + private ISupplierService iSupplierService; + + @Autowired + private TmsCarTypeService tmsCarTypeService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setMationForMap(beans, "commonDriverId", "commonDriverMation"); + iAuthUserService.setMationForMap(beans, "auxiliaryDriverId", "auxiliaryDriverMation"); + iAccountService.setMationForMap(beans, "settlementMethod", "settlementMethodMation"); + iSupplierService.setMationForMap(beans, "objectId", "objectMation"); + tmsCarTypeService.setMationForMap(beans, "typeId", "typeMation"); + return beans; + } + + @Override + protected void validatorEntity(Car entity) { + super.validatorEntity(entity); + if (StrUtil.isNotEmpty(entity.getCommonDriverId()) && StrUtil.equals(entity.getCommonDriverId(), entity.getAuxiliaryDriverId())) { + throw new CustomException("常用司机和辅助司机不能一致,请确认"); + } + } + + @Override + public void createPrepose(Car entity) { + Map business = BeanUtil.beanToMap(entity); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getServiceClassName(), business); + entity.setOddNumber(oddNumber); + } + + @Override + public Car selectById(String id) { + Car car = super.selectById(id); + iSupplierService.setDataMation(car, Car::getObjectId); + tmsCarTypeService.setDataMation(car, Car::getTypeId); + iAuthUserService.setDataMation(car, Car::getCommonDriverId); + iAuthUserService.setDataMation(car, Car::getAuxiliaryDriverId); + iAccountService.setDataMation(car, Car::getSettlementMethod); + return car; + } + + @Override + public List selectByIds(String... ids) { + List carList = super.selectByIds(ids); + iSupplierService.setDataMation(carList, Car::getObjectId); + tmsCarTypeService.setDataMation(carList, Car::getTypeId); + iAuthUserService.setDataMation(carList, Car::getCommonDriverId); + iAuthUserService.setDataMation(carList, Car::getAuxiliaryDriverId); + iAccountService.setDataMation(carList, Car::getSettlementMethod); + return carList; + } + + @Override + public void queryEnabledCarList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Car::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List carList = list(queryWrapper); + carList.forEach(tmsCarType -> { + tmsCarType.setName(String.format(Locale.ROOT, "%s_%s", tmsCarType.getOddNumber(), tmsCarType.getPlate())); + }); + outputObject.setBeans(carList); + outputObject.settotal(carList.size()); + } + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/controller/TmsCarTypeController.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/controller/TmsCarTypeController.java new file mode 100644 index 0000000..cbb92be --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/controller/TmsCarTypeController.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.cartype.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.cartype.entity.TmsCarType; +import com.skyeye.tms.cartype.service.TmsCarTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TmsCarTypeController + * @Description:车辆类型控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/5 15:17 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "车辆类型", tags = "车辆类型", modelName = "车辆类型") +public class TmsCarTypeController { + + @Autowired + private TmsCarTypeService tmsCarTypeService; + + /** + * 获取车辆类型列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTmsCarTypeList", value = "获取车辆类型列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TmsCarTypeController/queryTmsCarTypeList") + public void queryTmsCarTypeList(InputObject inputObject, OutputObject outputObject) { + tmsCarTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改车辆类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTmsCarType", value = "新增/编辑车辆类型", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TmsCarType.class) + @RequestMapping("/post/TmsCarTypeController/writeTmsCarType") + public void writeTmsCarType(InputObject inputObject, OutputObject outputObject) { + tmsCarTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除车辆类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTmsCarTypeById", value = "根据ID删除车辆类型", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TmsCarTypeController/deleteTmsCarTypeById") + public void deleteTmsCarTypeById(InputObject inputObject, OutputObject outputObject) { + tmsCarTypeService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的车辆类型 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledTmsCarType", value = "获取已启用的车辆类型", method = "GET", allUse = "2") + @RequestMapping("/post/TmsCarTypeController/queryEnabledTmsCarType") + public void queryEnabledTmsCarType(InputObject inputObject, OutputObject outputObject) { + tmsCarTypeService.queryEnabledTmsCarType(inputObject, outputObject); + } + +} + + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/dao/TmsCarTypeDao.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/dao/TmsCarTypeDao.java new file mode 100644 index 0000000..4f4cf33 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/dao/TmsCarTypeDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.cartype.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tms.cartype.entity.TmsCarType; + +/** + * @ClassName: TmsCarTypeDao + * @Description: 车辆类型交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface TmsCarTypeDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/entity/TmsCarType.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/entity/TmsCarType.java new file mode 100644 index 0000000..c6dd23b --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/entity/TmsCarType.java @@ -0,0 +1,55 @@ + +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.cartype.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +/** + * @ClassName: TmsCarType + * @Description: 车辆类型实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/9 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "tms:carType", cacheTime = RedisConstants.HALF_A_YEAR_SECONDS) +@TableName(value = "tms_car_type") +@ApiModel(value = "车辆类型表") +public class TmsCarType extends BaseGeneralInfo { + + @TableField("odd_number") + @Property(value = "编码") + private String oddNumber; + + @TableField("load_capacity_ton") + @ApiModelProperty(value = "核准载重(吨)", required = "required", defaultValue = "0.00") + private String loadCapacityTon; + + @TableField("load_capacity_cbm") + @ApiModelProperty(value = "核准载重体积(CBM)", required = "required", defaultValue = "0.00") + private String loadCapacityCbm; + + @TableField("max_transporter_num") + @ApiModelProperty(value = "最大运输件数") + private String maxTransporterNum; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/TmsCarTypeService.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/TmsCarTypeService.java new file mode 100644 index 0000000..b7caba7 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/TmsCarTypeService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.cartype.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.cartype.entity.TmsCarType; + +/** + * @ClassName: TmsCarTypeService + * @Description: 车辆类型接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface TmsCarTypeService extends SkyeyeBusinessService { + + void queryEnabledTmsCarType(InputObject inputObject, OutputObject outputObject); + +} + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/impl/TmsCarTypeServiceImpl.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/impl/TmsCarTypeServiceImpl.java new file mode 100644 index 0000000..9c9a5c5 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/cartype/service/impl/TmsCarTypeServiceImpl.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.cartype.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tms.cartype.dao.TmsCarTypeDao; +import com.skyeye.tms.cartype.entity.TmsCarType; +import com.skyeye.tms.cartype.service.TmsCarTypeService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * @ClassName: TmsCarTypeServiceImpl + * @Description: 车辆类型服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "车辆类型", groupName = "车辆类型") +public class TmsCarTypeServiceImpl extends SkyeyeBusinessServiceImpl implements TmsCarTypeService { + + @Override + public void createPrepose(TmsCarType tmsCarType) { + Map business = BeanUtil.beanToMap(tmsCarType); + String oddNumber = iCodeRuleService.getNextCodeByClassName(getServiceClassName(), business); + tmsCarType.setOddNumber(oddNumber); + } + + @Override + public void queryEnabledTmsCarType(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TmsCarType::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List tmsCarTypeList = list(queryWrapper); + tmsCarTypeList.forEach(tmsCarType -> { + tmsCarType.setName(String.format(Locale.ROOT, "%s_%s", tmsCarType.getOddNumber(), tmsCarType.getName())); + }); + outputObject.setBeans(tmsCarTypeList); + outputObject.settotal(tmsCarTypeList.size()); + } + +} + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/controller/TmsDriverController.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/controller/TmsDriverController.java new file mode 100644 index 0000000..8291e18 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/controller/TmsDriverController.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.driver.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.driver.entity.TmsDriver; +import com.skyeye.tms.driver.service.TmsDriverService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TmsDriverController + * @Description:司机管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/9/5 15:17 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "司机管理", tags = "司机管理", modelName = "司机管理") +public class TmsDriverController { + + @Autowired + private TmsDriverService tmsDriverService; + + /** + * 获取司机管理列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTmsDriverList", value = "获取司机管理列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TmsDriverController/queryTmsDriverList") + public void queryTmsDriverList(InputObject inputObject, OutputObject outputObject) { + tmsDriverService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改司机管理 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTmsDriver", value = "新增/编辑司机管理", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TmsDriver.class) + @RequestMapping("/post/TmsDriverController/writeTmsDriver") + public void writeTmsDriver(InputObject inputObject, OutputObject outputObject) { + tmsDriverService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除司机管理 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTmsDriverById", value = "根据ID删除司机管理", method = "DELETE", allUse = "1") + @ApiImplicitParams({@ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TmsDriverController/deleteTmsDriverById") + public void deleteTmsDriverById(InputObject inputObject, OutputObject outputObject) { + tmsDriverService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的司机 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledTmsDriverList", value = "获取已启用的司机", method = "GET", allUse = "2") + @RequestMapping("/post/TmsDriverController/queryEnabledTmsDriverList") + public void queryEnabledTmsDriverList(InputObject inputObject, OutputObject outputObject) { + tmsDriverService.queryEnabledTmsDriverList(inputObject, outputObject); + } + +} + + + + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/dao/TmsDriverDao.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/dao/TmsDriverDao.java new file mode 100644 index 0000000..3f4d762 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/dao/TmsDriverDao.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.driver.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tms.driver.entity.TmsDriver; + +/** + * @ClassName: TmsDriverDao + * @Description:司机管理交互层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:19 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface TmsDriverDao extends SkyeyeBaseMapper { + +} + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/entity/TmsDriver.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/entity/TmsDriver.java new file mode 100644 index 0000000..1218a39 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/entity/TmsDriver.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.driver.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: TmsDriver + * @Description: 司机管理实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/9 20:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField("userId") +@TableName(value = "tms_driver") +@ApiModel(value = "司机管理表") +public class TmsDriver extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(exist = false) + @Property(value = "名称") + private String name; + + @TableField("user_id") + @ApiModelProperty(value = "用户id", required = "required") + private String userId; + + @TableField(exist = false) + @Property(value = "用户信息") + private Map userMation; + + @TableField("driver_no") + @ApiModelProperty(value = "驾驶证号", required = "required") + private String driverNo; + + @TableField("effect_start_time") + @ApiModelProperty(value = "驾驶证有效期,开始", required = "required") + private String effectStartTime; + + @TableField("effect_end_time") + @ApiModelProperty(value = "驾驶证有效期,结束", required = "required") + private String effectEndTime; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/TmsDriverService.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/TmsDriverService.java new file mode 100644 index 0000000..360dc69 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/TmsDriverService.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.driver.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.driver.entity.TmsDriver; + +/** + * @ClassName: TmsDriverService + * @Description: 司机管理接口层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:21 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +public interface TmsDriverService extends SkyeyeBusinessService { + + void queryEnabledTmsDriverList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/impl/TmsDriverServiceImpl.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/impl/TmsDriverServiceImpl.java new file mode 100644 index 0000000..5ab5777 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/driver/service/impl/TmsDriverServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.driver.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.tms.driver.dao.TmsDriverDao; +import com.skyeye.tms.driver.entity.TmsDriver; +import com.skyeye.tms.driver.service.TmsDriverService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TmsDriverServiceImpl + * @Description: 司机管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/16 23:20 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye-report Inc. All rights reserved. + * 注意:本内容具体规则请参照readme执行,地址:https://gitee.com/doc_wei01/skyeye-report/blob/master/README.md + */ +@Service +@SkyeyeService(name = "司机管理", groupName = "司机管理") +public class TmsDriverServiceImpl extends SkyeyeBusinessServiceImpl implements TmsDriverService { + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + iAuthUserService.setMationForMap(beans, "userId", "userMation"); + return beans; + } + + @Override + public TmsDriver selectById(String id) { + TmsDriver tmsDriver = super.selectById(id); + iAuthUserService.setDataMation(tmsDriver, TmsDriver::getUserId); + return tmsDriver; + } + + @Override + public List selectByIds(String... ids) { + List tmsDriverList = super.selectByIds(ids); + iAuthUserService.setDataMation(tmsDriverList, TmsDriver::getUserId); + return tmsDriverList; + } + + @Override + public void queryEnabledTmsDriverList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TmsDriver::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List tmsDriverList = list(queryWrapper); + iAuthUserService.setDataMation(tmsDriverList, TmsDriver::getUserId); + tmsDriverList.forEach(tmsCarType -> { + tmsCarType.setId(tmsCarType.getUserId()); + Map userMation = tmsCarType.getUserMation(); + tmsCarType.setName(userMation.get("name").toString()); + }); + outputObject.setBeans(tmsDriverList); + outputObject.settotal(tmsDriverList.size()); + } +} + diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/controller/TransportationPathController.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/controller/TransportationPathController.java new file mode 100644 index 0000000..c5c1027 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/controller/TransportationPathController.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.path.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.path.entity.TransportationPath; +import com.skyeye.tms.path.service.TransportationPathService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: TransportationPathController + * @Description: 运输路径控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 22:15 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "运输路径", tags = "运输路径", modelName = "运输路径") +public class TransportationPathController { + + @Autowired + private TransportationPathService transportationPathService; + + /** + * 获取运输路径列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryTransportationPathList", value = "获取运输路径列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/TransportationPathController/queryTransportationPathList") + public void queryTransportationPathList(InputObject inputObject, OutputObject outputObject) { + transportationPathService.queryPageList(inputObject, outputObject); + } + + /** + * 添加或修改运输路径 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeTransportationPath", value = "新增/编辑运输路径", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = TransportationPath.class) + @RequestMapping("/post/TransportationPathController/writeTransportationPath") + public void writeTransportationPath(InputObject inputObject, OutputObject outputObject) { + transportationPathService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除运输路径 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteTransportationPathById", value = "根据ID删除运输路径", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/TransportationPathController/deleteTransportationPathById") + public void deleteTransportationPathById(InputObject inputObject, OutputObject outputObject) { + transportationPathService.deleteById(inputObject, outputObject); + } + + /** + * 获取已启用的运输路径 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnabledTransportationPathList", value = "获取已启用的运输路径", method = "GET", allUse = "2") + @RequestMapping("/post/TmsTransportationPathTypeController/queryEnabledTransportationPathList") + public void queryEnabledTransportationPathList(InputObject inputObject, OutputObject outputObject) { + transportationPathService.queryEnabledTransportationPathList(inputObject, outputObject); + } + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/dao/TransportationPathDao.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/dao/TransportationPathDao.java new file mode 100644 index 0000000..c8502f4 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/dao/TransportationPathDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.path.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.tms.path.entity.TransportationPath; + +/** + * @ClassName: TransportationPathDao + * @Description: 运输路径数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TransportationPathDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/entity/TransportationPath.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/entity/TransportationPath.java new file mode 100644 index 0000000..99c71b0 --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/entity/TransportationPath.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.path.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import com.skyeye.tms.address.entity.BillingAddress; +import lombok.Data; + +/** + * @ClassName: TransportationPath + * @Description: 运输路径实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 22:05 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField +@RedisCacheField(name = "tms:path", cacheTime = RedisConstants.A_YEAR_SECONDS) +@TableName(value = "tms_transportation_path") +@ApiModel("运输路径实体类") +public class TransportationPath extends BaseGeneralInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField(value = "departure_id") + @ApiModelProperty(value = "出发地(计费地址id)", required = "required") + private String departureId; + + @TableField(exist = false) + @Property(value = "出发地信息") + private BillingAddress departureMation; + + @TableField(value = "destination_id") + @ApiModelProperty(value = "目的地(计费地址id)", required = "required") + private String destinationId; + + @TableField(exist = false) + @Property(value = "目的地信息") + private BillingAddress destinationMation; + + @TableField(value = "billable_mileage") + @ApiModelProperty(value = "计费里程(千米)") + private String billableMileage; + + @TableField(value = "actual_mileage") + @ApiModelProperty(value = "实际里程(千米)") + private String actualMileage; + + @TableField(value = "enabled") + @ApiModelProperty(value = "启用状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/TransportationPathService.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/TransportationPathService.java new file mode 100644 index 0000000..40212cd --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/TransportationPathService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.path.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.tms.path.entity.TransportationPath; + +/** + * @ClassName: TransportationPathService + * @Description: 运输路径服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 22:13 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface TransportationPathService extends SkyeyeBusinessService { + + void queryEnabledTransportationPathList(InputObject inputObject, OutputObject outputObject); + +} diff --git a/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/impl/TransportationPathServiceImpl.java b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/impl/TransportationPathServiceImpl.java new file mode 100644 index 0000000..952cfab --- /dev/null +++ b/skyeye-tms/tms-pro/src/main/java/com/skyeye/tms/path/service/impl/TransportationPathServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.tms.path.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.tms.address.service.BillingAddressService; +import com.skyeye.tms.path.dao.TransportationPathDao; +import com.skyeye.tms.path.entity.TransportationPath; +import com.skyeye.tms.path.service.TransportationPathService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: TransportationPathServiceImpl + * @Description: 运输路径服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/6/11 22:14 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "运输路径", groupName = "运输路径") +public class TransportationPathServiceImpl extends SkyeyeBusinessServiceImpl implements TransportationPathService { + + @Autowired + private BillingAddressService billingAddressService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = super.queryPageDataList(inputObject); + billingAddressService.setMationForMap(beans, "departureId", "departureMation"); + billingAddressService.setMationForMap(beans, "destinationId", "destinationMation"); + return beans; + } + + @Override + protected void validatorEntity(TransportationPath entity) { + super.validatorEntity(entity); + if (StrUtil.equals(entity.getDepartureId(), entity.getDestinationId())) { + throw new CustomException("出发地和目的地不能一致,请确认"); + } + } + + @Override + public TransportationPath selectById(String id) { + TransportationPath transportationPath = super.selectById(id); + billingAddressService.setDataMation(transportationPath, TransportationPath::getDepartureId); + billingAddressService.setDataMation(transportationPath, TransportationPath::getDestinationId); + return transportationPath; + } + + @Override + public List selectByIds(String... ids) { + List transportationPathList = super.selectByIds(ids); + billingAddressService.setDataMation(transportationPathList, TransportationPath::getDepartureId); + billingAddressService.setDataMation(transportationPathList, TransportationPath::getDestinationId); + return transportationPathList; + } + + @Override + public void queryEnabledTransportationPathList(InputObject inputObject, OutputObject outputObject) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(TransportationPath::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List transportationPathList = list(queryWrapper); + outputObject.setBeans(transportationPathList); + outputObject.settotal(transportationPathList.size()); + } + +} diff --git a/skyeye-tms/tms-web/.gitignore b/skyeye-tms/tms-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-tms/tms-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-tms/tms-web/pom.xml b/skyeye-tms/tms-web/pom.xml new file mode 100644 index 0000000..4e3a628 --- /dev/null +++ b/skyeye-tms/tms-web/pom.xml @@ -0,0 +1,88 @@ + + + + skyeye-tms + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + tms-web + + + + + com.skyeye + tms-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-tms/tms-web/src/main/java/com/TmsApplication.java b/skyeye-tms/tms-web/src/main/java/com/TmsApplication.java new file mode 100644 index 0000000..0390052 --- /dev/null +++ b/skyeye-tms/tms-web/src/main/java/com/TmsApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class TmsApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(TmsApplication.class, args); + } + +} diff --git a/skyeye-tms/tms-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-tms/tms-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..8d57510 --- /dev/null +++ b/skyeye-tms/tms-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.tms.*.dao", + "com.skyeye.*.dao", + "com.skyeye.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + mybatisSqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + mybatisSqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + mybatisSqlSessionFactoryBean.afterPropertiesSet(); + return mybatisSqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-tms/tms-web/src/main/resources/banner.txt b/skyeye-tms/tms-web/src/main/resources/banner.txt new file mode 100644 index 0000000..b1cb7f9 --- /dev/null +++ b/skyeye-tms/tms-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev ifs-web.jar >> /opt/service/project/nohup-ifs.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-tms/tms-web/src/main/resources/bootstrap.yml b/skyeye-tms/tms-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..cff5d6f --- /dev/null +++ b/skyeye-tms/tms-web/src/main/resources/bootstrap.yml @@ -0,0 +1,44 @@ +server: + port: 8212 + +spring: + application: + name: skyeye-tms-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +feign: + client: + config: + # 全局配置 + default: + loggerLevel: FULL + diff --git a/skyeye-tms/tms-web/src/main/resources/jvm调优参数配置 b/skyeye-tms/tms-web/src/main/resources/jvm调优参数配置 new file mode 100644 index 0000000..ccedd4b --- /dev/null +++ b/skyeye-tms/tms-web/src/main/resources/jvm调优参数配置 @@ -0,0 +1,22 @@ +-- jvm堆的最小值3G +-Xms3072m +-- jvm堆的最大值3G +-Xmx3072m +-- 新生代内存区域的大小,设置新生代区域后,老年代内存=堆内存 - 新生代内存;老年代的最大内存 = 堆内存 - 新生代最大内存 +-Xmn2048M +-- 新生代内存区域中Eden和Survivor的比例,SurvivorRatio=8,那么Eden区占8/10,2个Survivor区各占1/10 +-XX:SurvivorRatio=8 +-- 大小为区间为[0,15],如果高于15,JDK7 会默认15,JDK 8会启动报错 +-XX:MaxTenuringThreshold=15 +-- 输出GC的时间戳(以日期的形式,如 2019-05-04T21:53:59.234+0800) +-XX:+PrintGCDateStamps +-- 打印出GC的详细信息 +-XX:+PrintGCDetails +-- 在进行GC的前后打印出堆的信息 +-XX:+PrintHeapAtGC +-- 打印年轻代各个引用的数量以及时长 +-XX:+PrintReferenceGC +-- 开启gc日志 +-verbose:gc +-- gc日志的存放位置 +-Xloggc:d:/gc.log diff --git a/skyeye-tms/tms-web/src/main/resources/log4j.properties b/skyeye-tms/tms-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..03115ff --- /dev/null +++ b/skyeye-tms/tms-web/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info diff --git a/skyeye-wages/.gitignore b/skyeye-wages/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-wages/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wages/pom.xml b/skyeye-wages/pom.xml new file mode 100644 index 0000000..1a4f414 --- /dev/null +++ b/skyeye-wages/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-wages + 1.0-SNAPSHOT + pom + + + wages-common + wages-entity + wages-pro + wages-web + + + \ No newline at end of file diff --git a/skyeye-wages/wages-common/.gitignore b/skyeye-wages/wages-common/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-wages/wages-common/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wages/wages-common/pom.xml b/skyeye-wages/wages-common/pom.xml new file mode 100644 index 0000000..2bf8629 --- /dev/null +++ b/skyeye-wages/wages-common/pom.xml @@ -0,0 +1,25 @@ + + + + skyeye-wages + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wages-common + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-entity/.gitignore b/skyeye-wages/wages-entity/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-wages/wages-entity/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wages/wages-entity/pom.xml b/skyeye-wages/wages-entity/pom.xml new file mode 100644 index 0000000..8179670 --- /dev/null +++ b/skyeye-wages/wages-entity/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-wages + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wages-entity + + + + + com.skyeye + wages-common + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/entity/wages/WagesStaffWorkTimeMation.java b/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/entity/wages/WagesStaffWorkTimeMation.java new file mode 100644 index 0000000..638fac4 --- /dev/null +++ b/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/entity/wages/WagesStaffWorkTimeMation.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.entity.wages; + +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesStaffWorkTimeMation + * @Description: 获取应出勤的班次以及小时的实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/7/17 18:21 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("获取应出勤的班次以及小时的实体类") +public class WagesStaffWorkTimeMation implements Serializable { + + @ApiModelProperty(value = "员工对应的考勤班次") + private List> staffWorkTime; + + @ApiModelProperty(value = "指定年月,格式为yyyy-MM", required = "required") + private String lastMonthDate; + +} diff --git a/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/rest/checkwork/CheckWorkTimeService.java b/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/rest/checkwork/CheckWorkTimeService.java new file mode 100644 index 0000000..6f30c30 --- /dev/null +++ b/skyeye-wages/wages-entity/src/main/java/com/skyeye/eve/rest/checkwork/CheckWorkTimeService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.rest.checkwork; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * @ClassName: CheckWorkTimeService + * @Description: 考勤班次模块接口类 + * @author: skyeye云系列--卫志强 + * @date: 2022/3/26 21:10 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@FeignClient(value = "${webroot.skyeye-flowable}", configuration = ClientConfiguration.class) +public interface CheckWorkTimeService { + + /** + * 根据指定年月获取所有的考勤班次的信息以及工作日信息等 + * + * @param pointMonthDate 指定年月,格式为yyyy-MM + * @return 所有的考勤班次的信息以及工作日信息等 + */ + @GetMapping("/getAllCheckWorkTime") + String getAllCheckWorkTime(@RequestParam("pointMonthDate") String pointMonthDate); + +} diff --git a/skyeye-wages/wages-pro/.gitignore b/skyeye-wages/wages-pro/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-wages/wages-pro/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wages/wages-pro/pom.xml b/skyeye-wages/wages-pro/pom.xml new file mode 100644 index 0000000..558c83d --- /dev/null +++ b/skyeye-wages/wages-pro/pom.xml @@ -0,0 +1,24 @@ + + + + skyeye-wages + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wages-pro + + + + + com.skyeye + wages-entity + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/classenum/WagesTypeEnum.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/classenum/WagesTypeEnum.java new file mode 100644 index 0000000..761efda --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/classenum/WagesTypeEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: WagesTypeEnum + * @Description: 薪资字段类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum WagesTypeEnum implements SkyeyeEnumClass { + + SALARY_INCREASE(1, "薪资增加", true, true), + SALARY_REDUCTION(2, "薪资减少", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/FieldStaffLinkController.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/FieldStaffLinkController.java new file mode 100644 index 0000000..04bdd30 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/FieldStaffLinkController.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.entity.wages.WagesStaffWorkTimeMation; +import com.skyeye.eve.field.service.FieldStaffLinkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: FieldStaffLinkController + * @Description: 员工与薪资字段关系管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/4 14:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "员工与薪资字段关系管理", tags = "员工与薪资字段关系管理", modelName = "员工与薪资字段关系管理") +public class FieldStaffLinkController { + + @Autowired + private FieldStaffLinkService wagesStaffMationService; + + /** + * 根据员工id获取该员工拥有的薪资字段 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagesstaff002", value = "根据员工id获取该员工拥有的薪资字段", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required")}) + @RequestMapping("/post/WagesStaffMationController/queryStaffWagesModelFieldMationListByStaffId") + public void queryStaffWagesModelFieldMationListByStaffId(InputObject inputObject, OutputObject outputObject) { + wagesStaffMationService.queryStaffWagesModelFieldMationListByStaffId(inputObject, outputObject); + } + + /** + * 保存员工薪资设定 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagesstaff003", value = "保存员工薪资设定", method = "POST", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "fieldStr", name = "fieldStr", value = "薪资信息", required = "required"), + @ApiImplicitParam(id = "actMoney", name = "actMoney", value = "员工月标准工资", required = "required,double")}) + @RequestMapping("/post/WagesStaffMationController/saveStaffWagesModelFieldMation") + public void saveStaffWagesModelFieldMation(InputObject inputObject, OutputObject outputObject) { + wagesStaffMationService.saveStaffWagesModelFieldMation(inputObject, outputObject); + } + + /** + * 获取应出勤的班次以及小时 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "setLastMonthBe", value = "获取应出勤的班次以及小时", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = WagesStaffWorkTimeMation.class) + @RequestMapping("/post/WagesStaffMationController/setLastMonthBe") + public void setLastMonthBe(InputObject inputObject, OutputObject outputObject) { + wagesStaffMationService.setLastMonthBe(inputObject, outputObject); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/WagesFieldTypeController.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/WagesFieldTypeController.java new file mode 100644 index 0000000..7a1614e --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/controller/WagesFieldTypeController.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.field.entity.FieldType; +import com.skyeye.eve.field.service.WagesFieldTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WagesFieldTypeController + * @Description: 薪资字段管理控制类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "薪资字段", tags = "薪资字段", modelName = "薪资字段") +public class WagesFieldTypeController { + + @Autowired + private WagesFieldTypeService wagesFieldTypeService; + + /** + * 获取薪资字段列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wages001", value = "获取薪资字段列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesFieldTypeController/queryWagesFieldTypeList") + public void queryWagesFieldTypeList(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑薪资字段信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWagesFieldTypeMation", value = "新增/编辑薪资字段信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = FieldType.class) + @RequestMapping("/post/WagesFieldTypeController/writeWagesFieldTypeMation") + public void writeWagesFieldTypeMation(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除薪资字段信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWagesFieldTypeMationById", value = "删除薪资字段信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WagesFieldTypeController/deleteWagesFieldTypeMationById") + public void deleteWagesFieldTypeMationById(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.deleteById(inputObject, outputObject); + } + + /** + * 获取已经启用的薪资字段列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryEnableWagesFieldTypeList", value = "获取已经启用的薪资字段列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesFieldTypeController/queryEnableWagesFieldTypeList") + public void queryEnableWagesFieldTypeList(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.queryEnableWagesFieldTypeList(inputObject, outputObject); + } + + /** + * 获取系统薪资字段列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "querySysWagesFieldTypeList", value = "获取系统薪资字段列表", method = "POST", allUse = "2") + @RequestMapping("/post/WagesFieldTypeController/querySysWagesFieldTypeList") + public void querySysWagesFieldTypeList(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.querySysWagesFieldTypeList(inputObject, outputObject); + } + + /** + * 根据字段key批量获取薪资字段信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryWagesFieldListByKeys", value = "根据字段key批量获取薪资字段信息", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "keys", name = "keys", value = "字段key,逗号隔开", required = "required")}) + @RequestMapping("/post/WagesFieldTypeController/queryWagesFieldListByKeys") + public void queryWagesFieldListByKeys(InputObject inputObject, OutputObject outputObject) { + wagesFieldTypeService.queryWagesFieldListByKeys(inputObject, outputObject); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/FieldStaffLinkDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/FieldStaffLinkDao.java new file mode 100644 index 0000000..d41122b --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/FieldStaffLinkDao.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.field.entity.FieldStaffLink; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FieldStaffLinkDao + * @Description: 员工与薪资字段关系管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface FieldStaffLinkDao extends SkyeyeBaseMapper { + + void saveStaffWagesModelFieldMation(@Param("list") List> wagesModelFieldMation); + + /** + * 获取一条还未计算上个月薪资的员工信息(不包含本月刚入职的新员工) + * + * @param lastMonthDate 上个月的年月 + * @param staffId 不包含的员工id + * @return + */ + Map queryNoWagesLastMonthByLastMonthDate(@Param("lastMonthDate") String lastMonthDate, @Param("list") List staffId); + + /** + * 获取上个月指定员工的所有考勤记录信息 + * + * @param staffId 员工id + * @param lastMonthDate 上个月的年月 + * @return + */ + List> queryLastMonthCheckWork(@Param("staffId") String staffId, @Param("lastMonthDate") String lastMonthDate); + + /** + * 获取上个月指定员工的所有审批通过请假记录信息 + * + * @param staffId 员工id + * @param lastMonthDate 上个月的年月 + * @return + */ + List> queryLastMonthLeaveTime(@Param("staffId") String staffId, @Param("lastMonthDate") String lastMonthDate); + + /** + * 获取上个月指定员工的所有审批通过销假记录信息 + * + * @param staffId 员工id + * @param lastMonthDate 上个月的年月 + * @return + */ + List> queryLastMonthCancleLeaveTime(@Param("staffId") String staffId, @Param("lastMonthDate") String lastMonthDate); + + /** + * 将指定员工月度清零的薪资字段设置为0 + * + * @param staffId 员工id + */ + void editStaffMonthlyClearingWagesByStaffId(@Param("staffId") String staffId); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/WagesFieldTypeDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/WagesFieldTypeDao.java new file mode 100644 index 0000000..05b0514 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/dao/WagesFieldTypeDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.field.entity.FieldType; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesFieldTypeDao + * @Description: 薪资字段管理数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesFieldTypeDao extends SkyeyeBaseMapper { + + List> queryWagesFieldTypeList(CommonPageInfo pageInfo); + + List> queryAllStaffMationList(); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldStaffLink.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldStaffLink.java new file mode 100644 index 0000000..7a9fb5f --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldStaffLink.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: FieldStaffLink + * @Description: 员工与薪资字段类型关系实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:18 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("员工与薪资字段类型关系实体类") +@TableName(value = "wages_field_staff_mation") +public class FieldStaffLink extends CommonInfo { + + @TableId("staff_id") + @ApiModelProperty(value = "员工id", required = "required") + private String staffId; + + @TableField("field_type_key") + @ApiModelProperty(value = "薪资字段key", required = "required") + private String fieldTypeKey; + + @TableField(value = "amount_money") + @ApiModelProperty(value = "员工与薪资字段类型对应的钱", required = "required,double") + private String amountMoney; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldType.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldType.java new file mode 100644 index 0000000..5d913cf --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/entity/FieldType.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: FieldType + * @Description: 薪资字段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:18 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("薪资字段实体类") +@UniqueField(value = {"key"}) +@TableName(value = "wages_field_type") +@RedisCacheField(name = CacheConstants.WAGES_FIELD_CACHE_KEY) +public class FieldType extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名称", required = "required") + private String name; + + @TableField(value = "`key`", fill = FieldFill.INSERT) + @ApiModelProperty(value = "key,可以用于区分字段内容,用于后面公式计算", required = "required") + private String key; + + @TableField("monthly_clearing") + @ApiModelProperty(value = "是否每月统计上月薪资时,该字段自动清零,参考#IsDefaultEnum", required = "required,num") + private Integer monthlyClearing; + + @TableField("wages_type") + @ApiModelProperty(value = "薪资字段类型,参考#WagesTypeEnum", required = "required,num") + private Integer wagesType; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/FieldStaffLinkService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/FieldStaffLinkService.java new file mode 100644 index 0000000..e12266c --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/FieldStaffLinkService.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.field.entity.FieldStaffLink; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: FieldStaffLinkService + * @Description: 员工与薪资字段关系管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/4 13:33 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface FieldStaffLinkService extends SkyeyeBusinessService { + + void queryStaffWagesModelFieldMationListByStaffId(InputObject inputObject, OutputObject outputObject); + + void saveStaffWagesModelFieldMation(InputObject inputObject, OutputObject outputObject); + + void setLastMonthBe(InputObject inputObject, OutputObject outputObject); + + /** + * 设置应出勤的班次以及小时 + * + * @param staffWorkTime 员工对应的考勤班次 + * @param lastMonthDate 指定年月,格式为yyyy-MM + * @return 员工拥有的所有薪资要素字段以及对应的值 + */ + Map setLastMonthBe(List> staffWorkTime, String lastMonthDate); + + /** + * 修改员工关联薪资字段的key + * + * @param oldKey 旧薪资字段的key + * @param newKey 新薪资字段的key + */ + void updateStaffFiledKey(String oldKey, String newKey); + + /** + * 删除员工关联薪资字段的key + * + * @param key 薪资字段的key + */ + void deleteStaffFiledKey(String key); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/WagesFieldTypeService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/WagesFieldTypeService.java new file mode 100644 index 0000000..324fe41 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/WagesFieldTypeService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.field.entity.FieldType; + +import java.util.Map; + +/** + * @ClassName: WagesFieldTypeService + * @Description: 薪资字段管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesFieldTypeService extends SkyeyeBusinessService { + + void queryEnableWagesFieldTypeList(InputObject inputObject, OutputObject outputObject); + + void querySysWagesFieldTypeList(InputObject inputObject, OutputObject outputObject); + + void queryWagesFieldListByKeys(InputObject inputObject, OutputObject outputObject); + + Map queryAllFieldTypeMap(); +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/FieldStaffLinkServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/FieldStaffLinkServiceImpl.java new file mode 100644 index 0000000..80d5464 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/FieldStaffLinkServiceImpl.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.WagesConstant; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.entity.wages.WagesStaffWorkTimeMation; +import com.skyeye.eve.field.classenum.WagesTypeEnum; +import com.skyeye.eve.field.dao.FieldStaffLinkDao; +import com.skyeye.eve.field.entity.FieldStaffLink; +import com.skyeye.eve.field.service.FieldStaffLinkService; +import com.skyeye.eve.model.dao.WagesModelDao; +import com.skyeye.eve.model.dao.WagesModelFieldDao; +import com.skyeye.eve.service.IScheduleDayService; +import com.skyeye.rest.staff.service.ISysUserStaffService; +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 java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: FieldStaffLinkServiceImpl + * @Description: 员工与薪资字段关系管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:18 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "员工与薪资字段关系管理", groupName = "员工与薪资字段关系管理") +public class FieldStaffLinkServiceImpl extends SkyeyeBusinessServiceImpl implements FieldStaffLinkService { + + private static Logger log = LoggerFactory.getLogger(FieldStaffLinkServiceImpl.class); + + @Autowired + private WagesModelDao wagesModelDao; + + @Autowired + private WagesModelFieldDao wagesModelFieldDao; + + @Autowired + private IScheduleDayService iScheduleDayService; + + @Autowired + private ISysUserStaffService iSysUserStaffService; + + /** + * 根据员工id获取该员工拥有的薪资字段 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryStaffWagesModelFieldMationListByStaffId(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(Arrays.asList(staffId)); + Map staffMation = staffMap.get(staffId); + List wagesApplicableObject = Arrays.asList(new String[]{ + staffMation.get("companyId").toString(), + staffMation.get("departmentId").toString(), + staffId}); + List> modelField = new ArrayList<>(); + // 1.获取薪资模板 + List> model = wagesModelDao.queryWagesModelListByApplicableObjectIds(wagesApplicableObject); + if (CollectionUtil.isNotEmpty(model)) { + // 2.获取模板参数 + List modelIds = model.stream().map(p -> p.get("id").toString()).collect(Collectors.toList()); + modelField = wagesModelFieldDao.queryWagesModelFieldByModelIdsAndStaffId(modelIds, staffId, staffMation.get("jobScoreId").toString()); + } + modelField.stream().forEach(bean -> { + if ("1".equals(bean.get("monthlyClearing").toString())) { + // 如果是自动清零,则不可进行薪资编辑 + bean.put("disabled", "disabled"); + } + Integer wagesType = Integer.parseInt(bean.get("wagesType").toString()); + if (WagesTypeEnum.SALARY_INCREASE.getKey().equals(wagesType)) { + bean.put("wagesTypeStr", WagesTypeEnum.SALARY_INCREASE.getValue()); + } else { + bean.put("wagesTypeStr", WagesTypeEnum.SALARY_REDUCTION.getValue()); + } + }); + outputObject.setBeans(modelField); + outputObject.settotal(modelField.size()); + } + + /** + * 保存员工薪资设定 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + @Transactional(value = TRANSACTION_MANAGER_VALUE, rollbackFor = Exception.class) + public void saveStaffWagesModelFieldMation(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String fieldStr = map.get("fieldStr").toString(); + List> wagesModelFieldMation = JSONUtil.toList(JSONUtil.parseArray(fieldStr), null); + // 保存薪资要素字段信息 + skyeyeBaseMapper.saveStaffWagesModelFieldMation(wagesModelFieldMation); + // 保存员工月标准薪资信息以及设定状态 + iSysUserStaffService.editSysUserStaffActMoneyById(staffId, map.get("actMoney").toString()); + } + + /** + * 获取应出勤的班次以及小时 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void setLastMonthBe(InputObject inputObject, OutputObject outputObject) { + WagesStaffWorkTimeMation wagesStaffWorkTimeMation = inputObject.getParams(WagesStaffWorkTimeMation.class); + Map staffModelFieldMap = this.setLastMonthBe(wagesStaffWorkTimeMation.getStaffWorkTime(), + wagesStaffWorkTimeMation.getLastMonthDate()); + outputObject.setBean(staffModelFieldMap); + } + + /** + * 设置应出勤的班次以及小时 + * + * @param staffWorkTime 员工对应的考勤班次 + * @param lastMonthDate 指定年月,格式为yyyy-MM + * @return 员工拥有的所有薪资要素字段以及对应的值 + */ + @Override + public Map setLastMonthBe(List> staffWorkTime, String lastMonthDate) { + List lastMonthDays = DateUtil.getMonthFullDay(Integer.parseInt(lastMonthDate.split("-")[0]), Integer.parseInt(lastMonthDate.split("-")[1])); + int lastMonthBeNum = 0; + String lastMonthBeHour = "0"; + for (Map bean : staffWorkTime) { + List> days = (List>) bean.get("checkWorkTimeWeekList"); + for (String day : lastMonthDays) { + // 周几 + if (iScheduleDayService.judgeISHoliday(day)) { + // 如果是节假日,则不计算 + continue; + } + int weekDay = DateUtil.getWeek(day); + int weekType = DateUtil.getWeekType(day); + List> simpleDay = days.stream().filter(item -> Integer.parseInt(item.get("weekNumber").toString()) == weekDay) + .collect(Collectors.toList()); + if (simpleDay != null && !simpleDay.isEmpty()) { + // 如果今天是需要考勤的日期 + int dayType = Integer.parseInt(simpleDay.get(0).get("type").toString()); + if (weekType == 1 && dayType == 2) { + // 如果获取到的日期是双周,但考勤班次里面是单周,则不做任何操作 + } else { + // 单周或者每周的当天都上班 + lastMonthBeNum++; + try { + String time = DateUtil.getDistanceMinuteByHMS(bean.get("startTime").toString(), bean.get("endTime").toString()); + lastMonthBeHour = CalculationUtil.add(lastMonthBeHour, time, 2); + } catch (Exception e) { + log.warn("get differ time failed, startTime is: {}, endTime is: {}", bean.get("startTime").toString(), + bean.get("endTime").toString(), e); + } + } + } + } + } + Map staffModelFieldMap = new HashMap<>(); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_NUM.getKey(), String.valueOf(lastMonthBeNum)); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey(), CalculationUtil.divide(lastMonthBeHour, "60", 2)); + return staffModelFieldMap; + } + + @Override + public void updateStaffFiledKey(String oldKey, String newKey) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + String keyField = MybatisPlusUtil.toColumns(FieldStaffLink::getFieldTypeKey); + updateWrapper.eq(keyField, oldKey); + updateWrapper.set(keyField, newKey); + update(updateWrapper); + } + + @Override + public void deleteStaffFiledKey(String key) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(FieldStaffLink::getFieldTypeKey), key); + remove(queryWrapper); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/WagesFieldTypeServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/WagesFieldTypeServiceImpl.java new file mode 100644 index 0000000..acd0af0 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/field/service/impl/WagesFieldTypeServiceImpl.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.field.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.WagesConstant; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.field.dao.WagesFieldTypeDao; +import com.skyeye.eve.field.entity.FieldStaffLink; +import com.skyeye.eve.field.entity.FieldType; +import com.skyeye.eve.field.service.FieldStaffLinkService; +import com.skyeye.eve.field.service.WagesFieldTypeService; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WagesFieldTypeServiceImpl + * @Description: 薪资字段管理服务层 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:11 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "薪资字段", groupName = "薪资字段") +public class WagesFieldTypeServiceImpl extends SkyeyeBusinessServiceImpl implements WagesFieldTypeService { + + @Autowired + private FieldStaffLinkService fieldStaffLinkService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryWagesFieldTypeList(pageInfo); + return beans; + } + + @Override + public void validatorEntity(FieldType entity) { + // 和系统默认的key做比较 + Map defaultKey = WagesConstant.DEFAULT_WAGES_FIELD_TYPE.getList().stream() + .filter(item -> entity.getKey().equals(item.get("key").toString())).findFirst().orElse(null); + // 操作的key在默认定义的key中是否包含 + if (CollectionUtil.isNotEmpty(defaultKey)) { + throw new CustomException("this ['key'] is Already exists simple default key."); + } + super.validatorEntity(entity); + } + + @Override + public void createPostpose(FieldType entity, String userId) { + // 保存完字段信息后,为每个员工加上该薪资字段 + insertWagesFieldTypeKeyToStaff(entity.getKey()); + } + + private void insertWagesFieldTypeKeyToStaff(String key) { + List> staff = skyeyeBaseMapper.queryAllStaffMationList(); + List fieldStaffLinkList = new ArrayList<>(); + staff.forEach(bean -> { + FieldStaffLink fieldStaffLink = new FieldStaffLink(); + fieldStaffLink.setStaffId(bean.get("id").toString()); + fieldStaffLink.setFieldTypeKey(key); + fieldStaffLinkList.add(fieldStaffLink); + }); + fieldStaffLinkService.saveOrUpdateEntity(fieldStaffLinkList, StrUtil.EMPTY, true); + } + + @Override + public void updatePrepose(FieldType entity) { + FieldType oldBean = selectById(entity.getId()); + if (!StrUtil.equals(oldBean.getKey(), entity.getKey())) { + // 修改员工之前绑定的薪资字段key + fieldStaffLinkService.updateStaffFiledKey(oldBean.getKey(), entity.getKey()); + } + } + + @Override + public void deletePostpose(FieldType entity) { + // 删除员工绑定的薪资字段key + fieldStaffLinkService.deleteStaffFiledKey(entity.getKey()); + } + + /** + * 获取已经启用的薪资字段列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryEnableWagesFieldTypeList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + pageInfo.setEnabled(EnableEnum.ENABLE_USING.getKey()); + List> beans = skyeyeBaseMapper.queryWagesFieldTypeList(pageInfo); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + @Override + public void querySysWagesFieldTypeList(InputObject inputObject, OutputObject outputObject) { + List> beans = WagesConstant.DEFAULT_WAGES_FIELD_TYPE.getList(); + outputObject.setBeans(beans); + outputObject.settotal(beans.size()); + } + + /** + * 根据字段key批量获取薪资字段信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryWagesFieldListByKeys(InputObject inputObject, OutputObject outputObject) { + String keys = inputObject.getParams().get("keys").toString(); + List keyList = Arrays.asList(keys.split(CommonCharConstants.COMMA_MARK)); + keyList = keyList.stream().filter(str -> !ToolUtil.isBlank(str)).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(keyList)) { + return; + } + // 从数据库中获取 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(FieldType::getKey), keyList); + List fieldTypeList = list(queryWrapper); + // 从枚举中获取 + List finalKeyList = keyList; + WagesConstant.DEFAULT_WAGES_FIELD_TYPE.getList().stream() + .filter(bean -> finalKeyList.contains(bean.get("key").toString())) + .forEach(bean -> { + FieldType fieldType = new FieldType(); + fieldType.setKey(bean.get("key").toString()); + fieldType.setName(bean.get("name").toString()); + fieldTypeList.add(fieldType); + }); + outputObject.setBeans(fieldTypeList); + outputObject.settotal(fieldTypeList.size()); + } + + @Override + public Map queryAllFieldTypeMap() { + List fieldTypes = list(); + return fieldTypes.stream().collect(Collectors.toMap(FieldType::getKey, bean -> bean)); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/classenum/WagesModelFieldType.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/classenum/WagesModelFieldType.java new file mode 100644 index 0000000..9aa07da --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/classenum/WagesModelFieldType.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: WagesModelFieldType + * @Description: 模板关联字段的字段类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2023/2/26 12:09 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum WagesModelFieldType implements SkyeyeEnumClass { + + FIELD(1, "字段", true, true), + ADD(2, "增加", true, false), + REDUCE(3, "减少", true, false), + ADD_ACTUAL(4, "仅实发增加", true, false), + REDUCE_ACTUAL(5, "仅实发减少", true, false), + ADD_PAYABLE(6, "仅应发增加", true, false), + REDUCE_PAYABLE(7, "仅应发减少", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/controller/WagesModelController.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/controller/WagesModelController.java new file mode 100644 index 0000000..a8154b7 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/controller/WagesModelController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.model.entity.WagesModel; +import com.skyeye.eve.model.service.WagesModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WagesModelController + * @Description: 薪资模板控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 11:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "薪资模板", tags = "薪资模板", modelName = "薪资模板") +public class WagesModelController { + + @Autowired + private WagesModelService wagesModelService; + + /** + * 获取薪资模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagesmodel001", value = "获取薪资模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesModelController/queryWagesModelList") + public void queryWagesModelList(InputObject inputObject, OutputObject outputObject) { + wagesModelService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑薪资模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWagesModel", value = "新增/编辑薪资模板信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = WagesModel.class) + @RequestMapping("/post/WagesModelController/writeWagesModel") + public void writeWagesModel(InputObject inputObject, OutputObject outputObject) { + wagesModelService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除薪资模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWagesModelById", value = "删除薪资模板信息", method = "DELETE", allUse = "1") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WagesModelController/deleteWagesModelById") + public void deleteWagesModelById(InputObject inputObject, OutputObject outputObject) { + wagesModelService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/CompanyTaxRateDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/CompanyTaxRateDao.java new file mode 100644 index 0000000..75c1c7a --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/CompanyTaxRateDao.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.dao; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CompanyTaxRateDao + * @Description: 企业个人所得税缴纳比例 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/8 22:10 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CompanyTaxRateDao { + + List> queryAllCompanyTaxRate(); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/ModelApplicableObjectsDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/ModelApplicableObjectsDao.java new file mode 100644 index 0000000..3b19ea8 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/ModelApplicableObjectsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.model.entity.ModelApplicableObjects; + +/** + * @ClassName: ModelApplicableObjectsDao + * @Description: 薪资模板适用对象数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 13:30 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ModelApplicableObjectsDao extends SkyeyeBaseMapper { + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/SysEveUserStaffDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/SysEveUserStaffDao.java new file mode 100644 index 0000000..3787b1f --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/SysEveUserStaffDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.dao; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: SysEveUserStaffDao + * @Description: 员工信息类----后期改为调rest服务 + * @author: skyeye云系列--卫志强 + * @date: 2022/8/8 22:12 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface SysEveUserStaffDao { + + List> queryStaffCheckWorkTimeRelationByStaffId(@Param("staffId") String staffId); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelDao.java new file mode 100644 index 0000000..20284a3 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelDao.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.model.entity.WagesModel; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesModelDao + * @Description: 薪资模板数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 11:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface WagesModelDao extends SkyeyeBaseMapper { + + List> queryWagesModelList(CommonPageInfo pageInfo); + + List> queryWagesModelListByApplicableObjectIds(@Param("list") List wagesApplicableObjectIds); +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelFieldDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelFieldDao.java new file mode 100644 index 0000000..88fd8a9 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/dao/WagesModelFieldDao.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.model.entity.WagesModelField; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesModelFieldDao + * @Description: 薪资模板关联的字段数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 14:03 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface WagesModelFieldDao extends SkyeyeBaseMapper { + + /** + * 获取指定员工用有的薪资模板对应的薪资要素字段信息,如果薪资模板中有重复的薪资要素字段,则根据薪资要素字段的key进行分组 + * + * @param modelIds 该员工拥有的薪资模板id集合 + * @param staffId 员工id + * @param jobScoreId 职位定级id + * @return 薪资要素字段信息,该员工的薪资信息以及对应的薪资描述薪资 + */ + public List> queryWagesModelFieldByModelIdsAndStaffId(@Param("list") List modelIds, + @Param("staffId") String staffId, + @Param("jobScoreId") String jobScoreId); +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/ModelApplicableObjects.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/ModelApplicableObjects.java new file mode 100644 index 0000000..dbe46fa --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/ModelApplicableObjects.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ModelApplicableObjects + * @Description: 薪资模板适用对象实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("薪资模板适用对象实体类") +@TableName(value = "wages_model_applicable_objects") +public class ModelApplicableObjects extends CommonInfo { + + @TableField("model_id") + @Property(value = "模板id") + private String modelId; + + @TableField("object_id") + @ApiModelProperty(value = "适用对象id", required = "required") + private String objectId; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField("object_type") + @ApiModelProperty(value = "适用对象类型,参考#ApplicableObjectsType", required = "required,num") + private Integer objectType; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModel.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModel.java new file mode 100644 index 0000000..7b69b95 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModel.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: WagesModel + * @Description: 薪资模板 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 11:08 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("薪资模板实体类") +@UniqueField +@TableName(value = "wages_model") +@RedisCacheField(name = CacheConstants.WAGES_MODEL_CACHE_KEY) +public class WagesModel extends BaseGeneralInfo { + + @TableField(value = "type_id") + @ApiModelProperty(value = "模板类型,数据来源数据字典", required = "required") + private String typeId; + + @TableField(value = "start_time") + @ApiModelProperty(value = "开始日期", required = "required") + private String startTime; + + @TableField(value = "end_time") + @ApiModelProperty(value = "结束日期", required = "required") + private String endTime; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField(exist = false) + @ApiModelProperty(value = "适用对象", required = "json") + private List applicableObjectsList; + + @TableField(exist = false) + @ApiModelProperty(value = "模板关联的薪资字段", required = "required,json") + private List wagesModelFieldList; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModelField.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModelField.java new file mode 100644 index 0000000..f248eec --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/entity/WagesModelField.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import com.skyeye.eve.field.entity.FieldType; +import lombok.Data; + +/** + * @ClassName: WagesModelField + * @Description: 薪资模板关联的字段实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 13:51 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("薪资模板关联的字段实体类") +@TableName(value = "wages_model_field") +public class WagesModelField extends CommonInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("model_id") + @Property(value = "模板id") + private String modelId; + + @TableField("field_key") + @ApiModelProperty(value = "字段key", required = "required") + private String fieldKey; + + @TableField(exist = false) + @Property(value = "字段信息") + private FieldType fieldKeyMation; + + @TableField("field_type") + @ApiModelProperty(value = "字段类型,参考#WagesModelFieldType", required = "required,num") + private Integer fieldType; + + @TableField("default_money") + @ApiModelProperty(value = "默认金额", required = "double", defaultValue = "0") + private String defaultMoney; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField("formula") + @ApiModelProperty(value = "公式,用于计算该薪资字段金额") + private String formula; + + @TableField(value = "remark") + @ApiModelProperty(value = "相关描述") + private String remark; + + @TableField(exist = false) + @Property(value = "转换的值") + private String moneyValue; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/ModelApplicableObjectsService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/ModelApplicableObjectsService.java new file mode 100644 index 0000000..00a779a --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/ModelApplicableObjectsService.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.model.entity.ModelApplicableObjects; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ModelApplicableObjectsService + * @Description: 薪资模板适用对象服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 13:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ModelApplicableObjectsService extends SkyeyeBusinessService { + void deleteApplicableObjectsByPId(String modelId); + + void saveApplicableObjects(String modelId, List applicableObjectsList); + + List queryApplicableObjectsByPId(String modelId); + + Map> queryApplicableObjectsByPId(List modelId); +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelFieldService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelFieldService.java new file mode 100644 index 0000000..4dc4629 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelFieldService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.model.entity.WagesModelField; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesModelFieldService + * @Description: 薪资模板关联的字段服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 14:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface WagesModelFieldService extends SkyeyeBusinessService { + + void deleteModelFieldByPId(String modelId); + + void saveModelField(String modelId, List modelFieldList); + + List queryModelFieldByPId(String modelId); + + Map> queryModelFieldByPId(List modelId); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelService.java new file mode 100644 index 0000000..c65f933 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/WagesModelService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.model.entity.WagesModel; + +import java.util.List; + +/** + * @ClassName: WagesModelService + * @Description: 薪资模板服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 11:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface WagesModelService extends SkyeyeBusinessService { + + /** + * 根据日期查找已经启用&&指定日期有效的薪资模板信息 + * + * @param date + * @return + */ + List queryWagesModelByDate(String date); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/ModelApplicableObjectsServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/ModelApplicableObjectsServiceImpl.java new file mode 100644 index 0000000..ff61759 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/ModelApplicableObjectsServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.model.dao.ModelApplicableObjectsDao; +import com.skyeye.eve.model.entity.ModelApplicableObjects; +import com.skyeye.eve.model.service.ModelApplicableObjectsService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ModelApplicableObjectsServiceImpl + * @Description: 薪资模板适用对象服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 13:29 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "薪资模板适用对象管理", groupName = "薪资模板适用对象管理", manageShow = false) +public class ModelApplicableObjectsServiceImpl extends SkyeyeBusinessServiceImpl implements ModelApplicableObjectsService { + + @Override + public void deleteApplicableObjectsByPId(String modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ModelApplicableObjects::getModelId), modelId); + remove(queryWrapper); + } + + @Override + public void saveApplicableObjects(String modelId, List applicableObjectsList) { + deleteApplicableObjectsByPId(modelId); + if (CollectionUtil.isNotEmpty(applicableObjectsList)) { + for (ModelApplicableObjects applicableObjects : applicableObjectsList) { + applicableObjects.setModelId(modelId); + } + createEntity(applicableObjectsList, StrUtil.EMPTY); + } + } + + @Override + public List queryApplicableObjectsByPId(String modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ModelApplicableObjects::getModelId), modelId); + List applicableObjectsList = list(queryWrapper); + return applicableObjectsList; + } + + @Override + public Map> queryApplicableObjectsByPId(List modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ModelApplicableObjects::getModelId), modelId); + List applicableObjectsList = list(queryWrapper); + Map> listMap = applicableObjectsList.stream() + .collect(Collectors.groupingBy(ModelApplicableObjects::getModelId)); + return listMap; + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelFieldServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelFieldServiceImpl.java new file mode 100644 index 0000000..438f250 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelFieldServiceImpl.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.model.dao.WagesModelFieldDao; +import com.skyeye.eve.model.entity.WagesModelField; +import com.skyeye.eve.model.service.WagesModelFieldService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WagesModelFieldServiceImpl + * @Description: 薪资模板关联的字段服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 14:03 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "薪资模板关联的字段管理", groupName = "薪资模板关联的字段管理", manageShow = false) +public class WagesModelFieldServiceImpl extends SkyeyeBusinessServiceImpl implements WagesModelFieldService { + + @Override + public void deleteModelFieldByPId(String modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesModelField::getModelId), modelId); + remove(queryWrapper); + } + + @Override + public void saveModelField(String modelId, List wagesModelFields) { + deleteModelFieldByPId(modelId); + if (CollectionUtil.isNotEmpty(wagesModelFields)) { + for (WagesModelField modelField : wagesModelFields) { + modelField.setModelId(modelId); + } + createEntity(wagesModelFields, StrUtil.EMPTY); + } + } + + @Override + public List queryModelFieldByPId(String modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesModelField::getModelId), modelId); + List wagesModelFields = list(queryWrapper); + return wagesModelFields; + } + + @Override + public Map> queryModelFieldByPId(List modelId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(WagesModelField::getModelId), modelId); + List wagesModelFields = list(queryWrapper); + Map> listMap = wagesModelFields.stream() + .collect(Collectors.groupingBy(WagesModelField::getModelId)); + return listMap; + } +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelServiceImpl.java new file mode 100644 index 0000000..5ab46c7 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/model/service/impl/WagesModelServiceImpl.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.model.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.WagesConstant; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.ApplicableObjectsType; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.field.entity.FieldType; +import com.skyeye.eve.field.service.WagesFieldTypeService; +import com.skyeye.eve.model.dao.WagesModelDao; +import com.skyeye.eve.model.entity.ModelApplicableObjects; +import com.skyeye.eve.model.entity.WagesModel; +import com.skyeye.eve.model.entity.WagesModelField; +import com.skyeye.eve.model.service.ModelApplicableObjectsService; +import com.skyeye.eve.model.service.WagesModelFieldService; +import com.skyeye.eve.model.service.WagesModelService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WagesModelServiceImpl + * @Description: 薪资模板服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/21 11:19 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +@SkyeyeService(name = "薪资模板", groupName = "薪资模板") +public class WagesModelServiceImpl extends SkyeyeBusinessServiceImpl implements WagesModelService { + + @Autowired + private ModelApplicableObjectsService modelApplicableObjectsService; + + @Autowired + private WagesModelFieldService wagesModelFieldService; + + @Autowired + private WagesFieldTypeService wagesFieldTypeService; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryWagesModelList(pageInfo); + return beans; + } + + @Override + public void writePostpose(WagesModel entity, String userId) { + super.writePostpose(entity, userId); + // 保存适用对象 + modelApplicableObjectsService.saveApplicableObjects(entity.getId(), entity.getApplicableObjectsList()); + // 保存关联的字段 + wagesModelFieldService.saveModelField(entity.getId(), entity.getWagesModelFieldList()); + } + + @Override + public void deletePostpose(String id) { + // 删除适用对象 + modelApplicableObjectsService.deleteApplicableObjectsByPId(id); + // 删除关联的字段 + wagesModelFieldService.deleteModelFieldByPId(id); + } + + @Override + public WagesModel getDataFromDb(String id) { + WagesModel wagesModel = super.getDataFromDb(id); + // 适用对象信息 + List applicableObjectsList = modelApplicableObjectsService.queryApplicableObjectsByPId(id); + wagesModel.setApplicableObjectsList(applicableObjectsList); + // 关联的字段 + List wagesModelFields = wagesModelFieldService.queryModelFieldByPId(id); + wagesModel.setWagesModelFieldList(wagesModelFields); + return wagesModel; + } + + @Override + protected List getDataFromDb(List idList) { + List wagesModels = super.getDataFromDb(idList); + // 适用对象信息 + Map> applicableObjectsMap = modelApplicableObjectsService.queryApplicableObjectsByPId(idList); + wagesModels.forEach(wagesModel -> { + wagesModel.setApplicableObjectsList(applicableObjectsMap.get(wagesModel.getId())); + }); + // 关联的字段 + Map> modelFieldMap = wagesModelFieldService.queryModelFieldByPId(idList); + wagesModels.forEach(wagesModel -> { + wagesModel.setWagesModelFieldList(modelFieldMap.get(wagesModel.getId())); + }); + return wagesModels; + } + + @Override + public WagesModel selectById(String id) { + WagesModel wagesModel = super.selectById(id); + // 设置适用对象信息 + List applicableObjectsList = wagesModel.getApplicableObjectsList(); + setApplicable(applicableObjectsList); + // 设置关联的字段信息 + Map fieldTypeMap = wagesFieldTypeService.queryAllFieldTypeMap(); + setFieldType(wagesModel, fieldTypeMap); + return wagesModel; + } + + @Override + public List selectByIds(String... ids) { + List wagesModels = super.selectByIds(ids); + // 设置适用对象信息 + wagesModels.forEach(wagesModel -> { + List applicableObjectsList = wagesModel.getApplicableObjectsList(); + setApplicable(applicableObjectsList); + }); + + // 设置关联的字段信息 + Map fieldTypeMap = wagesFieldTypeService.queryAllFieldTypeMap(); + wagesModels.forEach(wagesModel -> { + setFieldType(wagesModel, fieldTypeMap); + }); + return wagesModels; + } + + private void setApplicable(List applicableObjectsList) { + if (CollectionUtil.isNotEmpty(applicableObjectsList)) { + Map> listMap = applicableObjectsList.stream() + .collect(Collectors.groupingBy(ModelApplicableObjects::getObjectType)); + listMap.forEach((key, value) -> { + List ids = value.stream().map(ModelApplicableObjects::getObjectId).collect(Collectors.toList()); + if (ApplicableObjectsType.STAFF.getKey().equals(key)) { + // 员工 + Map> staffMaps = iAuthUserService.queryUserMationListByStaffIds(ids); + setObjectMation(applicableObjectsList, staffMaps, key); + } else if (ApplicableObjectsType.DEPARTMENT.getKey().equals(key)) { + // 部门 + String departmentIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(ids); + Map> departMent = iDepmentService.queryDataMationForMapByIds(departmentIdStr); + setObjectMation(applicableObjectsList, departMent, key); + } else if (ApplicableObjectsType.COMPANY.getKey().equals(key)) { + // 企业 + String companyIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(ids); + Map> company = iCompanyService.queryDataMationForMapByIds(companyIdStr); + setObjectMation(applicableObjectsList, company, key); + } + }); + } + } + + private static void setFieldType(WagesModel wagesModel, Map fieldTypeMap) { + if (CollectionUtil.isNotEmpty(wagesModel.getWagesModelFieldList())) { + wagesModel.getWagesModelFieldList().forEach(wagesModelField -> { + FieldType fieldType = fieldTypeMap.get(wagesModelField.getFieldKey()); + if (ObjectUtil.isEmpty(fieldType)) { + fieldType = new FieldType(); + String name = WagesConstant.DEFAULT_WAGES_FIELD_TYPE.getNameByKey(wagesModelField.getFieldKey()); + fieldType.setName(name); + } + wagesModelField.setFieldKeyMation(fieldType); + }); + } + } + + private static void setObjectMation(List applicableObjectsList, Map> temMap, Integer key) { + if (CollectionUtil.isEmpty(temMap)) { + return; + } + applicableObjectsList.forEach(applicableObjects -> { + if (key.equals(applicableObjects.getObjectType())) { + applicableObjects.setObjectMation(temMap.get(applicableObjects.getObjectId())); + } + }); + } + + @Override + public List queryWagesModelByDate(String date) { + if (StrUtil.isEmpty(date)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.apply("date_format(" + MybatisPlusUtil.toColumns(WagesModel::getStartTime) + ", '%Y-%m') <= date_format({0}, '%Y-%m')", date) + .apply("date_format(" + MybatisPlusUtil.toColumns(WagesModel::getEndTime) + ", '%Y-%m') >= date_format({0}, '%Y-%m')", date); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesModel::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List wagesModelList = list(queryWrapper); + List ids = wagesModelList.stream().map(WagesModel::getId).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(ids)) { + return CollectionUtil.newArrayList(); + } + List wagesModels = selectByIds(ids.toArray(new String[]{})); + return wagesModels; + } +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryState.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryState.java new file mode 100644 index 0000000..daf8f5f --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryState.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PaymentHistoryState + * @Description: 薪资发放状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 17:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PaymentHistoryState implements SkyeyeEnumClass { + + UNISSUED(1, "未发放", true, true), + ISSUED(2, "已发放", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryType.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryType.java new file mode 100644 index 0000000..7a99175 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/classenum/PaymentHistoryType.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: PaymentHistoryType + * @Description: 薪资核算类型枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 17:20 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum PaymentHistoryType implements SkyeyeEnumClass { + + MANUAL_ACCOUNTING(1, "人工核算", true, true), + SYSTEM_ACCOUNTING(2, "系统核算", true, false); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/controller/WagesPaymentHistoryController.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/controller/WagesPaymentHistoryController.java new file mode 100644 index 0000000..b314174 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/controller/WagesPaymentHistoryController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.payment.service.WagesPaymentHistoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WagesPaymentHistoryController + * @Description: 薪资发放历史管理控制层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 18:11 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@RestController +@Api(value = "薪资发放历史", tags = "薪资发放历史", modelName = "薪资发放历史") +public class WagesPaymentHistoryController { + + @Autowired + private WagesPaymentHistoryService wagesPaymentHistoryService; + + /** + * 获取所有已发放薪资发放历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagespaymenthistory001", value = "获取所有已发放薪资发放历史列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesPaymentHistoryController/queryAllGrantWagesPaymentHistoryList") + public void queryAllGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + wagesPaymentHistoryService.queryAllGrantWagesPaymentHistoryList(inputObject, outputObject); + } + + /** + * 获取我的薪资发放历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagespaymenthistory002", value = "获取我的薪资发放历史列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesPaymentHistoryController/queryMyWagesPaymentHistoryList") + public void queryMyWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + wagesPaymentHistoryService.queryMyWagesPaymentHistoryList(inputObject, outputObject); + } + + /** + * 获取所有待发放薪资列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagespaymenthistory003", value = "获取所有待发放薪资列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesPaymentHistoryController/queryAllNotGrantWagesPaymentHistoryList") + public void queryAllNotGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + wagesPaymentHistoryService.queryAllNotGrantWagesPaymentHistoryList(inputObject, outputObject); + } + + /** + * 获取员工薪资条薪资 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryWagesStaffPaymentDetail", value = "获取员工薪资条薪资", method = "GET", allUse = "2") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "staffId", name = "staffId", value = "员工id", required = "required"), + @ApiImplicitParam(id = "payMonth", name = "payMonth", value = "薪资月份", required = "required")}) + @RequestMapping("/post/WagesPaymentHistoryController/queryWagesStaffPaymentDetail") + public void queryWagesStaffPaymentDetail(InputObject inputObject, OutputObject outputObject) { + wagesPaymentHistoryService.queryWagesStaffPaymentDetail(inputObject, outputObject); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/dao/WagesPaymentHistoryDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/dao/WagesPaymentHistoryDao.java new file mode 100644 index 0000000..93e99cf --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/dao/WagesPaymentHistoryDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.payment.entity.WagesPaymentHistory; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesPaymentHistoryDaow + * @Description: 薪资发放历史管理数据层 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:35 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesPaymentHistoryDao extends SkyeyeBaseMapper { + + List> queryWagesPaymentHistoryList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/entity/WagesPaymentHistory.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/entity/WagesPaymentHistory.java new file mode 100644 index 0000000..5348a53 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/entity/WagesPaymentHistory.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesPaymentHistory + * @Description: 薪资发放历史实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 17:12 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Data +@ApiModel("薪资发放历史实体类") +@TableName(value = "wages_payment_history", autoResultMap = true) +@RedisCacheField(name = CacheConstants.WAGES_PAYMENT_CACHE_KEY) +public class WagesPaymentHistory extends CommonInfo { + + @TableField("staff_id") + @ApiModelProperty(value = "员工id", required = "required") + private String staffId; + + @TableField("pay_month") + @ApiModelProperty(value = "发放的薪资年月", required = "required") + private String payMonth; + + @TableField(value = "wages_json", typeHandler = JacksonTypeHandler.class) + @ApiModelProperty(value = "薪资发放详细信息,json串[{\"name\":\"基础工资(名称)\", \"modelId\": \"模型id,可为空\", \"childField\": [{\"name\":\"奖励\", \"moneyValue\": \"100(实际金额)\", \"key\": \"jiangli\", \"fieldType\": \"字段类型,参考#WagesModelFieldType\", \"defaultMoney\": \"0,该薪资模板中设置的默认金额\", \"orderBy\": \"排序号\", \"formula\": \"计算公式\"}]}]", required = "required") + private List> wagesJson; + + @TableField("act_wages") + @ApiModelProperty(value = "实发总薪资", required = "required") + private String actWages; + + @TableField("create_time") + @ApiModelProperty(value = "薪资核算日期", required = "required") + private String createTime; + + @TableField("grant_time") + @ApiModelProperty(value = "薪资发放日期", required = "required") + private String grantTime; + + @TableField("type") + @ApiModelProperty(value = "核算类型,参考#PaymentHistoryType", required = "required") + private Integer type; + + @TableField("state") + @ApiModelProperty(value = "是否发放,参考#PaymentHistoryState", required = "required") + private Integer state; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/WagesPaymentHistoryService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/WagesPaymentHistoryService.java new file mode 100644 index 0000000..2263861 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/WagesPaymentHistoryService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.payment.entity.WagesPaymentHistory; + +import java.util.List; + +/** + * @ClassName: WagesPaymentHistoryService + * @Description: 薪资发放历史管理服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/1/22 18:10 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface WagesPaymentHistoryService extends SkyeyeBusinessService { + + void queryAllGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject); + + void queryMyWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject); + + void queryAllNotGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject); + + List queryWagesPaymentHistoryByState(Integer state); + + void editWagesPaymentHistoryState(String staffId, String payMonth, Integer state); + + void queryWagesStaffPaymentDetail(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/impl/WagesPaymentHistoryServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/impl/WagesPaymentHistoryServiceImpl.java new file mode 100644 index 0000000..a53719c --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/payment/service/impl/WagesPaymentHistoryServiceImpl.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.payment.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.payment.classenum.PaymentHistoryState; +import com.skyeye.eve.payment.dao.WagesPaymentHistoryDao; +import com.skyeye.eve.payment.entity.WagesPaymentHistory; +import com.skyeye.eve.payment.service.WagesPaymentHistoryService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WagesPaymentHistoryServiceImpl + * @Description: 薪资发放历史管理服务类 + * @author: skyeye云系列--卫志强 + * @date: 2021/8/7 23:34 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "薪资发放历史", groupName = "薪资发放历史") +public class WagesPaymentHistoryServiceImpl extends SkyeyeBusinessServiceImpl implements WagesPaymentHistoryService { + + private void queryList(CommonPageInfo pageInfo, OutputObject outputObject) { + Page pages = PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit()); + List> beans = skyeyeBaseMapper.queryWagesPaymentHistoryList(pageInfo); + // 设置员工信息 + List staffIds = beans.stream().map(bean -> bean.get("staffId").toString()) + .filter(staffId -> StrUtil.isNotEmpty(staffId)).distinct().collect(Collectors.toList()); + Map> staffMap = iAuthUserService.queryUserMationListByStaffIds(staffIds); + beans.forEach(bean -> { + String staffId = bean.get("staffId").toString(); + bean.put("staffMation", staffMap.get(staffId)); + }); + outputObject.setBeans(beans); + outputObject.settotal(pages.getTotal()); + } + + /** + * 获取所有已发放薪资发放历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setState(PaymentHistoryState.ISSUED.getKey().toString()); + queryList(pageInfo, outputObject); + } + + /** + * 获取我的薪资发放历史列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryMyWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setStaffId(inputObject.getLogParams().get("staffId").toString()); + queryList(pageInfo, outputObject); + } + + /** + * 获取所有待发放薪资列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @Override + public void queryAllNotGrantWagesPaymentHistoryList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setState(PaymentHistoryState.UNISSUED.getKey().toString()); + queryList(pageInfo, outputObject); + } + + @Override + public List queryWagesPaymentHistoryByState(Integer state) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesPaymentHistory::getState), state); + List paymentHistories = list(queryWrapper); + return paymentHistories; + } + + @Override + public void editWagesPaymentHistoryState(String staffId, String payMonth, Integer state) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(MybatisPlusUtil.toColumns(WagesPaymentHistory::getStaffId), staffId); + updateWrapper.eq(MybatisPlusUtil.toColumns(WagesPaymentHistory::getPayMonth), payMonth); + updateWrapper.set(MybatisPlusUtil.toColumns(WagesPaymentHistory::getState), state); + updateWrapper.set(MybatisPlusUtil.toColumns(WagesPaymentHistory::getGrantTime), DateUtil.getTimeAndToString()); + update(updateWrapper); + } + + @Override + public void queryWagesStaffPaymentDetail(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String staffId = map.get("staffId").toString(); + String payMonth = map.get("payMonth").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesPaymentHistory::getStaffId), staffId); + queryWrapper.eq(MybatisPlusUtil.toColumns(WagesPaymentHistory::getPayMonth), payMonth); + WagesPaymentHistory wagesPaymentHistory = getOne(queryWrapper, false); + outputObject.setBean(wagesPaymentHistory); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/controller/WagesSocialSecurityFundController.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/controller/WagesSocialSecurityFundController.java new file mode 100644 index 0000000..73a362b --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/controller/WagesSocialSecurityFundController.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.eve.social.entity.SocialSecurityFund; +import com.skyeye.eve.social.service.WagesSocialSecurityFundService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: WagesSocialSecurityFundController + * @Description: 社保公积金控制层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:50 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "社保公积金管理", tags = "社保公积金管理", modelName = "社保公积金管理") +public class WagesSocialSecurityFundController { + + @Autowired + private WagesSocialSecurityFundService wagesSocialSecurityFundService; + + /** + * 获取社保公积金模板列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wagessocialsecurityfund001", value = "获取社保公积金模板列表", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/WagesSocialSecurityFundController/queryWagesSocialSecurityFundList") + public void queryWagesSocialSecurityFundList(InputObject inputObject, OutputObject outputObject) { + wagesSocialSecurityFundService.queryPageList(inputObject, outputObject); + } + + /** + * 新增/编辑社保公积金模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeWagesSocialSecurityFund", value = "新增/编辑社保公积金模板信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = SocialSecurityFund.class) + @RequestMapping("/post/WagesSocialSecurityFundController/writeWagesSocialSecurityFund") + public void writeWagesSocialSecurityFund(InputObject inputObject, OutputObject outputObject) { + wagesSocialSecurityFundService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 删除社保公积金模板信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteWagesSocialSecurityFund", value = "删除社保公积金模板信息", method = "DELETE", allUse = "1") + @ApiImplicitParams(value = { + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/WagesSocialSecurityFundController/deleteWagesSocialSecurityFund") + public void deleteWagesSocialSecurityFund(InputObject inputObject, OutputObject outputObject) { + wagesSocialSecurityFundService.deleteById(inputObject, outputObject); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/ApplicableObjectsDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/ApplicableObjectsDao.java new file mode 100644 index 0000000..a52fb99 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/ApplicableObjectsDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.social.entity.ApplicableObjects; + +/** + * @ClassName: ApplicableObjectsDao + * @Description: 社保公积金适用对象数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:45 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ApplicableObjectsDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/WagesSocialSecurityFundDao.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/WagesSocialSecurityFundDao.java new file mode 100644 index 0000000..2b8939a --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/dao/WagesSocialSecurityFundDao.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.eve.social.entity.SocialSecurityFund; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: WagesSocialSecurityFundDao + * @Description: 社保公积金数据接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesSocialSecurityFundDao extends SkyeyeBaseMapper { + + List> queryWagesSocialSecurityFundList(CommonPageInfo pageInfo); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/ApplicableObjects.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/ApplicableObjects.java new file mode 100644 index 0000000..4d8dde2 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/ApplicableObjects.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: ApplicableObjects + * @Description: 社保公积金适用对象实体类 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:35 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("社保公积金适用对象实体类") +@TableName(value = "wages_social_security_fund_applicable_objects") +public class ApplicableObjects extends CommonInfo { + + @TableField("security_fund_id") + @Property(value = "社保公积金id") + private String securityFundId; + + @TableField("object_id") + @ApiModelProperty(value = "适用对象id", required = "required") + private String objectId; + + @TableField(exist = false) + @Property(value = "适用对象信息") + private Map objectMation; + + @TableField("object_type") + @ApiModelProperty(value = "适用对象类型,参考#ApplicableObjectsType", required = "required,num") + private Integer objectType; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/SocialSecurityFund.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/SocialSecurityFund.java new file mode 100644 index 0000000..73a9d95 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/entity/SocialSecurityFund.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: SocialSecurityFund + * @Description: 社保公积金实体类 + * @author: skyeye云系列--卫志强 + * @date: 2022/11/26 9:18 + * @Copyright: 2022 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@ApiModel("社保公积金实体类") +@UniqueField +@TableName(value = "wages_social_security_fund") +@RedisCacheField(name = CacheConstants.WAGES_SOCIAL_SECURITY_FUND_CACHE_KEY) +public class SocialSecurityFund extends BaseGeneralInfo { + + @TableField("start_time") + @ApiModelProperty(value = "开始时间", required = "required") + private String startTime; + + @TableField("end_time") + @ApiModelProperty(value = "结束时间", required = "required") + private String endTime; + + @TableField("enabled") + @ApiModelProperty(value = "状态,参考#EnableEnum", required = "required,num") + private Integer enabled; + + @TableField("endowment_base") + @ApiModelProperty(value = "养老保险基数", required = "double", defaultValue = "0") + private String endowmentBase; + + @TableField("endowment_person") + @ApiModelProperty(value = "养老个人比例(%)", required = "double", defaultValue = "0") + private String endowmentPerson; + + @TableField("endowment_company") + @ApiModelProperty(value = "养老单位比例(%)", required = "double", defaultValue = "0") + private String endowmentCompany; + + @TableField("unemployment_base") + @ApiModelProperty(value = "失业保险基数", required = "double", defaultValue = "0") + private String unemploymentBase; + + @TableField("unemployment_person") + @ApiModelProperty(value = "失业个人比例(%)", required = "double", defaultValue = "0") + private String unemploymentPerson; + + @TableField("unemployment_company") + @ApiModelProperty(value = "失业单位比例(%)", required = "double", defaultValue = "0") + private String unemploymentCompany; + + @TableField("employment_base") + @ApiModelProperty(value = "工伤保险基数", required = "double", defaultValue = "0") + private String employmentBase; + + @TableField("employment_person") + @ApiModelProperty(value = "工伤个人比例(%)", required = "double", defaultValue = "0") + private String employmentPerson; + + @TableField("employment_company") + @ApiModelProperty(value = "工伤单位比例(%)", required = "double", defaultValue = "0") + private String employmentCompany; + + @TableField("maternity_base") + @ApiModelProperty(value = "生育保险基数", required = "double", defaultValue = "0") + private String maternityBase; + + @TableField("maternity_person") + @ApiModelProperty(value = "生育个人比例(%)", required = "double", defaultValue = "0") + private String maternityPerson; + + @TableField("maternity_company") + @ApiModelProperty(value = "生育单位比例(%)", required = "double", defaultValue = "0") + private String maternityCompany; + + @TableField("medical_base") + @ApiModelProperty(value = "医疗保险基数", required = "double", defaultValue = "0") + private String medicalBase; + + @TableField("medical_person") + @ApiModelProperty(value = "医疗个人比例(%)", required = "double", defaultValue = "0") + private String medicalPerson; + + @TableField("medical_company") + @ApiModelProperty(value = "医疗单位比例(%)", required = "double", defaultValue = "0") + private String medicalCompany; + + @TableField("ins_total_seriously_ill_individual") + @ApiModelProperty(value = "保险合计:大病个人", required = "double", defaultValue = "0") + private String insTotalSeriouslyIllIndividual; + + @TableField("ins_total_person") + @ApiModelProperty(value = "保险合计:个人社保缴费", required = "double", defaultValue = "0") + private String insTotalPerson; + + @TableField("ins_total_company") + @ApiModelProperty(value = "保险合计:单位社保缴费", required = "double", defaultValue = "0") + private String insTotalCompany; + + @TableField("accumulation_base") + @ApiModelProperty(value = "公积金基数", required = "double", defaultValue = "0") + private String accumulationBase; + + @TableField("accumulation_person_scale") + @ApiModelProperty(value = "公积金个人比例(%)", required = "double", defaultValue = "0") + private String accumulationPersonScale; + + @TableField("accumulation_company_scale") + @ApiModelProperty(value = "公积金单位比例(%)", required = "double", defaultValue = "0") + private String accumulationCompanyScale; + + @TableField("accumulation_person_amount") + @ApiModelProperty(value = "公积金个人(元)", required = "double", defaultValue = "0") + private String accumulationPersonAmount; + + @TableField("accumulation_company_amount") + @ApiModelProperty(value = "公积金单位(元)", required = "double", defaultValue = "0") + private String accumulationCompanyAmount; + + @TableField(value = "order_by") + @ApiModelProperty(value = "排序", required = "required,num") + private Integer orderBy; + + @TableField(value = "delete_flag") + private Integer deleteFlag; + + @TableField(exist = false) + @ApiModelProperty(value = "适用对象", required = "json") + private List applicableObjectsList; + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/ApplicableObjectsService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/ApplicableObjectsService.java new file mode 100644 index 0000000..ce16744 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/ApplicableObjectsService.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.social.entity.ApplicableObjects; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: ApplicableObjectsService + * @Description: 社保公积金适用对象服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:45 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface ApplicableObjectsService extends SkyeyeBusinessService { + + void deleteApplicableObjectsByPId(String securityFundId); + + void saveApplicableObjects(String securityFundId, List applicableObjectsList); + + List queryApplicableObjectsByPId(String securityFundId); + + Map> queryApplicableObjectsByPId(List securityFundId); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/WagesSocialSecurityFundService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/WagesSocialSecurityFundService.java new file mode 100644 index 0000000..a68fbad --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/WagesSocialSecurityFundService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.eve.social.entity.SocialSecurityFund; + +import java.util.List; + +/** + * @ClassName: WagesSocialSecurityFundService + * @Description: 社保公积金服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface WagesSocialSecurityFundService extends SkyeyeBusinessService { + + /** + * 根据日期查找已经启用&&指定日期有效的社保公积金信息 + * + * @param date 指定日期的年月,例如:2023-11 + * @return + */ + List querySocialSecurityFundByDate(String date); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/ApplicableObjectsServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/ApplicableObjectsServiceImpl.java new file mode 100644 index 0000000..d266698 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/ApplicableObjectsServiceImpl.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.social.dao.ApplicableObjectsDao; +import com.skyeye.eve.social.entity.ApplicableObjects; +import com.skyeye.eve.social.service.ApplicableObjectsService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: ApplicableObjectsServiceImpl + * @Description: 社保公积金适用对象服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:46 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "社保公积金适用对象管理", groupName = "社保公积金适用对象管理", manageShow = false) +public class ApplicableObjectsServiceImpl extends SkyeyeBusinessServiceImpl implements ApplicableObjectsService { + + @Override + public void deleteApplicableObjectsByPId(String securityFundId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApplicableObjects::getSecurityFundId), securityFundId); + remove(queryWrapper); + } + + @Override + public void saveApplicableObjects(String securityFundId, List applicableObjectsList) { + deleteApplicableObjectsByPId(securityFundId); + if (CollectionUtil.isNotEmpty(applicableObjectsList)) { + for (ApplicableObjects applicableObjects : applicableObjectsList) { + applicableObjects.setSecurityFundId(securityFundId); + } + createEntity(applicableObjectsList, StrUtil.EMPTY); + } + } + + @Override + public List queryApplicableObjectsByPId(String securityFundId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(ApplicableObjects::getSecurityFundId), securityFundId); + List applicableObjectsList = list(queryWrapper); + return applicableObjectsList; + } + + @Override + public Map> queryApplicableObjectsByPId(List securityFundId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(ApplicableObjects::getSecurityFundId), securityFundId); + List applicableObjectsList = list(queryWrapper); + Map> listMap = applicableObjectsList.stream() + .collect(Collectors.groupingBy(ApplicableObjects::getSecurityFundId)); + return listMap; + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/WagesSocialSecurityFundServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/WagesSocialSecurityFundServiceImpl.java new file mode 100644 index 0000000..b41559f --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/eve/social/service/impl/WagesSocialSecurityFundServiceImpl.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.eve.social.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.base.Joiner; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.ApplicableObjectsType; +import com.skyeye.common.enumeration.DeleteFlagEnum; +import com.skyeye.common.enumeration.EnableEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.eve.social.dao.WagesSocialSecurityFundDao; +import com.skyeye.eve.social.entity.ApplicableObjects; +import com.skyeye.eve.social.entity.SocialSecurityFund; +import com.skyeye.eve.social.service.ApplicableObjectsService; +import com.skyeye.eve.social.service.WagesSocialSecurityFundService; +import com.skyeye.organization.service.ICompanyService; +import com.skyeye.organization.service.IDepmentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: WagesSocialSecurityFundServiceImpl + * @Description: 社保公积金服务层 + * @author: skyeye云系列--卫志强 + * @date: 2023/11/15 8:49 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Slf4j +@Service +@SkyeyeService(name = "社保公积金管理", groupName = "社保公积金管理") +public class WagesSocialSecurityFundServiceImpl extends SkyeyeBusinessServiceImpl implements WagesSocialSecurityFundService { + + @Autowired + private ApplicableObjectsService applicableObjectsService; + + @Autowired + private ICompanyService iCompanyService; + + @Autowired + private IDepmentService iDepmentService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo pageInfo = inputObject.getParams(CommonPageInfo.class); + pageInfo.setDeleteFlag(DeleteFlagEnum.NOT_DELETE.getKey()); + List> beans = skyeyeBaseMapper.queryWagesSocialSecurityFundList(pageInfo); + return beans; + } + + @Override + public void writePostpose(SocialSecurityFund entity, String userId) { + super.writePostpose(entity, userId); + applicableObjectsService.saveApplicableObjects(entity.getId(), entity.getApplicableObjectsList()); + } + + @Override + public void deletePostpose(String id) { + applicableObjectsService.deleteApplicableObjectsByPId(id); + } + + @Override + public SocialSecurityFund getDataFromDb(String id) { + SocialSecurityFund securityFund = super.getDataFromDb(id); + // 适用对象信息 + List applicableObjectsList = applicableObjectsService.queryApplicableObjectsByPId(id); + securityFund.setApplicableObjectsList(applicableObjectsList); + return securityFund; + } + + @Override + public SocialSecurityFund selectById(String id) { + SocialSecurityFund securityFund = super.selectById(id); + // 设置适用对象信息 + List applicableObjectsList = securityFund.getApplicableObjectsList(); + if (CollectionUtil.isNotEmpty(applicableObjectsList)) { + Map> listMap = applicableObjectsList.stream() + .collect(Collectors.groupingBy(ApplicableObjects::getObjectType)); + listMap.forEach((key, value) -> { + List ids = value.stream().map(ApplicableObjects::getObjectId).collect(Collectors.toList()); + if (ApplicableObjectsType.STAFF.getKey().equals(key)) { + // 员工 + Map> staffMaps = iAuthUserService.queryUserMationListByStaffIds(ids); + setObjectMation(applicableObjectsList, staffMaps, key); + } else if (ApplicableObjectsType.DEPARTMENT.getKey().equals(key)) { + // 部门 + String departmentIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(ids); + Map> departMent = iDepmentService.queryDataMationForMapByIds(departmentIdStr); + setObjectMation(applicableObjectsList, departMent, key); + } else if (ApplicableObjectsType.COMPANY.getKey().equals(key)) { + // 企业 + String companyIdStr = Joiner.on(CommonCharConstants.COMMA_MARK).join(ids); + Map> company = iCompanyService.queryDataMationForMapByIds(companyIdStr); + setObjectMation(applicableObjectsList, company, key); + } + }); + } + return securityFund; + } + + private static void setObjectMation(List applicableObjectsList, Map> temMap, Integer key) { + if (CollectionUtil.isEmpty(temMap)) { + return; + } + applicableObjectsList.forEach(applicableObjects -> { + if (key.equals(applicableObjects.getObjectType())) { + applicableObjects.setObjectMation(temMap.get(applicableObjects.getObjectId())); + } + }); + } + + @Override + public List querySocialSecurityFundByDate(String date) { + if (StrUtil.isEmpty(date)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(SocialSecurityFund::getDeleteFlag), DeleteFlagEnum.NOT_DELETE.getKey()); + queryWrapper.apply("date_format(" + MybatisPlusUtil.toColumns(SocialSecurityFund::getStartTime) + ", '%Y-%m') <= date_format({0}, '%Y-%m')", date) + .apply("date_format(" + MybatisPlusUtil.toColumns(SocialSecurityFund::getEndTime) + ", '%Y-%m') >= date_format({0}, '%Y-%m')", date); + queryWrapper.eq(MybatisPlusUtil.toColumns(SocialSecurityFund::getEnabled), EnableEnum.ENABLE_USING.getKey()); + List socialSecurityFundList = list(queryWrapper); + List ids = socialSecurityFundList.stream().map(SocialSecurityFund::getId).collect(Collectors.toList()); + // 获取适用对象 + Map> listMap = applicableObjectsService.queryApplicableObjectsByPId(ids); + socialSecurityFundList.forEach(socialSecurityFund -> { + socialSecurityFund.setApplicableObjectsList(listMap.get(socialSecurityFund.getId())); + }); + return socialSecurityFundList; + } +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/rest/ISysUserStaffRest.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/rest/ISysUserStaffRest.java new file mode 100644 index 0000000..7e27c38 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/rest/ISysUserStaffRest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.staff.rest; + +import com.skyeye.common.client.ClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; + +import java.util.Map; + +/** + * @ClassName: ISysUserStaffRest + * @Description: 员工信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@FeignClient(value = "${webroot.skyeye-pro}", configuration = ClientConfiguration.class) +public interface ISysUserStaffRest { + + /** + * 修改员工薪资设定信息 + * + * @param params 参数信息: + * staffId:员工id--必填 + * actMoney:实际薪资--必填 + */ + @PostMapping("/editSysUserStaffActMoneyById") + String editSysUserStaffActMoneyById(Map params); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/ISysUserStaffService.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/ISysUserStaffService.java new file mode 100644 index 0000000..9058f3e --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/ISysUserStaffService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.staff.service; + +import com.skyeye.base.rest.service.IService; + +/** + * @ClassName: ISysUserStaffService + * @Description: 员工信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +public interface ISysUserStaffService extends IService { + + /** + * 修改员工薪资设定信息 + * + * @param staffId 员工id + * @param actMoney 员工实际薪资 + */ + void editSysUserStaffActMoneyById(String staffId, String actMoney); + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/impl/ISysUserStaffServiceImpl.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/impl/ISysUserStaffServiceImpl.java new file mode 100644 index 0000000..1184286 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/rest/staff/service/impl/ISysUserStaffServiceImpl.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.rest.staff.service.impl; + +import com.skyeye.base.rest.service.impl.IServiceImpl; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.rest.staff.rest.ISysUserStaffRest; +import com.skyeye.rest.staff.service.ISysUserStaffService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: ISysUserStaffServiceImpl + * @Description: 员工信息管理公共的一些操作 + * @author: skyeye云系列--卫志强 + * @date: 2023/8/15 10:32 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Service +public class ISysUserStaffServiceImpl extends IServiceImpl implements ISysUserStaffService { + + @Autowired + private ISysUserStaffRest iSysUserStaffRest; + + @Override + public void editSysUserStaffActMoneyById(String staffId, String actMoney) { + Map map = new HashMap<>(); + map.put("staffId", staffId); + map.put("actMoney", actMoney); + ExecuteFeignClient.get(() -> iSysUserStaffRest.editSysUserStaffActMoneyById(map)); + } +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesPaymentQuartz.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesPaymentQuartz.java new file mode 100644 index 0000000..0fcfbe2 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesPaymentQuartz.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import com.skyeye.common.util.DateUtil; +import com.skyeye.eve.payment.classenum.PaymentHistoryState; +import com.skyeye.eve.payment.entity.WagesPaymentHistory; +import com.skyeye.eve.payment.service.WagesPaymentHistoryService; +import com.skyeye.jedis.util.RedisLock; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @ClassName: StaffWagesPaymentQuartz + * @Description: 薪资发放定时任务,每月15日上午10:15触发 + * @author: skyeye云系列--卫志强 + * @date: 2021/5/1 21:32 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Component +public class StaffWagesPaymentQuartz { + + private static Logger LOGGER = LoggerFactory.getLogger(StaffWagesPaymentQuartz.class); + + @Autowired + private WagesPaymentHistoryService wagesPaymentHistoryService; + + /** + * 定时发放薪资功能,每月15日上午10:15触发 + */ + @XxlJob("staffWagesPaymentQuartz") + public void staffWagesPayment() { + LOGGER.info("staff wagesPayment month is start"); + // 获取上个月的年月 + String lastMonthDate = DateUtil.getLastMonthDate(); + String lockKey = String.format("inWagesPaymentStaffRedisKey:%s", lastMonthDate); + RedisLock lock = new RedisLock(lockKey); + try { + if (!lock.lock()) { + // 加锁失败 + return; + } + List wagesPaymentHistories = wagesPaymentHistoryService.queryWagesPaymentHistoryByState(PaymentHistoryState.UNISSUED.getKey()); + wagesPaymentHistories.forEach(wagesPaymentHistory -> { + paymentStaffWages(wagesPaymentHistory, lastMonthDate); + }); + } catch (Exception e) { + LOGGER.warn("StaffWagesPaymentQuartz error.", e); + } finally { + lock.unlock(); + } + LOGGER.info("staff wagesPayment month is end"); + } + + /** + * 薪资发放 + * + * @param staffWages 员工薪资信息 + * @param lastMonthDate 上个月的年月 + */ + private void paymentStaffWages(WagesPaymentHistory staffWages, String lastMonthDate) { + String staffId = staffWages.getStaffId(); + // todo 这里处理薪资发放的信息 + + + wagesPaymentHistoryService.editWagesPaymentHistoryState(staffId, lastMonthDate, PaymentHistoryState.ISSUED.getKey()); + } + +} diff --git a/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesQuartz.java b/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesQuartz.java new file mode 100644 index 0000000..b6bdf65 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/java/com/skyeye/xxljob/StaffWagesQuartz.java @@ -0,0 +1,858 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.xxljob; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.skyeye.common.client.ExecuteFeignClient; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.constans.WagesConstant; +import com.skyeye.common.enumeration.AbnormalCheckworkType; +import com.skyeye.common.enumeration.IsDefaultEnum; +import com.skyeye.common.util.*; +import com.skyeye.eve.field.classenum.WagesTypeEnum; +import com.skyeye.eve.field.dao.FieldStaffLinkDao; +import com.skyeye.eve.field.entity.FieldType; +import com.skyeye.eve.field.service.FieldStaffLinkService; +import com.skyeye.eve.model.classenum.WagesModelFieldType; +import com.skyeye.eve.model.dao.CompanyTaxRateDao; +import com.skyeye.eve.model.dao.SysEveUserStaffDao; +import com.skyeye.eve.model.dao.WagesModelFieldDao; +import com.skyeye.eve.model.entity.ModelApplicableObjects; +import com.skyeye.eve.model.entity.WagesModel; +import com.skyeye.eve.model.entity.WagesModelField; +import com.skyeye.eve.model.service.WagesModelService; +import com.skyeye.eve.payment.classenum.PaymentHistoryState; +import com.skyeye.eve.payment.classenum.PaymentHistoryType; +import com.skyeye.eve.payment.entity.WagesPaymentHistory; +import com.skyeye.eve.payment.service.WagesPaymentHistoryService; +import com.skyeye.eve.rest.checkwork.CheckWorkTimeService; +import com.skyeye.eve.service.ISystemFoundationSettingsService; +import com.skyeye.eve.social.entity.ApplicableObjects; +import com.skyeye.eve.social.entity.SocialSecurityFund; +import com.skyeye.eve.social.service.WagesSocialSecurityFundService; +import com.skyeye.jedis.JedisClientService; +import com.xxl.job.core.handler.annotation.XxlJob; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: StaffWagesQuartz + * @Description: 定时统计上个月员工的薪资情况 + * @author: skyeye云系列--卫志强 + * @date: 2021/4/5 18:28 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目 + */ +@Component +public class StaffWagesQuartz { + + private static Logger LOGGER = LoggerFactory.getLogger(StaffWagesQuartz.class); + + @Autowired + private FieldStaffLinkDao wagesStaffMationDao; + + @Autowired + private JedisClientService jedisClient; + + @Autowired + private CompanyTaxRateDao companyTaxRateDao; + + @Autowired + private WagesModelFieldDao wagesModelFieldDao; + + @Autowired + private WagesSocialSecurityFundService wagesSocialSecurityFundService; + + @Autowired + private ISystemFoundationSettingsService iSystemFoundationSettingsService; + + @Autowired + private CheckWorkTimeService checkWorkTimeService; + + @Autowired + private SysEveUserStaffDao sysEveUserStaffDao; + + @Autowired + private WagesModelService wagesModelService; + + @Autowired + private FieldStaffLinkService wagesStaffMationService; + + @Autowired + private WagesPaymentHistoryService wagesPaymentHistoryService; + + /** + * 当前薪资统计中的员工id存储在redis的key,因为存在多台机器同时处理员工薪资的情况,所以不去主动删除该缓存信息,等待自动失效即可 + */ + private static final String IN_STATISTICS_STAFF_REDIS_KEY = "inStatisticsWagesStaff"; + + /** + * 每月十号的凌晨两点开始执行薪资统计任务 + */ + @XxlJob("staffWagesQuartz") + public void statisticsStaffWages() { + try { + // 获取上个月的年月 + String lastMonthDate = DateUtil.getLastMonthDate(); + LOGGER.info("statistics staff wages month is {}", lastMonthDate); + // 个人所得税缴纳比例 + Map>> taxRate = getTaxRate(); + // 所有启用中的薪资模板适用对象关系以及模板要素字段 + List wagesModelList = wagesModelService.queryWagesModelByDate(lastMonthDate); + // 所有启动中的社保公积金适用对象关系以及社保公积金参数信息 + List socialSecurityFund = wagesSocialSecurityFundService.querySocialSecurityFundByDate(lastMonthDate); + // 系统基础信息 + Map systemFoundationSettings = iSystemFoundationSettingsService.querySystemFoundationSettingsList(); + // 所有的考勤班次信息 + List> workTime = + ExecuteFeignClient.get(() -> checkWorkTimeService.getAllCheckWorkTime(lastMonthDate)).getRows(); + while (true) { + // 获取一条未生成薪资的员工数据 + Map staff = wagesStaffMationDao.queryNoWagesLastMonthByLastMonthDate(lastMonthDate, getStaffIdsFromRedis()); + // 如果已经没有要统计薪资的员工,则停止统计 + if (staff == null) { + break; + } + String staffId = staff.get("id").toString(); + // 判断该员工的薪资统计是否在处理中,如果在处理中,则进行下一条 + if (isInStatisticsRedisMation(staffId)) { + continue; + } + try { + // 锁定该员工为处理中 + addStaffIdInStatisticsRedisMation(staffId); + // 开始统计 + calcStaffWages(staff, wagesModelList, socialSecurityFund, systemFoundationSettings, workTime, lastMonthDate, taxRate); + // 将指定员工月度清零的薪资字段设置为0 + wagesStaffMationDao.editStaffMonthlyClearingWagesByStaffId(staffId); + } catch (Exception e) { + LOGGER.warn("deal with staff failed, staffId is {}", staffId, e); + break; + } finally { + // 从正在处理中的员工集合数据中移除,说明该员工数据已经处理完成 + removeStaffIdInStatisticsRedisMation(staffId); + } + } + deleteStatisticsRedisMation(); + } catch (Exception e) { + LOGGER.warn("StaffWagesQuartz error.", e); + } + LOGGER.info("statistics staff wages month is end"); + } + + /** + * 统计员工的薪资 + * + * @param staff 员工信息 + * @param wagesModelList 所有启用中的薪资模板 + * @param socialSecurityFund 所有启动中的社保公积金适用对象关系以及社保公积金参数信息 + * @param systemFoundationSettings 系统基础信息 + * @param workTime 考勤制度 + * @param lastMonthDate 上个月的年月 + * @param taxRate 个人所得税缴纳比例 + */ + private void calcStaffWages(Map staff, List wagesModelList, List socialSecurityFund, + Map systemFoundationSettings, List> workTime, String lastMonthDate, Map>> taxRate) { + String companyId = staff.get("companyId").toString(); + String departmentId = staff.get("departmentId").toString(); + String staffId = staff.get("id").toString(); + // 员工应发薪资 + String actWages = staff.get("actWages").toString(); + LOGGER.info("staffId is {}, actWages is {}", staffId, actWages); + // 获取该员工具备的模板id + List modelIds = getModelIdsForStaff(companyId, departmentId, staffId, wagesModelList); + // 该员工拥有的所有薪资要素字段以及对应的值 + List> staffModelField = getUserStaffWagesModelField(modelIds, staffId); + Map staffModelFieldMap = convert2Map(staffModelField); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_SALARY.getKey(), actWages); + // 获取该员工应该缴纳的社保公积金的金额 + String socialSecurityFundMoney = getSocialSecurityFundMoney(companyId, departmentId, staffId, socialSecurityFund, staffModelFieldMap); + LOGGER.info("staffId is {}, socialSecurityFundMoney is {}", staffId, socialSecurityFundMoney); + // 计算员工的考勤相关应扣的薪资 + String staffCheckWorkMoney = calcStaffCheckWork(staffId, systemFoundationSettings, workTime, staffModelFieldMap, lastMonthDate); + LOGGER.info("staffId is {}, staffCheckWorkMoney is {}", staffId, staffCheckWorkMoney); + // 开始计算上月实发工资 + String monthlyStandardRealMoney = calcMonthRealMoney(lastMonthDate, taxRate, companyId, actWages, + staffModelField, staffModelFieldMap, socialSecurityFundMoney, staffCheckWorkMoney); + // 实发薪资 + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_REAL_MONEY.getKey(), monthlyStandardRealMoney); + // 开始输出json + outputJsonToSQL(wagesModelList, staffModelFieldMap, staffId, lastMonthDate, modelIds); + } + + private List getModelIdsForStaff(String companyId, String departmentId, String staffId, List wagesModelList) { + List temIds = CollectionUtil.newArrayList(companyId, departmentId, staffId); + List modelIds = wagesModelList.stream().filter(bean -> { + List objectIds = bean.getApplicableObjectsList().stream().map(ModelApplicableObjects::getObjectId).collect(Collectors.toList()); + return objectIds.stream().anyMatch(str -> temIds.contains(str)); + }).map(WagesModel::getId).distinct().collect(Collectors.toList()); + return modelIds; + } + + /** + * 开始计算上月实发工资 + * + * @param lastMonthDate 上月的日期 + * @param taxRate 个人所得税缴纳比例 + * @param companyId 企业id + * @param actWages 员工应发薪资 + * @param staffModelField 该员工拥有的所有薪资要素字段以及对应的值 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值转成的map + * @param socialSecurityFundMoney 该员工应该缴纳的社保公积金的金额 + * @param staffCheckWorkMoney 员工的考勤相关应扣的薪资,如果为负数,则说明加班和销假>请假以及异常考勤 + * @return + */ + private String calcMonthRealMoney(String lastMonthDate, Map>> taxRate, + String companyId, String actWages, List> staffModelField, + Map staffModelFieldMap, String socialSecurityFundMoney, String staffCheckWorkMoney) { + String monthlyStandardRealMoney = CalculationUtil.subtract(actWages, socialSecurityFundMoney, CommonNumConstants.NUM_TWO); + monthlyStandardRealMoney = CalculationUtil.subtract(monthlyStandardRealMoney, staffCheckWorkMoney, CommonNumConstants.NUM_TWO); + for (Map bean : staffModelField) { + if (IsDefaultEnum.IS_DEFAULT.getKey().equals(bean.get("monthlyClearing").toString())) { + // 只算自动清零的 + if (WagesTypeEnum.SALARY_INCREASE.getKey().equals(bean.get("wagesType").toString())) { + // 薪资增加 + monthlyStandardRealMoney = + CalculationUtil.add(monthlyStandardRealMoney, bean.get("amountMoney").toString(), CommonNumConstants.NUM_TWO); + } else if (WagesTypeEnum.SALARY_REDUCTION.getKey().equals(bean.get("wagesType").toString())) { + // 薪资减少 + monthlyStandardRealMoney = + CalculationUtil.subtract(monthlyStandardRealMoney, bean.get("amountMoney").toString(), CommonNumConstants.NUM_TWO); + } + } + } + monthlyStandardRealMoney = + calcTaxRate(monthlyStandardRealMoney, taxRate, companyId, lastMonthDate, staffModelFieldMap); + return monthlyStandardRealMoney; + } + + /** + * 输出json + * + * @param wagesModelList 所有启用中的薪资模板 + * @param staffModelFieldMap 薪资数据 + * @param staffId 员工id + * @param lastMonthDate 上个月的年月 + * @param modelIds 员工拥有的模板的模型id + */ + private void outputJsonToSQL(List wagesModelList, Map staffModelFieldMap, String staffId, String lastMonthDate, + List modelIds) { + WagesPaymentHistory wagesPaymentHistory = new WagesPaymentHistory(); + wagesPaymentHistory.setStaffId(staffId); + wagesPaymentHistory.setCreateTime(DateUtil.getTimeAndToString()); + wagesPaymentHistory.setPayMonth(lastMonthDate); + wagesPaymentHistory.setActWages(staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_REAL_MONEY.getKey())); + wagesPaymentHistory.setState(PaymentHistoryState.UNISSUED.getKey()); + wagesPaymentHistory.setType(PaymentHistoryType.SYSTEM_ACCOUNTING.getKey()); + List staffModel = wagesModelList.stream().filter(bean -> modelIds.contains(bean.getId())) + .collect(Collectors.toList()); + wagesPaymentHistory.setWagesJson(getWagesJson(staffModel, staffModelFieldMap)); + wagesPaymentHistoryService.createEntity(wagesPaymentHistory, StrUtil.EMPTY); + } + + /** + * 获取员工的json薪资列表 + * + * @param staffModel 该员工拥有的所有薪资模板 + * @param staffModelFieldMap 薪资数据 + * @return + */ + private List> getWagesJson(List staffModel, Map staffModelFieldMap) { + List> beans = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(staffModel)) { + for (WagesModel model : staffModel) { + Map bean = new HashMap<>(); + bean.put("name", model.getName()); + bean.put("modelId", model.getId()); + model.getWagesModelFieldList().forEach(wagesModelField -> { + if (ToolUtil.isBlank(wagesModelField.getFormula())) { + wagesModelField.setMoneyValue(staffModelFieldMap.get(wagesModelField.getFieldKey())); + } else { + wagesModelField.setMoneyValue(String.valueOf(ReflexUtil.convertToCode(wagesModelField.getFormula(), staffModelFieldMap))); + } + }); + bean.put("childFields", model.getWagesModelFieldList()); + beans.add(bean); + } + } + beans.addAll(getSocialSecurityFundWagesJson(staffModelFieldMap)); + beans.addAll(getTaxRateWagesJson(staffModelFieldMap)); + return beans; + } + + /** + * 获取社保公积金信息 + * + * @param staffModelFieldMap 薪资数据 + * @return + */ + private List> getSocialSecurityFundWagesJson(Map staffModelFieldMap) { + List> beans = new ArrayList<>(); + Map bean = new HashMap<>(); + bean.put("name", "社保公积金"); + List childFields = new ArrayList<>(); + WagesModelField childField = new WagesModelField(); + FieldType fieldKeyMation = new FieldType(); + fieldKeyMation.setName("个人缴纳社保"); + childField.setFieldKeyMation(fieldKeyMation); + childField.setMoneyValue(staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_INSURANCE.getKey())); + childField.setFieldKey(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_INSURANCE.getKey()); + childField.setFieldType(WagesModelFieldType.FIELD.getKey()); + childField.setOrderBy(CommonNumConstants.NUM_ONE); + childFields.add(childField); + + WagesModelField childField2 = new WagesModelField(); + FieldType fieldKeyMation2 = new FieldType(); + fieldKeyMation2.setName("个人缴纳公积金"); + childField2.setFieldKeyMation(fieldKeyMation2); + childField2.setMoneyValue(staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_ACCUMULATION.getKey())); + childField2.setFieldKey(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_ACCUMULATION.getKey()); + childField2.setFieldType(WagesModelFieldType.FIELD.getKey()); + childField2.setOrderBy(CommonNumConstants.NUM_TWO); + childFields.add(childField2); + bean.put("childFields", childFields); + beans.add(bean); + return beans; + } + + /** + * 获取个人缴税信息 + * + * @param staffModelFieldMap 薪资数据 + * @return + */ + private List> getTaxRateWagesJson(Map staffModelFieldMap) { + List> beans = new ArrayList<>(); + Map bean = new HashMap<>(); + bean.put("name", "个人缴税"); + List childFields = new ArrayList<>(); + WagesModelField childField = new WagesModelField(); + FieldType fieldKeyMation = new FieldType(); + fieldKeyMation.setName("个人缴纳税额"); + childField.setFieldKeyMation(fieldKeyMation); + childField.setMoneyValue(staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_TAX_RATE_BY_PERSON.getKey())); + childField.setFieldKey(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_TAX_RATE_BY_PERSON.getKey()); + childField.setFieldType(WagesModelFieldType.FIELD.getKey()); + childField.setOrderBy(CommonNumConstants.NUM_ONE); + childFields.add(childField); + bean.put("childFields", childFields); + beans.add(bean); + return beans; + } + + /** + * 获取减去个人所得税之后的钱 + * + * @param monthlyStandardRealMoney 未缴税的金额 + * @param taxRate 缴税信息 + * @param companyId 公司id + * @param lastMonthDate 上个月的年月 + * @param staffModelFieldMap 薪资数据 + * @return + */ + private String calcTaxRate(String monthlyStandardRealMoney, Map>> taxRate, String companyId, String lastMonthDate, + Map staffModelFieldMap) { + List> companyTaxRate = taxRate.get(companyId); + String finalMonthlyStandardRealMoney = monthlyStandardRealMoney; + List> staffTaxRate = companyTaxRate.stream().filter(bean -> { + String intervalStr = String.format(Locale.ROOT, "[%s, %s)", bean.get("minMoney").toString(), bean.get("maxMoney").toString()); + return IntervalUtil.isInTheInterval(finalMonthlyStandardRealMoney, intervalStr); + }).collect(Collectors.toList()); + // 缴纳的税额 + String taxRateMoney = "0"; + if (staffTaxRate != null && !staffTaxRate.isEmpty()) { + taxRateMoney = CalculationUtil.multiply(monthlyStandardRealMoney, + CalculationUtil.divide(getMonthRate(lastMonthDate, staffTaxRate), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_FOUR); + } + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_TAX_RATE_BY_PERSON.getKey(), taxRateMoney); + monthlyStandardRealMoney = CalculationUtil.subtract(monthlyStandardRealMoney, + taxRateMoney, CommonNumConstants.NUM_FOUR); + return monthlyStandardRealMoney; + } + + /** + * 获取上个月的税率 + * + * @param lastMonthDate 上个月的年月 + * @param staffTaxRate 员工的个人缴纳税率 + * @return + */ + private String getMonthRate(String lastMonthDate, List> staffTaxRate) { + Map taxRate = staffTaxRate.get(0); + String month = lastMonthDate.split("-")[1]; + String key = ""; + switch (month) { + case "01": + key = "janRate"; + break; + case "02": + key = "febRate"; + break; + case "03": + key = "marRate"; + break; + case "04": + key = "aprRate"; + break; + case "05": + key = "mayRate"; + break; + case "06": + key = "junRate"; + break; + case "07": + key = "julRate"; + break; + case "08": + key = "augRate"; + break; + case "09": + key = "septRate"; + break; + case "10": + key = "octRate"; + break; + case "11": + key = "novRate"; + break; + case "12": + key = "decRate"; + break; + } + return taxRate.get(key).toString(); + } + + /** + * 计算员工的考勤相关应扣的薪资 + * + * @param staffId 员工id + * @param systemFoundationSettings 系统基础信息 + * @param workTime 考勤制度 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @param lastMonthDate 上个月的年月 + * @return 如果返回值为负数,则说明加班和销假>请假以及异常考勤 + */ + private String calcStaffCheckWork(String staffId, Map systemFoundationSettings, List> workTime, + Map staffModelFieldMap, String lastMonthDate) { + // 1.获取该员工拥有的考勤班次id集合 + List> staffTimeIdMation = sysEveUserStaffDao + .queryStaffCheckWorkTimeRelationByStaffId(staffId); + List userTimeIds = staffTimeIdMation.stream() + .map(p -> p.get("timeId").toString()).collect(Collectors.toList()); + List> staffWorkTime = workTime.stream() + .filter(bean -> userTimeIds.contains(bean.get("timeId").toString())) + .collect(Collectors.toList()); + // 2.获取上个月指定员工的所有考勤记录信息 + List> lastMonthCheckWork = wagesStaffMationDao.queryLastMonthCheckWork(staffId, lastMonthDate); + // 3.设置应出勤的班次以及小时 + Map monthBe = wagesStaffMationService.setLastMonthBe(staffWorkTime, lastMonthDate); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_NUM.getKey(), + monthBe.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_NUM.getKey()).toString()); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey(), + monthBe.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()).toString()); + // 上个月迟到的分钟集合 + List lateMinute = new ArrayList<>(); + // 上个月早退的分钟集合 + List earlyMinute = new ArrayList<>(); + // 4.设置员工考勤的对应数据信息 + setStaffCheckWorkMation(lastMonthCheckWork, staffModelFieldMap, lateMinute, earlyMinute, staffWorkTime); + // 5.计算考勤的扣薪情况 + String checkWorkMoney = calcCheckWorkMation(lateMinute, earlyMinute, staffModelFieldMap, systemFoundationSettings); + // 6.计算请假的扣薪情况 + String leaveMoney = calcLeaveTimeMation(systemFoundationSettings, staffId, lastMonthDate, staffModelFieldMap); + // 7.计算销假应退还给员工的薪资 + String cancleLeaveMoney = calcCancleLeaveTimeMation(staffId, lastMonthDate, staffModelFieldMap); + // 计算请假以及异常考勤应结算的钱 + String shouldSubtractMoney = CalculationUtil.add(CommonNumConstants.NUM_TWO, checkWorkMoney, leaveMoney); + return CalculationUtil.subtract(shouldSubtractMoney, cancleLeaveMoney, CommonNumConstants.NUM_TWO); + } + + /** + * 计算销假应退还给员工的薪资 + * + * @param staffId 员工id + * @param lastMonthDate 上个月的日期,格式为yyyy-MM + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @return + */ + private String calcCancleLeaveTimeMation(String staffId, String lastMonthDate, Map staffModelFieldMap) { + // 获取上个月指定员工的所有审批通过销假记录信息 + List> cancleLeaveTime = wagesStaffMationDao.queryLastMonthCancleLeaveTime(staffId, lastMonthDate); + // 获取月标准小时薪资计算 + String hourWages = CalculationUtil.divide( + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_SALARY.getKey()), + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()), CommonNumConstants.NUM_TWO); + // 销假要退还给员工的钱 + String cancleLeaveMoney = "0"; + for (Map bean : cancleLeaveTime) { + // 销假的时长(分钟) + String cancelMinute = DateUtil.getDistanceMinuteByHMS(bean.get("cancelStartTime").toString(), bean.get("cancelEndTime").toString()); + String cancelHourTime = CalculationUtil.divide(cancelMinute, "60", CommonNumConstants.NUM_TWO); + cancleLeaveMoney = CalculationUtil.add( + cancleLeaveMoney, + CalculationUtil.multiply(cancelHourTime, hourWages, CommonNumConstants.NUM_FOUR), CommonNumConstants.NUM_FOUR); + } + return cancleLeaveMoney; + } + + /** + * 计算考勤的扣薪情况 + * + * @param lateMinute 上个月迟到的分钟集合 + * @param earlyMinute 上个月早退的分钟集合 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @param systemFoundationSettings 系统基础信息 + * @return + */ + private String calcCheckWorkMation(List lateMinute, List earlyMinute, Map staffModelFieldMap, + Map systemFoundationSettings) { + // 异常考勤制度管理信息 + List> abnormalMation = JSONUtil.toList(systemFoundationSettings.get("abnormalMation").toString(), null); + // 1.早退 + List> leaveearly = abnormalMation.stream() + .filter(bean -> AbnormalCheckworkType.ABNORMAL_LEAVEEARLY.getKey().equals(bean.get("abnormalType").toString())) + .collect(Collectors.toList()); + String leaveearlyMoney = calcMoney(earlyMinute, leaveearly, staffModelFieldMap, WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_EARLY_NUM.getKey()); + // 2.迟到 + List> late = abnormalMation.stream() + .filter(bean -> AbnormalCheckworkType.ABNORMAL_LATE.getKey().equals(bean.get("abnormalType").toString())) + .collect(Collectors.toList()); + String lateMoney = calcMoney(lateMinute, late, staffModelFieldMap, WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_LATE_NUM.getKey()); + // 3.旷工 + List> miner = abnormalMation.stream() + .filter(bean -> AbnormalCheckworkType.ABNORMAL_MINER.getKey().equals(bean.get("abnormalType").toString())) + .collect(Collectors.toList()); + String minerMoney = calcMinerMoney(miner, staffModelFieldMap); + return CalculationUtil.add(CommonNumConstants.NUM_FOUR, leaveearlyMoney, lateMoney, minerMoney); + } + + /** + * 计算异常考勤的扣薪金额 + * + * @param minute 异常的时间 + * @param abnormalTypes 异常类型 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @param key 异常类型的次数key + * @return + */ + private String calcMoney(List minute, List> abnormalTypes, Map staffModelFieldMap, + String key) { + if (abnormalTypes != null && !abnormalTypes.isEmpty()) { + Map abnormalType = abnormalTypes.get(0); + // 扣费类型 1.按次扣费 2.按时间扣费 + String abnormal = abnormalType.get("abnormal").toString(); + if ("1".equals(abnormal)) { + // 次数 + String num = staffModelFieldMap.get(key); + // 次数*扣款金额,保留四位小数 + return CalculationUtil.multiply(num, abnormalType.get("abnormalMoney").toString(), CommonNumConstants.NUM_FOUR); + } else if ("2".equals(abnormal)) { + // 与默认的一样(按时间扣费) + } + } + // 获取月标准小时薪资计算 + String hourWages = CalculationUtil.divide( + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_SALARY.getKey()), + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()), CommonNumConstants.NUM_FOUR); + String resultMoney = "0"; + for (String str : minute) { + resultMoney = CalculationUtil.add( + resultMoney, + CalculationUtil.multiply(CommonNumConstants.NUM_TWO, CalculationUtil.divide(str, "60", CommonNumConstants.NUM_TWO), hourWages), CommonNumConstants.NUM_FOUR); + } + return resultMoney; + } + + /** + * 计算异常考勤旷工的扣薪金额 + * + * @param abnormalTypes 异常类型 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @return + */ + private String calcMinerMoney(List> abnormalTypes, Map staffModelFieldMap) { + if (abnormalTypes != null && !abnormalTypes.isEmpty()) { + Map abnormalType = abnormalTypes.get(0); + // 扣费类型 1.按次扣费 2.按时间扣费 + String abnormal = abnormalType.get("abnormal").toString(); + if ("1".equals(abnormal)) { + // 缺勤次数 + String num = staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_DUTY_NUM.getKey()); + // 次数*扣款金额,保留四位小数 + return CalculationUtil.multiply(num, abnormalType.get("abnormalMoney").toString(), CommonNumConstants.NUM_FOUR); + } else if ("2".equals(abnormal)) { + // 与默认的一样(按时间扣费) + } + } + // 获取月标准小时薪资计算 + String hourWages = CalculationUtil.divide( + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_SALARY.getKey()), + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()), CommonNumConstants.NUM_FOUR); + // 实际缺勤多少小时[应出勤(小时) - 应实际出勤(小时)] + String dutyHour = CalculationUtil.subtract( + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()), + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_REAL_HOUR.getKey()), CommonNumConstants.NUM_FOUR); + return CalculationUtil.multiply(dutyHour, hourWages, CommonNumConstants.NUM_FOUR); + } + + /** + * 计算请假的扣薪情况 + * + * @param systemFoundationSettings 系统基础信息 + * @param staffId 员工id + * @param lastMonthDate 上个月的年月 + * @param staffModelFieldMap 该员工拥有的所有薪资要素字段以及对应的值 + * @return 请假的扣薪金额 + */ + private String calcLeaveTimeMation(Map systemFoundationSettings, String staffId, String lastMonthDate, Map staffModelFieldMap) { + // 获取上个月指定员工的所有审批通过请假记录信息 + List> leaveTime = wagesStaffMationDao.queryLastMonthLeaveTime(staffId, lastMonthDate); + // 企业假期类型以及扣薪信息 + List> holidaysTypeJson = JSONUtil.toList(systemFoundationSettings.get("holidaysTypeJson").toString(), null); + Map>> leaveTimeGroupType = leaveTime.stream() + .collect(Collectors.groupingBy(map -> map.get("leaveType").toString())); + // 获取月标准小时薪资计算 + String hourWages = CalculationUtil.divide( + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_STANDARD_SALARY.getKey()), + staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_HOUR.getKey()), CommonNumConstants.NUM_TWO); + // 计算请假的小时以及请假扣的钱 + String allLeaveHourTime = "0"; + String allLeaveHourMoney = "0"; + for (Map.Entry>> entry : leaveTimeGroupType.entrySet()) { + String leaveType = entry.getKey(); + List> holidays = holidaysTypeJson.stream().filter(bean -> leaveType.equals(bean.get("holidayNo").toString())).collect(Collectors.toList()); + for (Map bean : entry.getValue()) { + // 请假的时长(分钟) + String leaveMinuteTime = DateUtil.getDistanceMinuteByHMS(bean.get("leaveStartTime").toString(), bean.get("leaveEndTime").toString()); + // 请假的时长(小时) + String leaveHourTime = CalculationUtil.divide(leaveMinuteTime, "60", CommonNumConstants.NUM_TWO); + allLeaveHourTime = CalculationUtil.add(allLeaveHourTime, leaveHourTime, CommonNumConstants.NUM_TWO); + if (holidays != null && !holidays.isEmpty()) { + // 该扣薪规则存在,获取扣钱百分比 + String percentage = CalculationUtil.divide(holidays.get(0).get("offPercentageMoney").toString(), "100", CommonNumConstants.NUM_FOUR); + allLeaveHourMoney = CalculationUtil.add( + allLeaveHourMoney, + CalculationUtil.multiply(CommonNumConstants.NUM_FOUR, leaveHourTime, hourWages, percentage), CommonNumConstants.NUM_FOUR); + } else { + allLeaveHourMoney = CalculationUtil.add( + allLeaveHourMoney, + CalculationUtil.multiply(leaveHourTime, hourWages, CommonNumConstants.NUM_FOUR), CommonNumConstants.NUM_FOUR); + } + } + } + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_HOLIDAY_HOUR.getKey(), String.valueOf(allLeaveHourTime)); + return allLeaveHourMoney; + } + + /** + * 设置员工考勤的对应数据信息 + * + * @param lastMonthCheckWork 上个月指定员工的所有考勤记录信息 + * @param staffModelFieldMap 员工拥有的所有薪资要素字段以及对应的值 + * @param lateMinute 上个月迟到的分钟集合 + * @param earlyMinute 上个月早退的分钟集合 + * @param staffWorkTime 该员工拥有的考勤班次id集合 + */ + private void setStaffCheckWorkMation(List> lastMonthCheckWork, Map staffModelFieldMap, + List lateMinute, List earlyMinute, List> staffWorkTime) { + // 全勤以及工时不足的都算为实际出勤 + int lastMonthRealNum = 0; + String lastMonthRealHour = "0"; + int lastMonthLateNum = 0; + int lastMonthEarlyNum = 0; + String lastMonthBeRealHour = "0"; + for (Map bean : lastMonthCheckWork) { + String state = bean.get("state").toString(); + // 能匹配到,说明不是加班的打卡 + List> workTimes = staffWorkTime.stream() + .filter(item -> bean.get("timeId").toString().equals(item.get("timeId").toString())) + .collect(Collectors.toList()); + if (workTimes != null && !workTimes.isEmpty()) { + Map workTime = workTimes.get(0); + // 全勤以及工时不足的都算为实际出勤 + if ("1".equals(state) || "3".equals(state)) { + lastMonthRealNum++; + String time = DateUtil.getDistanceMinuteByHMS(bean.get("clockIn").toString(), bean.get("clockOut").toString()); + lastMonthRealHour = CalculationUtil.add(lastMonthRealHour, time, CommonNumConstants.NUM_TWO); + lastMonthBeRealHour = CalculationUtil.add(lastMonthBeRealHour, + DateUtil.getDistanceMinuteByHMS(workTime.get("startTime").toString(), workTime.get("endTime").toString()), CommonNumConstants.NUM_TWO); + } + // 迟到 + if ("2".equals(bean.get("clockInState").toString())) { + lastMonthLateNum++; + lateMinute.add(DateUtil.getDistanceMinuteByHMS(bean.get("clockIn").toString(), workTime.get("startTime").toString())); + } + // 早退 + if ("2".equals(bean.get("clockOutState").toString())) { + lastMonthEarlyNum++; + earlyMinute.add(DateUtil.getDistanceMinuteByHMS(bean.get("clockOut").toString(), workTime.get("endTime").toString())); + } + } + } + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_REAL_NUM.getKey(), String.valueOf(lastMonthRealNum)); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_REAL_HOUR.getKey(), CalculationUtil.divide(lastMonthRealHour, "60", CommonNumConstants.NUM_TWO)); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_REAL_HOUR.getKey(), CalculationUtil.divide(lastMonthBeRealHour, "60", CommonNumConstants.NUM_TWO)); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_LATE_NUM.getKey(), String.valueOf(lastMonthLateNum)); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_EARLY_NUM.getKey(), String.valueOf(lastMonthEarlyNum)); + // 应出勤班次 + String lastMonthBeNum = staffModelFieldMap.get(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_BE_NUM.getKey()); + // 缺勤的次数 + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.LAST_MONTH_DUTY_NUM.getKey(), + CalculationUtil.subtract(lastMonthBeNum, String.valueOf(lastMonthRealNum), CommonNumConstants.NUM_TWO)); + } + + /** + * 将员工拥有的所有薪资要素字段以及对应的值转换成map + * + * @param staffModelField 该员工应该缴纳的社保公积金的金额 + * @return + */ + private Map convert2Map(List> staffModelField) { + Map staffModelFieldMap = staffModelField.stream() + .collect(Collectors.toMap(bean -> bean.get("fieldKey").toString(), bean -> bean.get("amountMoney").toString())); + return staffModelFieldMap; + } + + /** + * 获取该员工应该缴纳的社保公积金的金额 + * + * @param companyId 企业id + * @param departmentId 部门id + * @param staffId 员工id + * @param socialSecurityFund 所有启动中的社保公积金适用对象关系以及社保公积金参数信息 + * @param staffModelFieldMap 薪资数据 + * @return + */ + private String getSocialSecurityFundMoney(String companyId, String departmentId, String staffId, List socialSecurityFund, + Map staffModelFieldMap) { + // 根据公司id,部门id,员工id找到适用该员工的社保公积金缴纳信息 + List applyThisUserStaffSocialSecurityFund = socialSecurityFund.stream().filter(bean -> { + List objectIds = bean.getApplicableObjectsList().stream().map(ApplicableObjects::getObjectId).collect(Collectors.toList()); + return (objectIds.indexOf(companyId) > -1 || objectIds.indexOf(departmentId) > -1 + || objectIds.indexOf(staffId) > -1); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(applyThisUserStaffSocialSecurityFund)) { + // 因为根据公司id,部门id,员工id会找到多个信息,所以筛选值sortNo最大那个社保公积金 + SocialSecurityFund staffSocialSecurityFund = applyThisUserStaffSocialSecurityFund.stream() + .max(Comparator.comparingInt(SocialSecurityFund::getOrderBy)).get(); + // 养老保险 + String insuranceEndowment = CalculationUtil.multiply(staffSocialSecurityFund.getEndowmentBase(), + CalculationUtil.divide(staffSocialSecurityFund.getEndowmentPerson(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + // 失业保险 + String insuranceUnemployment = CalculationUtil.multiply(staffSocialSecurityFund.getUnemploymentBase(), + CalculationUtil.divide(staffSocialSecurityFund.getUnemploymentPerson(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + // 工伤保险 + String insuranceEmployment = CalculationUtil.multiply(staffSocialSecurityFund.getEmploymentBase(), + CalculationUtil.divide(staffSocialSecurityFund.getEmploymentPerson(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + // 生育保险 + String insuranceMaternity = CalculationUtil.multiply(staffSocialSecurityFund.getMaternityBase(), + CalculationUtil.divide(staffSocialSecurityFund.getMaternityPerson(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + // 医疗保险 + String insuranceMedical = CalculationUtil.multiply(staffSocialSecurityFund.getMedicalBase(), + CalculationUtil.divide(staffSocialSecurityFund.getMedicalPerson(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + String insurance = CalculationUtil.add(CommonNumConstants.NUM_TWO, insuranceEndowment, insuranceUnemployment, insuranceEmployment, insuranceMaternity, + insuranceMedical); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_INSURANCE.getKey(), insurance); + // 公积金 + String accumulation = CalculationUtil.multiply(staffSocialSecurityFund.getAccumulationBase(), + CalculationUtil.divide(staffSocialSecurityFund.getAccumulationPersonScale(), "100", CommonNumConstants.NUM_TWO), CommonNumConstants.NUM_TWO); + staffModelFieldMap.put(WagesConstant.DEFAULT_WAGES_FIELD_TYPE.MONTHLY_SOCIAL_SECURITY_FUND_ACCUMULATION.getKey(), accumulation); + String result = CalculationUtil.add(CommonNumConstants.NUM_TWO, insurance, accumulation, staffSocialSecurityFund.getInsTotalSeriouslyIllIndividual()); + return result; + } + return "0"; + } + + /** + * 获取该员工拥有的所有薪资要素字段以及对应的值 + * + * @param modelIds 薪资模板id + * @param staffId 员工id + * @return + */ + private List> getUserStaffWagesModelField(List modelIds, String staffId) { + if (modelIds == null || modelIds.isEmpty()) { + return new ArrayList<>(); + } + // 获取薪资要素字段以及对应的值 + List> modelField = wagesModelFieldDao.queryWagesModelFieldByModelIdsAndStaffId(modelIds, staffId, null); + return modelField; + } + + /** + * 获取所有公司个人所得税缴纳比例 + * + * @return + */ + private Map>> getTaxRate() { + List> companyTaxRate = companyTaxRateDao.queryAllCompanyTaxRate(); + return companyTaxRate.stream() + .collect(Collectors.groupingBy(map -> map.get("companyId").toString())); + } + + /** + * 加入到redis缓存 + * + * @param staffIds 员工ids + */ + private void setToRedis(List staffIds) { + // 默认存储时间为六个小时 + jedisClient.set(IN_STATISTICS_STAFF_REDIS_KEY, JSONUtil.toJsonStr(staffIds), 60 * 60 * 6); + } + + /** + * 移除指定的员工id存储在redis的缓存 + * + * @param staffId 员工id + */ + private void removeStaffIdInStatisticsRedisMation(String staffId) { + List staffIds = getStaffIdsFromRedis(); + staffIds = staffIds.stream().filter(str -> !staffId.equals(str)).collect(Collectors.toList()); + setToRedis(staffIds); + } + + /** + * 添加指定的员工id存储在redis的缓存 + * + * @param staffId 员工id + */ + private void addStaffIdInStatisticsRedisMation(String staffId) { + List staffIds = getStaffIdsFromRedis(); + staffIds.add(staffId); + setToRedis(staffIds); + } + + /** + * 判断该员工的薪资信息是否在处理中 + * + * @param staffId 员工id + * @return true:处理中,false:未在处理 + */ + private boolean isInStatisticsRedisMation(String staffId) { + List staffIds = getStaffIdsFromRedis(); + return staffIds.contains(staffId); + } + + private void deleteStatisticsRedisMation() { + jedisClient.del(IN_STATISTICS_STAFF_REDIS_KEY); + } + + private List getStaffIdsFromRedis() { + List staffIds = new ArrayList<>(); + if (jedisClient.exists(IN_STATISTICS_STAFF_REDIS_KEY)) { + staffIds = JSONUtil.toList(JSONUtil.parseArray(jedisClient.get(IN_STATISTICS_STAFF_REDIS_KEY)), null); + } + return staffIds; + } + +} diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/field/FieldStaffLinkMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/field/FieldStaffLinkMapper.xml new file mode 100644 index 0000000..6d3e726 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/field/FieldStaffLinkMapper.xml @@ -0,0 +1,113 @@ + + + + + + + UPDATE wages_field_staff_mation + + amount_money = #{item.amountMoney} + + WHERE staff_id = #{item.staffId} + AND field_type_key = #{item.fieldKey} + + + + + + + + + + + UPDATE + wages_field_staff_mation a, + wages_field_type b + + amount_money = '0', + + WHERE a.staff_id = #{staffId} + AND a.field_type_key = b.`key` + AND b.monthly_clearing = '1' + AND b.id = (SELECT c.id FROM wages_field_type c WHERE c.`key` = a.field_type_key ORDER BY c.last_update_time DESC LIMIT 1) + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/field/WagesFieldTypeMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/field/WagesFieldTypeMapper.xml new file mode 100644 index 0000000..fd9ac05 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/field/WagesFieldTypeMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/model/CompanyTaxRateMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/model/CompanyTaxRateMapper.xml new file mode 100644 index 0000000..388ffd9 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/model/CompanyTaxRateMapper.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/model/SysEveUserStaffMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/model/SysEveUserStaffMapper.xml new file mode 100644 index 0000000..b57a673 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/model/SysEveUserStaffMapper.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelFieldMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelFieldMapper.xml new file mode 100644 index 0000000..888ee1a --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelFieldMapper.xml @@ -0,0 +1,35 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelMapper.xml new file mode 100644 index 0000000..e5a580d --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/model/WagesModelMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/payment/WagesPaymentHistoryMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/payment/WagesPaymentHistoryMapper.xml new file mode 100644 index 0000000..ac8984e --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/payment/WagesPaymentHistoryMapper.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-pro/src/main/resources/mapper/social/WagesSocialSecurityFundMapper.xml b/skyeye-wages/wages-pro/src/main/resources/mapper/social/WagesSocialSecurityFundMapper.xml new file mode 100644 index 0000000..42458c6 --- /dev/null +++ b/skyeye-wages/wages-pro/src/main/resources/mapper/social/WagesSocialSecurityFundMapper.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-web/.gitignore b/skyeye-wages/wages-web/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/skyeye-wages/wages-web/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wages/wages-web/pom.xml b/skyeye-wages/wages-web/pom.xml new file mode 100644 index 0000000..406a4cc --- /dev/null +++ b/skyeye-wages/wages-web/pom.xml @@ -0,0 +1,93 @@ + + + + skyeye-wages + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wages-web + + + 8 + 8 + + + + + + com.skyeye + wages-pro + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.jolokia + jolokia-core + + + + + + ${project.artifactId} + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/skyeye-wages/wages-web/src/main/java/com/SkyWagesApplication.java b/skyeye-wages/wages-web/src/main/java/com/SkyWagesApplication.java new file mode 100644 index 0000000..e3a483e --- /dev/null +++ b/skyeye-wages/wages-web/src/main/java/com/SkyWagesApplication.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration(exclude = { + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class +}) +@ComponentScan(basePackages = {"com.skyeye"}) +@EnableTransactionManagement//启注解事务管理,等同于xml配置方式的 +@EnableDiscoveryClient +@EnableFeignClients +public class SkyWagesApplication { + + public static void main(String[] args) { + System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(SkyWagesApplication.class, args); + } + +} diff --git a/skyeye-wages/wages-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java b/skyeye-wages/wages-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java new file mode 100644 index 0000000..561a9bf --- /dev/null +++ b/skyeye-wages/wages-web/src/main/java/com/skyeye/db/config/BaseDataSourceConfig.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.db.config; + +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.exception.CustomException; +import org.apache.commons.collections.CollectionUtils; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = { + "com.skyeye.eve.*.dao", + "com.skyeye.*.dao"}, sqlSessionFactoryRef = "baseSqlSessionFactory") +public class BaseDataSourceConfig { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseDataSourceConfig.class); + + protected static Properties databaseTypeMappings = CommonConstants.getDefaultDatabaseTypeMappings(); + + @Autowired + protected ResourceLoader resourceLoader; + + /** + * Primary 必须加此注解,不然报错,下一个类则不需要添加,表示这个数据源是默认数据源 + * ConfigurationProperties(prefix)值必须是application.properteis中对应属性的前缀 + * + * @return + */ + @Bean(name = "baseDataSource") + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource baseDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * a、SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。 + * b、使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。 + * c、因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。 + * + * @param dataSource + * @return + */ + @Primary + @Bean(name = "baseSqlSessionFactory") + public SqlSessionFactory baseSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) { + MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); + + sqlSessionFactoryBean.setDataSource(dataSource); + String databaseType = this.initDatabaseType(dataSource); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type"); + } else { + try { + // 添加XML目录 + sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations()); + sqlSessionFactoryBean.afterPropertiesSet(); + return sqlSessionFactoryBean.getObject(); + } catch (Exception var5) { + throw new CustomException("Could not create sqlSessionFactory", var5); + } + } + } + + public Resource[] resolveMapperLocations() { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List mapperLocations = new ArrayList<>(); + mapperLocations.add("classpath*:mapper/**/*.xml"); + List resources = new ArrayList(); + if (!CollectionUtils.isEmpty(mapperLocations)) { + for (String mapperLocation : mapperLocations) { + try { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } catch (IOException e) { + LOGGER.error("Get myBatis resources happened exception", e); + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("baseDataSource") DataSource dataSourceOne) { + return new DataSourceTransactionManager(dataSourceOne); + } + + @Primary + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { + // 使用上面配置的Factory + return new SqlSessionTemplate(sqlSessionFactory); + } + + /** + * 初始化 + * + * @param dataSource + * @return + */ + protected String initDatabaseType(@Qualifier("baseDataSource") DataSource dataSource) { + String databaseType = null; + Connection connection = null; + + try { + connection = dataSource.getConnection(); + DatabaseMetaData databaseMetaData = connection.getMetaData(); + String databaseProductName = databaseMetaData.getDatabaseProductName(); + LOGGER.info("database product name: '{}'", databaseProductName); + databaseType = databaseTypeMappings.getProperty(databaseProductName); + if (databaseType == null) { + throw new CustomException("couldn't deduct database type from database product name '" + databaseProductName + "'"); + } + + LOGGER.info("using database type: {}", databaseType); + } catch (SQLException var14) { + LOGGER.error("Exception while initializing Database connection", var14); + } finally { + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException var13) { + LOGGER.error("Exception while closing the Database connection", var13); + } + + } + databaseType = ("dm".equals(databaseType)) ? "oracle" : databaseType; + return databaseType; + } + +} diff --git a/skyeye-wages/wages-web/src/main/resources/banner.txt b/skyeye-wages/wages-web/src/main/resources/banner.txt new file mode 100644 index 0000000..1c184b3 --- /dev/null +++ b/skyeye-wages/wages-web/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/** + * _ooOoo_ + * o8888888o + * 88" . "88 + * (| -_- |) + * O\ = /O + * ____/`---'\____ + * .' \\| |// `. + * / \\||| : |||// \ + * / _||||| -:- |||||- \ + * | | \\\ - /// | | + * | \_| ''\---/'' | | + * \ .-\__ `-` ___/-. / + * ___`. .' /--.--\ `. . __ + * ."" '< `.___\_<|>_/___.' >'"". + * | | : `- \`.;`\ _ /`;.`/ - ` : | | + * \ \ `-. \_ __\ /__ _/ .-` / / + * ======`-.____`-.___\_____/___.-`____.-'====== + * `=---=' + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * 佛祖保佑 永无BUG + * 佛曰: + * 写字楼里写字间,写字间里程序员; + * 程序人员写程序,又拿程序换酒钱。 + * 酒醒只在网上坐,酒醉还来网下眠; + * 酒醉酒醒日复日,网上网下年复年。 + * 但愿老死电脑间,不愿鞠躬老板前; + * 奔驰宝马贵者趣,公交自行程序员。 + * 别人笑我忒疯癫,我笑自己命太贱; + * 不见满街漂亮妹,哪个归得程序员? + * :: springboot 2.x + * :: Skyeye系列框架,作者:卫志强 + * :: 作者独家专属,未购买禁止私自使用 + * 启动:nohup java -jar -Dspring.cloud.nacos.discovery.server-addr=localhost:9000 -Dspring.cloud.nacos.config.server-addr=localhost:9000 -Dspring.profiles.active=dev wages-web.jar >> /opt/service/project/nohup-wages.out 2>&1 & + * 清空日志:cat /dev/null > xxx-web.out +*/ \ No newline at end of file diff --git a/skyeye-wages/wages-web/src/main/resources/bootstrap.yml b/skyeye-wages/wages-web/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..e5a7aa7 --- /dev/null +++ b/skyeye-wages/wages-web/src/main/resources/bootstrap.yml @@ -0,0 +1,42 @@ + +server: + port: 8101 + +spring: + application: + name: skyeye-wages-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: public + cloud: + nacos: + discovery: + server-addr: 172.18.92.40:8848 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: 172.18.92.40:8848 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false +logging: + level: + com.skyeye: debug + +webroot: + # 工作流相关的服务 + skyeye-flowable: skyeye-flowable-${spring.profiles.active} + diff --git a/skyeye-wages/wages-web/src/main/resources/log4j.properties b/skyeye-wages/wages-web/src/main/resources/log4j.properties new file mode 100644 index 0000000..840b663 --- /dev/null +++ b/skyeye-wages/wages-web/src/main/resources/log4j.properties @@ -0,0 +1,70 @@ +### set log levels这里的INFO,Stdout,D,E可以理解为变量,也可以说是输出平台,在下面我们可以看到 ### +log4j.rootLogger = INFO, C, D, E + +### console控制台输出 ### +log4j.appender.C = org.apache.log4j.ConsoleAppender +### System.out也就是输出 out输出是黑色字体,err输出的字体是红色 ### +log4j.appender.C.Target = System.out +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.C.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.C.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### log file INFO级别输出日志文件 ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +### 指定日志输出位置 ### +log4j.appender.D.File = ../logs/skyeye.log +### 这个的意思是指是追加还是覆盖 默认是 true true是追加 false是覆盖 ### +log4j.appender.D.Append = true +### 这个是指日志输出的级别在这里指定的是 INFO级别 ### +log4j.appender.D.Threshold = INFO +### layout是指布局,也就是说输出日志信息的格式样式,在这里我们使用的是log4j提供的 ### +log4j.appender.D.layout = org.apache.log4j.PatternLayout +### 这里就是指定我们日志文件以哪一种格式去输出 ### +log4j.appender.D.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + + +### exception ERROR级别输出日志文件 ### +#这个跟上面一样 只不过是日志级别是 ERROR级的,方便我们直接查看系统异常信息 +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = ../logs/skyeye_error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = [skyeye-promote][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n + +#localhost日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +#localhost日志文件输出处理类2localhost.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +#manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +#manager日志文件输出处理类3manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +#host-manager日志文件输出级别为INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +#host-manager日志文件输出处理类4host-manager.org.apache.juli.FileHandler +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +#设置包名的输出级别 +log4j.logger.com.skyeye.common.filter=info, database +# 记录日志至数据库 +# 这里定义了数据源 +log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender +log4j.appender.database.driver=com.mysql.jdbc.Driver +# BufferSize就是每次缓存多少条数据然后插入数据库,为了演示这里设置为1 +log4j.appender.database.BufferSize=1 +# 数据库连接池 +# 设置要将日志插入到数据库的驱动 +log4j.appender.database.Threshold=info +log4j.appender.database.URL=${jdbc.database.path} +log4j.appender.database.user=${jdbc.database.username} +log4j.appender.database.password=${jdbc.database.password} +# 看名字也该明白这里是定义Sql语句的啦 +log4j.appender.database.sql=insert into sys_work_log (id, class, mothod, create_time, log_level, log_line, message, user_name, file_name, real_path, req_ip) values (REPLACE(UUID(), '-', ''), '%C', '%M', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%l', '%m', '%X{userName}', '%F', '%X{realPath}', '%X{ip}') +log4j.appender.database.layout=org.apache.log4j.PatternLayout + + diff --git a/skyeye-wall/.gitignore b/skyeye-wall/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-wall/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wall/pom.xml b/skyeye-wall/pom.xml new file mode 100644 index 0000000..4cd15fb --- /dev/null +++ b/skyeye-wall/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + + com.skyeye + skyeye-parent + 1.0-SNAPSHOT + + + com.skyeye + skyeye-wall + pom + 1.0-SNAPSHOT + + + wall-common + wall-pro + wall-web + + + \ No newline at end of file diff --git a/skyeye-wall/wall-common/.gitignore b/skyeye-wall/wall-common/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-wall/wall-common/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wall/wall-common/pom.xml b/skyeye-wall/wall-common/pom.xml new file mode 100644 index 0000000..19e8fe1 --- /dev/null +++ b/skyeye-wall/wall-common/pom.xml @@ -0,0 +1,31 @@ + + + + skyeye-wall + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wall-common + + + 8 + 8 + UTF-8 + + + + + + + com.skyeye + skyeye-common-rest + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-wall/wall-pro/.gitignore b/skyeye-wall/wall-pro/.gitignore new file mode 100644 index 0000000..bdd1e1a --- /dev/null +++ b/skyeye-wall/wall-pro/.gitignore @@ -0,0 +1,17 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/skyeye-wall/wall-pro/pom.xml b/skyeye-wall/wall-pro/pom.xml new file mode 100644 index 0000000..e4a706c --- /dev/null +++ b/skyeye-wall/wall-pro/pom.xml @@ -0,0 +1,41 @@ + + + + skyeye-wall + com.skyeye + 1.0-SNAPSHOT + + 4.0.0 + + wall-pro + + + 8 + 8 + UTF-8 + + + + + + + com.skyeye + wall-common + 1.0-SNAPSHOT + + + org.jboss.logging + jboss-logging + 3.3.2.Final + + + com.skyeye + skyeye-base + 1.0-SNAPSHOT + + + + + \ No newline at end of file diff --git a/skyeye-wall/wall-pro/pom.xml.rej b/skyeye-wall/wall-pro/pom.xml.rej new file mode 100644 index 0000000..5d3b0d4 --- /dev/null +++ b/skyeye-wall/wall-pro/pom.xml.rej @@ -0,0 +1,15 @@ +diff a/skyeye-wall/wall-pro/pom.xml b/skyeye-wall/wall-pro/pom.xml (rejected hunks) +@@ -25,12 +25,6 @@ + wall-common + 1.0-SNAPSHOT + +- +- org.jboss.logging +- jboss-logging +- 3.3.2.Final +- +- + + + +\ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/controller/BackgroundController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/controller/BackgroundController.java new file mode 100644 index 0000000..59afa78 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/controller/BackgroundController.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.background.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.background.entity.Background; +import com.skyeye.background.service.BackgroundService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: BackgroundController + * @Description: 背景图片管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "背景图片管理", tags = "背景图片管理", modelName = "背景图片管理") +public class BackgroundController { + + @Autowired + private BackgroundService backgroundService; + + /** + * 分页查询历史背景图片 + * + * @param inputObject + * @param outputObject + */ + @ApiOperation(id = "queryBackgroundList", value = "分页查询历史背景图片", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/BackgroundController/queryBackgroundList") + public void queryBackgroundList(InputObject inputObject, OutputObject outputObject) { + backgroundService.queryPageList(inputObject, outputObject); + } + + /** + * 新增背景图片 + * + * @param inputObject + * @param outputObject + */ + @ApiOperation(id = "insertBackground", value = "修改背景图片", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Background.class) + @RequestMapping("/post/BackgroundController/insertBackground") + public void insertBackground(InputObject inputObject, OutputObject outputObject) { + backgroundService.createEntity(inputObject, outputObject); + } + + /** + * 根据id删除背景图片 + * + * @param inputObject + * @param outputObject + */ + @ApiOperation(id = "deleteBackgroundById", value = "根据id删除背景图片", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/BackgroundController/deleteBackgroundById") + public void deleteBackgroundById(InputObject inputObject, OutputObject outputObject) { + backgroundService.deleteById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/dao/BackgroundDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/dao/BackgroundDao.java new file mode 100644 index 0000000..4ff6699 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/dao/BackgroundDao.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.background.dao; + +import com.skyeye.background.entity.Background; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: BackgroundDao + * @Description: 背景图片数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BackgroundDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/entity/Background.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/entity/Background.java new file mode 100644 index 0000000..d455aff --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/entity/Background.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.background.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Background + * @Description: 背景图片实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_background") +@ApiModel(value = "背景图实体类") +public class Background extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("image") + @ApiModelProperty(value = "图片", required = "required") + private String image; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/BackgroundService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/BackgroundService.java new file mode 100644 index 0000000..e489094 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/BackgroundService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.background.service; + +import com.skyeye.background.entity.Background; +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: backgroundService + * @Description: 背景图片服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface BackgroundService extends SkyeyeBusinessService { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/impl/BackgroundServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/impl/BackgroundServiceImpl.java new file mode 100644 index 0000000..7c49e39 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/background/service/impl/BackgroundServiceImpl.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ +package com.skyeye.background.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.background.dao.BackgroundDao; +import com.skyeye.background.entity.Background; +import com.skyeye.background.service.BackgroundService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.user.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: backgroundServiceImpl + * @Description: 背景图片服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "背景图片管理", groupName = "背景图片管理") +public class BackgroundServiceImpl extends SkyeyeBusinessServiceImpl implements BackgroundService { + + @Autowired + private UserService userService; + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Background::getCreateId), userId); + return queryWrapper; + } + @Override + public void createPostpose(Background background, String userId) { + userService.updateBackgroundImage(userId, background.getImage()); + } + + @Override + public void deletePreExecution(String id) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String createId = selectById(id).getCreateId(); + if (!userId.equals(createId)) { + throw new CustomException("无权限"); + } + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/classenum/StateEnum.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/classenum/StateEnum.java new file mode 100644 index 0000000..4583c1c --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/classenum/StateEnum.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.classenum; + +import com.skyeye.common.base.classenum.SkyeyeEnumClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @ClassName: StateEnum + * @Description: 学生认证状态枚举类 + * @author: skyeye云系列--卫志强 + * @date: 2024/5/15 8:58 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum StateEnum implements SkyeyeEnumClass { + UNVERIFIED(1, "未认证", true, false), + CERTIFIEDING(2, "认证中", true, false), + CERTIFIEDFAILURE(3, "认证失败", true, false), + CERTIFIEDSUCCESS(4, "认证成功", true, true); + + private Integer key; + + private String value; + + private Boolean show; + + private Boolean isDefault; +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/controller/CertificationController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/controller/CertificationController.java new file mode 100644 index 0000000..2750f00 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/controller/CertificationController.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.certification.entity.Certification; +import com.skyeye.certification.service.CertificationService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CertificationController + * @Description: 学生认证信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "学生认证管理", tags = "学生认证管理", modelName = "学生认证管理") +public class CertificationController { + + @Autowired + private CertificationService certificationService; + + /** + * 获取学生认证信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCertificationList", value = "获取学生认证信息", method = "POST", allUse = "1") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CertificationController/queryCertificationList") + public void queryCertificationList(InputObject inputObject, OutputObject outputObject) { + certificationService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id查询认证信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCertificationById", value = "根据id查询认证信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "用户id", required = "required")}) + @RequestMapping("/post/CertificationController/queryCertificationById") + public void queryCertificationById(InputObject inputObject, OutputObject outputObject) { + certificationService.queryByUserId(inputObject, outputObject); + } + + /** + * 新增/编辑学生认证信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "saveOrUpdateCertification", value = "新增/编辑学生认证信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Certification.class) + @RequestMapping("/post/CertificationController/saveOrUpdateCertification") + public void saveOrUpdateCertification(InputObject inputObject, OutputObject outputObject) { + certificationService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 审核学生信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "reviewInformation", value = "审核学生信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required"), + @ApiImplicitParam(id = "state", name = "state", value = "状态", required = "required")}) + @RequestMapping("/post/CertificationController/reviewInformation") + public void reviewInformation(InputObject inputObject, OutputObject outputObject) { + certificationService.reviewInformation(inputObject, outputObject); + } + + /** + * 根据学生学号查询已认证的学生信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserByStudentNumber", value = "根据学生学号查询已认证的学生信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "studentNumber", name = "studentNumber", value = "学生学号,多个逗号隔开", required = "required")}) + @RequestMapping("/post/CertificationController/queryUserByStudentNumber") + public void queryUserByStudentNumber(InputObject inputObject, OutputObject outputObject) { + certificationService.queryUserByStudentNumber(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/dao/CertificationDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/dao/CertificationDao.java new file mode 100644 index 0000000..74b3bc8 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/dao/CertificationDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.dao; + +import com.skyeye.certification.entity.Certification; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CertificationDao + * @Description: 学生认证信息数据层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CertificationDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/entity/Certification.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/entity/Certification.java new file mode 100644 index 0000000..4dba601 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/entity/Certification.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: Certification + * @Description: 学生信息认证实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "wall:certification", value = {"id", "userId"}, cacheTime = RedisConstants.TEN_DAY_SECONDS) +@TableName(value = "wall_certification") +@ApiModel(value = "学生认证实体类") +public class Certification extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("user_id") + @Property(value = "用户id") + private String userId; + + @TableField("`name`") + @ApiModelProperty(value = "姓名", required = "required", fuzzyLike = true) + private String name; + + @TableField("campus") + @ApiModelProperty(value = "校区", required = "required") + private String campus; + + @TableField("student_number") + @ApiModelProperty(value = "学号", required = "required") + private String studentNumber; + + @TableField("id_photo_front") + @ApiModelProperty(value = "身份证正面照片", required = "required") + private String idPhotoFront; + + @TableField("id_photo_other") + @ApiModelProperty(value = "身份证反面照片", required = "required") + private String idPhotoOther; + + @TableField("student_id_photo") + @ApiModelProperty(value = "学生证照片", required = "required") + private String studentIdPhoto; + + @TableField("state") + @ApiModelProperty(value = "状态,参考#StuteEnum") + private Integer state; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/CertificationService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/CertificationService.java new file mode 100644 index 0000000..05561a5 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/CertificationService.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.certification.entity.Certification; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import java.util.List; + +/** + * @ClassName: CertificationService + * @Description: 学生认证信息服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CertificationService extends SkyeyeBusinessService { + void reviewInformation(InputObject inputObject, OutputObject outputObject); + + void queryByUserId(InputObject inputObject, OutputObject outputObject); + + List getCertificationListByIds(List userIds); + + void queryUserByStudentNumber(InputObject inputObject, OutputObject outputObject); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/impl/CertificationServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/impl/CertificationServiceImpl.java new file mode 100644 index 0000000..52ce3e0 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/certification/service/impl/CertificationServiceImpl.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.certification.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.certification.classenum.StateEnum; +import com.skyeye.certification.dao.CertificationDao; +import com.skyeye.certification.entity.Certification; +import com.skyeye.certification.service.CertificationService; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.user.entity.User; +import com.skyeye.user.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: CertificationServiceImpl + * @Description: 学生认证信息服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/24 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "学生认证管理", groupName = "学生认证管理") +public class CertificationServiceImpl extends SkyeyeBusinessServiceImpl implements CertificationService { + + @Autowired + private CertificationService certificationService; + + @Autowired + private UserService userService; + + @Override + protected QueryWrapper getQueryWrapper(CommonPageInfo commonPageInfo) { + QueryWrapper queryWrapper = super.getQueryWrapper(commonPageInfo); + if (StrUtil.isNotEmpty(commonPageInfo.getState())) { + if (!StrUtil.equals(commonPageInfo.getState(), "All")) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Certification::getState), commonPageInfo.getState()); + } + } + return queryWrapper; + } + + public List getCertificationListByIds(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Certification::getUserId), ids); + List certificationList = list(queryWrapper); + return certificationList; + } + + @Override + public void queryByUserId(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (id.equals(userId)) { + Certification certification = selectById(userId); + outputObject.setBean(certification); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } else { + throw new CustomException("无权限"); + } + } + + @Override + public void validatorEntity(Certification certification) { + String id = certification.getId(); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (StrUtil.isEmpty(id)) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Certification::getUserId), userId); + Certification certificationFlag = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(certificationFlag)) { + throw new CustomException("认证信息已提交,不可重复提交"); + } + } else { + Certification certificationFlag = certificationService.selectById(id); + if (!userId.equals(certificationFlag.getUserId())) { + throw new CustomException("无权限,不可修改!!"); + } + if (certificationFlag.getState() == StateEnum.CERTIFIEDING.getKey()) { + throw new CustomException("管理员正在审核,暂时无法修改认证信息编辑"); + } + if (certificationFlag.getState() == StateEnum.CERTIFIEDSUCCESS.getKey()) { + throw new CustomException("已认证,不可修改"); + } + } + } + + @Override + public void createPrepose(Certification certification) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + certification.setUserId(userId); + certification.setState(StateEnum.CERTIFIEDING.getKey()); + } + + @Override + public void updatePrepose(Certification certification) { + certification.setState(StateEnum.CERTIFIEDING.getKey()); + } + + @Override + public void reviewInformation(InputObject inputObject, OutputObject outputObject) { + String id = inputObject.getParams().get("id").toString(); + Integer state = Integer.parseInt(inputObject.getParams().get("state").toString()); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Certification::getState), state); + update(updateWrapper); + if (state == StateEnum.CERTIFIEDSUCCESS.getKey()) { + Certification certification = certificationService.selectById(id); + userService.setCertification(certification.getUserId(), certification.getStudentNumber(), certification.getName()); + } + refreshCache(id); + } + + @Override + public void queryUserByStudentNumber(InputObject inputObject, OutputObject outputObject) { + String studentNumber = inputObject.getParams().get("studentNumber").toString(); + List studentNumberList = Arrays.asList(studentNumber.split(CommonCharConstants.COMMA_MARK)); + // 查询学生认证信息 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Certification::getStudentNumber), studentNumberList); + queryWrapper.eq(MybatisPlusUtil.toColumns(Certification::getState), StateEnum.CERTIFIEDSUCCESS.getKey()); + List certificationList = list(queryWrapper); + if (CollectionUtil.isEmpty(certificationList)) { + return; + } + // 查询用户信息 + List userIdList = certificationList.stream().map(Certification::getUserId).distinct().collect(Collectors.toList()); + List userList = userService.selectByIds(userIdList.toArray(new String[userIdList.size()])); + outputObject.setBeans(userList); + outputObject.settotal(userList.size()); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/controller/CircleController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/controller/CircleController.java new file mode 100644 index 0000000..4b9cdf1 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/controller/CircleController.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.circle.entity.Circle; +import com.skyeye.circle.service.CircleService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CircleController + * @Description: 圈子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "圈子管理", tags = "圈子管理", modelName = "圈子管理") +public class CircleController { + + @Autowired + private CircleService circleService; + + /** + * 获取圈子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCircleList", value = "获取圈子信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CircleController/queryCircleList") + public void queryCircleList(InputObject inputObject, OutputObject outputObject) { + circleService.queryPageList(inputObject, outputObject); + } + + /** + * 新增圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertCircle", value = "新增圈子信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Circle.class) + @RequestMapping("/post/CircleController/insertCircle") + public void insertCircle(InputObject inputObject, OutputObject outputObject) { + circleService.createEntity(inputObject, outputObject); + } + + /** + * 根据ID删除圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCircleById", value = "根据ID删除圈子信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CircleController/deleteCircleById") + public void deleteCircleById(InputObject inputObject, OutputObject outputObject) { + circleService.deleteById(inputObject, outputObject); + } + + /** + * 根据ID查询圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "selectCircleById", value = "根据ID查询圈子信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CircleController/selectCircleById") + public void selectCircleById(InputObject inputObject, OutputObject outputObject) { + circleService.selectById(inputObject, outputObject); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/dao/CircleDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/dao/CircleDao.java new file mode 100644 index 0000000..bfb3f32 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/dao/CircleDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circle.dao; + +import com.skyeye.circle.entity.Circle; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CircleDao + * @Description: 圈子信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CircleDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/entity/Circle.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/entity/Circle.java new file mode 100644 index 0000000..4253277 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/entity/Circle.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Circle + * @Description: 圈子实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_circle") +@ApiModel(value = "圈子实体层") +public class Circle extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id") + private String id; + + @TableField("title") + @ApiModelProperty(value = "标题", required = "required") + private String title; + + @TableField("`describe`") + @ApiModelProperty(value = "描述") + private String describe; + + @TableField("img") + @ApiModelProperty(value = "图片", required = "required") + private String img; + + @TableField("view_num") + @ApiModelProperty(value = "浏览数量") + private Integer viewNum; + + @TableField("num") + @ApiModelProperty(value = "圈子人数") + private Integer num; +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/CircleService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/CircleService.java new file mode 100644 index 0000000..c45e66a --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/CircleService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.circle.entity.Circle; + +/** + * @ClassName: CircleService + * @Description: 圈子服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CircleService extends SkyeyeBusinessService { + void updateViewNum(String circleId, Integer count); + + void updateJoinNum(String circleId, Integer collectNum); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/impl/CircleServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/impl/CircleServiceImpl.java new file mode 100644 index 0000000..2d8618a --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circle/service/impl/CircleServiceImpl.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circle.service.impl; + + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.circle.dao.CircleDao; +import com.skyeye.circle.entity.Circle; +import com.skyeye.circle.service.CircleService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.service.MaterialService; +import com.skyeye.post.service.PostService; +import com.skyeye.user.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: CircleServiceImpl + * @Description: 圈子服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "圈子管理", groupName = "圈子管理") +public class CircleServiceImpl extends SkyeyeBusinessServiceImpl implements CircleService { + + @Autowired + private PostService postService; + + @Autowired + private UserService userService; + + @Autowired + private MaterialService materialService; + + @Override + public void validatorEntity(Circle circle) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Circle::getTitle), circle.getTitle()); + if (ObjectUtil.isNotEmpty(getOne(queryWrapper))) { + throw new CustomException("标题重复"); + } + } + + @Override + public void createPrepose(Circle circle) { + circle.setViewNum(CommonNumConstants.NUM_ZERO); + circle.setNum(CommonNumConstants.NUM_ZERO); + } + + @Override + public void deletePreExecution(Circle circle) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(circle.getCreateId())) { + throw new CustomException("无权限"); + } + } + + @Override + public void deletePostpose(String id) { + postService.deleteByCircleId(id); + materialService.deleteByCircleId(id); + } + + @Override + public Circle selectById(String id) { + Circle circle = super.selectById(id); + userService.setDataMation(circle, Circle::getCreateId); + return circle; + } + + @Override + public void updateViewNum(String circleId, Integer count) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, circleId); + updateWrapper.set(MybatisPlusUtil.toColumns(Circle::getNum), count); + update(updateWrapper); + } + + @Override + public void updateJoinNum(String circleId, Integer joinNum) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, circleId); + updateWrapper.set(MybatisPlusUtil.toColumns(Circle::getViewNum), joinNum); + update(updateWrapper); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/controller/CircleViewController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/controller/CircleViewController.java new file mode 100644 index 0000000..e4b8b42 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/controller/CircleViewController.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circleview.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.circleview.entity.CircleView; +import com.skyeye.circleview.service.CircleViewService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CircleController + * @Description: 圈子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "圈子浏览记录管理", tags = "圈子浏览记录管理", modelName = "圈子浏览记录管理") +public class CircleViewController { + + @Autowired + private CircleViewService circleViewService; + + /** + * 获取圈子浏览信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyCircleList", value = "获取圈子浏览信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CircleViewController/queryMyCircleList") + public void queryMyCircleList(InputObject inputObject, OutputObject outputObject) { + circleViewService.queryMyCircleList(inputObject, outputObject); + } + + /** + * 新增圈子浏览信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertCircleView", value = "新增圈子浏览信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CircleView.class) + @RequestMapping("/post/CircleViewController/insertCircleView") + public void insertCircleView(InputObject inputObject, OutputObject outputObject) { + circleViewService.createEntity(inputObject, outputObject); + } + + /** + * 根据ID删除圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCircleById", value = "根据ID删除圈子浏览信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CircleViewController/deleteCircleById") + public void deleteCircleById(InputObject inputObject, OutputObject outputObject) { + circleViewService.deleteById(inputObject, outputObject); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/dao/CircleViewDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/dao/CircleViewDao.java new file mode 100644 index 0000000..d12ae58 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/dao/CircleViewDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circleview.dao; + +import com.skyeye.circleview.entity.CircleView; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +/** + * @ClassName: CircleDao + * @Description: 圈子信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CircleViewDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/entity/CircleView.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/entity/CircleView.java new file mode 100644 index 0000000..2b1a041 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/entity/CircleView.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circleview.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: Circle + * @Description: 圈子实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_circle_view") +@ApiModel(value = "圈子浏览记录实体层") +public class CircleView extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id") + private String id; + + @TableField("create_id") + @ApiModelProperty(value = "创建人id") + private String createId; + + @TableField("circle_id") + @ApiModelProperty(value = "圈子id", required = "required") + private String circleId; + +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/CircleViewService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/CircleViewService.java new file mode 100644 index 0000000..20a4c95 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/CircleViewService.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circleview.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.circleview.entity.CircleView; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +/** + * @ClassName: CircleService + * @Description: 圈子服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CircleViewService extends SkyeyeBusinessService { + void queryMyCircleList(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/impl/CircleViewServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/impl/CircleViewServiceImpl.java new file mode 100644 index 0000000..b45792f --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/circleview/service/impl/CircleViewServiceImpl.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.circleview.service.impl; + + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.circle.entity.Circle; +import com.skyeye.circle.service.CircleService; +import com.skyeye.circleview.dao.CircleViewDao; +import com.skyeye.circleview.entity.CircleView; +import com.skyeye.circleview.service.CircleViewService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ClassName: CircleServiceImpl + * @Description: 圈子服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "圈子浏览记录管理", groupName = "圈子浏览记录管理") +public class CircleViewServiceImpl extends SkyeyeBusinessServiceImpl implements CircleViewService { + + @Autowired + private CircleService circleService; + + @Override + public void queryMyCircleList(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + Page page = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CircleView::getCreateId), userId); + List circleViewList = list(queryWrapper); + outputObject.setBeans(circleViewList); + outputObject.settotal(page.size()); + } + + @Override + public String createEntity(CircleView circleView, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CircleView::getCircleId), circleView.getCircleId()) + .eq(MybatisPlusUtil.toColumns(CircleView::getCreateId), userId); + long count = count(queryWrapper); + if (count > 0) { + return StrUtil.EMPTY; + } + return super.createEntity(circleView, userId); + } + + @Override + public void validatorEntity(CircleView circleView) { + Circle circle = circleService.selectById(circleView.getCircleId()); + if (StrUtil.isEmpty(circle.getId())) { + throw new CustomException("圈子不存在"); + } + } + + @Override + public void createPrepose(CircleView circleView) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + circleView.setCreateId(userId); + } + + @Override + public void createPostpose(CircleView circleView, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CircleView::getCircleId), circleView.getCircleId()); + long count = count(queryWrapper); + circleService.updateViewNum(circleView.getCircleId(), (int) count); + } + + @Override + public void deletePreExecution(CircleView circleView) { + Circle circle = circleService.selectById(circleView.getCircleId()); + if (ObjectUtil.isEmpty(circle)) { + throw new CustomException("圈子不存在"); + } + } + + @Override + public void deletePostpose(CircleView circleView) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(CircleView::getCircleId), circleView.getCircleId()); + long count = count(queryWrapper); + circleService.updateViewNum(circleView.getCircleId(), (int) count); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/controller/CommentController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/controller/CommentController.java new file mode 100644 index 0000000..654414a --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/controller/CommentController.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.comment.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.comment.entity.Comment; +import com.skyeye.comment.service.CommentService; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: CommentController + * @Description: 评论信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "评论管理", tags = "评论管理", modelName = "评论管理") +public class CommentController { + + @Autowired + private CommentService commentService; + + /** + * 获取评论信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryCommentList", value = "获取评论信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/CommentController/queryCommentList") + public void queryCommentList(InputObject inputObject, OutputObject outputObject) { + commentService.queryPageList(inputObject, outputObject); + } + + /** + * 新增评论信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertComment", value = "新增评论信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Comment.class) + @RequestMapping("/post/CommentController/insertComment") + public void insertComment(InputObject inputObject, OutputObject outputObject) { + commentService.createEntity(inputObject, outputObject); + } + + /** + * 根据ID删除评论信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCommentById", value = "根据ID删除评论信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CommentController/deleteCommentById") + public void deleteCommentById(InputObject inputObject, OutputObject outputObject) { + commentService.deleteById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/dao/CommentDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/dao/CommentDao.java new file mode 100644 index 0000000..a75124d --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/dao/CommentDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.comment.dao; + +import com.skyeye.comment.entity.Comment; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CommentDao + * @Description: 评论信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CommentDao extends SkyeyeBaseMapper { + List> queryCommentList(CommonPageInfo commonPageInfo); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/entity/Comment.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/entity/Comment.java new file mode 100644 index 0000000..c000e7e --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/entity/Comment.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.comment.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.user.entity.User; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Comment + * @Description: 评论实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_comment") +@ApiModel(value = "评论实体类") +public class Comment extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("content") + @ApiModelProperty(value = "评论内容") + private String content; + + @TableField("ip") + @Property(value = "IP属地") + private String ip; + + @TableField("upvote_num") + @Property(value = "点赞数量") + private String upvoteNum; + + @TableField("anonymity") + @ApiModelProperty(value = "是否匿名,参考#WhetherEnum", required = "required,num") + private Integer anonymity; + + @TableField("comment_id") + @ApiModelProperty(value = "被评论的评论id") + private String commentId; + + @TableField("parent_id") + @ApiModelProperty(value = "父节点id") + private String parentId; + + @TableField("post_id") + @ApiModelProperty(value = "被评论的帖子id", required = "required") + private String postId; + + @TableField("user_id") + @Property(value = "被回复人id") + private String userId; + + @TableField(exist = false) + @Property(value = "被回复人信息") + private User userMation; + + @TableField(exist = false) + @ApiModelProperty(value = "评论图片", required = "json") + private Map picture; + + @TableField(exist = false) + @Property(value = "当前登陆人是否点赞") + private Boolean checkUpvote; + +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/CommentService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/CommentService.java new file mode 100644 index 0000000..25685a9 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/CommentService.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.comment.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.comment.entity.Comment; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: CommentService + * @Description: 评论服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface CommentService extends SkyeyeBusinessService { + + Map> getCommentMapListByIds(List postIds); + + void deleteByPostId(String id); + + void deleteByPostIds(List postIds); + + void updateCommentUpvoteNum(String id, String count); + + List queryCommentList(String userId); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/impl/CommentServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/impl/CommentServiceImpl.java new file mode 100644 index 0000000..90ba433 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/comment/service/impl/CommentServiceImpl.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.comment.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.comment.dao.CommentDao; +import com.skyeye.comment.entity.Comment; +import com.skyeye.comment.service.CommentService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.CalculationUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.picture.entity.Picture; +import com.skyeye.picture.service.PictureService; +import com.skyeye.post.entity.Post; +import com.skyeye.post.service.PostService; +import com.skyeye.upvote.service.UpvoteService; +import com.skyeye.user.service.UserService; +import com.xxl.job.core.util.IpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: CommentServiceImpl + * @Description: 评论服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "评论管理", groupName = "评论管理") +public class CommentServiceImpl extends SkyeyeBusinessServiceImpl implements CommentService { + + @Autowired + private UserService userService; + + @Autowired + private CommentService commentService; + + @Autowired + private PostService postService; + + @Autowired + private PictureService pictureService; + + @Autowired + private UpvoteService upvoteService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryCommentList(commonPageInfo); + List ids = beans.stream() + .map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + + // 查询子评论 + List child = getCommentMapList(ids); + List> mapList = JSONUtil.toList(JSONUtil.toJsonStr(child), null); + beans.addAll(mapList); + + // 获取评论的匿名信息 + Map anonymityMap = beans.stream() + .collect(Collectors.toMap(bean -> bean.get("id").toString(), bean -> Integer.parseInt(bean.get("anonymity").toString()))); + + // 获取评论图片 + ids = beans.stream() + .map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + Map> picturetMap = pictureService.getPictureMapListByIds(ids); + // 获取点赞信息 + String userId = inputObject.getLogParams().get("id").toString(); + Map checkUpvoteMap = upvoteService.checkUpvote(userId, ids.toArray(new String[]{})); + + beans.forEach(bean -> { + String id = bean.get("id").toString(); + // 被回复评论id + String commentId = bean.get("commentId").toString(); + // 是否匿名 + Integer anonymity = Integer.parseInt(bean.get("anonymity").toString()); + if (anonymity == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + bean.put("createId", StrUtil.EMPTY); + bean.put("lastUpdateId", StrUtil.EMPTY); + } + if (StrUtil.isNotEmpty(commentId)) { + if (anonymityMap.get(commentId) == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + bean.put("userId", StrUtil.EMPTY); + } + } + // 设置图片信息 + List pictures = picturetMap.get(id); + if (CollectionUtil.isNotEmpty(pictures)) { + bean.put("picture", pictures.stream().findFirst().orElse(null)); + } + // 设置点赞信息 + bean.put("checkUpvote", checkUpvoteMap.get(id)); + }); + userService.setMationForMap(beans, "createId", "createMation"); + userService.setMationForMap(beans, "userId", "userMation"); + return beans; + } + + + public List getCommentMapList(List parentIds) { + if (CollectionUtil.isEmpty(parentIds)) { + return CollectionUtil.newArrayList(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Comment::getParentId), parentIds); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Comment::getCreateTime)); + List commentList = list(queryWrapper); + return commentList; + } + + @Override + public Map> getCommentMapListByIds(List postIds) { + if (CollectionUtil.isEmpty(postIds)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Comment::getPostId), postIds); + queryWrapper.eq(MybatisPlusUtil.toColumns(Comment::getParentId), StrUtil.EMPTY); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Comment::getCreateTime)); + List commentList = list(queryWrapper); + + List ids = commentList.stream() + .map(Comment::getId).collect(Collectors.toList()); + Map> picturetMap = pictureService.getPictureMapListByIds(ids); + commentList.forEach(comment -> { + String id = comment.getId(); + if (comment.getAnonymity() == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + comment.setCreateId(StrUtil.EMPTY); + comment.setLastUpdateId(StrUtil.EMPTY); + } + List pictures = picturetMap.get(id); + if (CollectionUtil.isNotEmpty(pictures)) { + comment.setPicture(JSONUtil.toBean(JSON.toJSONString(pictures.stream().findFirst().orElse(null)), null)); + } + }); + userService.setDataMation(commentList, Comment::getCreateId); + Map> commentMap = commentList.stream() + .collect(Collectors.groupingBy(Comment::getPostId)); + return commentMap; + } + + @Override + public void deleteByPostId(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Comment::getPostId), id); + List list = list(queryWrapper); + List ids = list.stream().map(Comment::getId).collect(Collectors.toList()); + pictureService.deleteByCommentIds(ids); + remove(queryWrapper); + } + + @Override + public void deleteByPostIds(List postIds) { + if (CollectionUtil.isEmpty(postIds)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Comment::getPostId), postIds); + List list = list(queryWrapper); + List ids = list.stream().map(Comment::getId).collect(Collectors.toList()); + pictureService.deleteByCommentIds(ids); + remove(queryWrapper); + } + + @Override + public void deletePostpose(Comment entity) { + // 删除子评论 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Comment::getParentId), entity.getId()); + List commentList = list(queryWrapper); + List ids = commentList.stream() + .map(Comment::getId).collect(Collectors.toList()); + ids.add(entity.getId()); + pictureService.deleteByCommentIds(ids); + remove(queryWrapper); + // 查询所有评论条数,更新帖子评论总数 + QueryWrapper countQueryWrapper = new QueryWrapper<>(); + countQueryWrapper.eq(MybatisPlusUtil.toColumns(Comment::getPostId), entity.getPostId()); + long count = count(countQueryWrapper); + postService.updateCommentCount(entity.getPostId(), String.valueOf(count)); + } + + @Override + protected void deletePreExecution(Comment comment) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String postId = comment.getPostId(); + Post post = postService.selectById(postId); + if (post.getCreateId().equals(userId)) { + return; + } + if (!userId.equals(comment.getCreateId())) { + throw new CustomException("无权限"); + } + } + + @Override + public void createPrepose(Comment entity) { + entity.setUpvoteNum(String.valueOf(CommonNumConstants.NUM_ZERO)); + if (StrUtil.isNotEmpty(entity.getCommentId())) { + Comment comment = commentService.selectById(entity.getCommentId()); + entity.setUserId(comment.getCreateId()); + } + entity.setIp(IpUtil.getIp()); + } + + @Override + public void createPostpose(Comment comment, String userId) { + addCommentNum(comment.getPostId()); + if (CollectionUtil.isNotEmpty(comment.getPicture())) { + Picture picture = new Picture(); + picture.setImg(comment.getPicture().get("img").toString()); + picture.setOrderBy(comment.getPicture().get("orderBy").toString()); + picture.setObjectId(comment.getId()); + pictureService.createEntity(picture, userId); + } + } + + public void addCommentNum(String postId) { + Post post = postService.selectById(postId); + if (post.getCommentNum() != null) { + postService.updateCommentCount(post.getId(), CalculationUtil.add(CommonNumConstants.NUM_ZERO, + post.getCommentNum(), String.valueOf(CommonNumConstants.NUM_ONE))); + } + } + + @Override + public void updateCommentUpvoteNum(String id, String count) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Comment::getUpvoteNum), count); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void validatorEntity(Comment comment) { + super.validatorEntity(comment); + Post post = postService.selectById(comment.getPostId()); + if (ObjectUtil.isEmpty(post) && StrUtil.isEmpty(post.getId())) { + throw new CustomException("无此帖子,不可评论!"); + } + Comment parentComment = commentService.selectById(comment.getCommentId()); + if (ObjectUtil.isEmpty(parentComment) && StrUtil.isEmpty(parentComment.getId())) { + throw new CustomException("无此评论,不可评论!"); + } + } + + @Override + public List queryCommentList(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Comment::getCreateId), userId); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Comment::getCreateTime)); + return list(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/controller/HistoryPostController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/controller/HistoryPostController.java new file mode 100644 index 0000000..285ae24 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/controller/HistoryPostController.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.historypost.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.historypost.entity.HistoryPost; +import com.skyeye.historypost.service.HistoryPostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: HistoryPostController + * @Description: 历史帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "历史帖子管理", tags = "历史帖子管理", modelName = "历史帖子管理") +public class HistoryPostController { + + @Autowired + private HistoryPostService historyPostService; + + /** + * 新增历史帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertHistoryPost", value = "新增历史帖子信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = HistoryPost.class) + @RequestMapping("/post/HistoryPostController/insertHistoryPost") + public void insertHistoryPost(InputObject inputObject, OutputObject outputObject) { + historyPostService.createEntity(inputObject, outputObject); + } + + /** + * 一键删除历史帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMyHistoryPost", value = "一键删除历史帖子信息", method = "POST", allUse = "2") + @RequestMapping("/post/HistoryPostController/deleteMyHistoryPost") + public void deleteMyHistoryPost(InputObject inputObject, OutputObject outputObject) { + historyPostService.deleteMyHistoryPost(inputObject, outputObject); + } + + /** + * 批量删除历史帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteHistoryPostByIds", value = "批量删除历史帖子信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids",name = "ids", value = "id列表",required = "required")}) + @RequestMapping("/post/HistoryPostController/deleteHistoryPostByIds") + public void deleteHistoryPostByIds(InputObject inputObject, OutputObject outputObject) { + historyPostService.deleteHistoryPostByIds(inputObject, outputObject); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/dao/HistoryPostDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/dao/HistoryPostDao.java new file mode 100644 index 0000000..ec6740f --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/dao/HistoryPostDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.historypost.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.historypost.entity.HistoryPost; + +/** + * @ClassName: HistoryPostDao + * @Description: ;历史帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface HistoryPostDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/entity/HistoryPost.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/entity/HistoryPost.java new file mode 100644 index 0000000..bffe1f3 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/entity/HistoryPost.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.historypost.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: HistoryPost + * @Description: 历史帖子实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_history_post") +@ApiModel(value = "历史帖子实体类") +public class HistoryPost extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("create_id") + @ApiModelProperty(value = "创建人id") + private String createId; + + @TableField("post_id") + @ApiModelProperty(value = "帖子id", required = "required") + private String postId; + + @TableField("create_time") + @ApiModelProperty("创建人时间") + private String createTime; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/HistoryPostService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/HistoryPostService.java new file mode 100644 index 0000000..73076b6 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/HistoryPostService.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.historypost.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.historypost.entity.HistoryPost; + +import java.util.List; + +/** + * @ClassName: HistoryPostService + * @Description: 历史帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface HistoryPostService extends SkyeyeBusinessService { + List getHistoryPostById(String userId); + + void deleteMyHistoryPost(InputObject inputObject, OutputObject outputObject); + + void deleteHistoryPostByIds(InputObject inputObject, OutputObject outputObject); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/impl/HistoryPostServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/impl/HistoryPostServiceImpl.java new file mode 100644 index 0000000..68bf421 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/historypost/service/impl/HistoryPostServiceImpl.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.historypost.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonCharConstants; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.historypost.dao.HistoryPostDao; +import com.skyeye.historypost.entity.HistoryPost; +import com.skyeye.historypost.service.HistoryPostService; +import com.skyeye.popularpost.service.PopularPostService; +import com.skyeye.post.entity.Post; +import com.skyeye.post.service.PostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ClassName: HistoryPostServiceImpl + * @Description: 历史帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "历史帖子管理", groupName = "历史帖子管理") +public class HistoryPostServiceImpl extends SkyeyeBusinessServiceImpl implements HistoryPostService { + + @Autowired + private PostService postService; + + @Override + public List getHistoryPostById(String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HistoryPost::getCreateId), userId); + queryWrapper.select(MybatisPlusUtil.toColumns(HistoryPost::getPostId)); + queryWrapper.groupBy(MybatisPlusUtil.toColumns(HistoryPost::getPostId)); + List historyPostList = list(queryWrapper); + return historyPostList; + } + + + @Autowired + private PopularPostService popularPostService; + + @Override + public String createEntity(HistoryPost entity, String userId) { + popularPostService.insertPopularPostList(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HistoryPost::getPostId), entity.getPostId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(HistoryPost::getCreateId), userId); + queryWrapper.eq(MybatisPlusUtil.toColumns(HistoryPost::getCreateTime), DateUtil.getYmdTimeAndToString()); + long length = count(queryWrapper); + if (length > 0) { + return StrUtil.EMPTY; + } + return super.createEntity(entity, userId); + } + + @Override + public void createPrepose(HistoryPost historyPost) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + historyPost.setCreateId(userId); + historyPost.setCreateTime(DateUtil.getYmdTimeAndToString()); + } + + @Override + public void createPostpose(HistoryPost historyPost, String userId) { + Post post = postService.selectById(historyPost.getPostId()); + if (post.getViewNum() != null) { + Integer flag = Integer.parseInt(post.getViewNum()) + CommonNumConstants.NUM_ONE; + postService.updateViewCount(historyPost.getPostId(), String.valueOf(flag)); + } else { + postService.updateViewCount(historyPost.getPostId(), String.valueOf(CommonNumConstants.NUM_ZERO)); + } + } + + @Override + public void deleteMyHistoryPost(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(HistoryPost::getCreateId), userId); + remove(queryWrapper); + } + + @Override + public void deleteHistoryPostByIds(InputObject inputObject, OutputObject outputObject) { + String ids = inputObject.getParams().get("ids").toString(); + List idList = Arrays.asList(ids.split(CommonCharConstants.COMMA_MARK)); + idList = idList.stream().filter(StrUtil::isNotEmpty).distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(idList)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, idList); + remove(queryWrapper); + outputObject.setBeans(idList); + outputObject.settotal(idList.size()); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/controller/JoinCircleController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/controller/JoinCircleController.java new file mode 100644 index 0000000..7467e32 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/controller/JoinCircleController.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.joincircle.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.joincircle.entity.JoinCircle; +import com.skyeye.joincircle.service.JoinCircleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: JoinCircleController + * @Description: 加入圈子管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "加入圈子管理", tags = "加入圈子管理", modelName = "加入圈子管理") +public class JoinCircleController { + + @Autowired + private JoinCircleService joinCircleService; + + /** + * 新增加入圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertCircleCollect", value = "新增加入圈子信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = JoinCircle.class) + @RequestMapping("/post/CircleCollectController/insertCircleCollect") + public void insertCircleCollect(InputObject inputObject, OutputObject outputObject) { + joinCircleService.createEntity(inputObject, outputObject); + } + + /** + * 根据ID删除加入圈子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteCircleCollectById", value = "根据ID删除加入圈子信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/CircleCollectController/deleteCircleCollectById") + public void deleteCircleCollectById(InputObject inputObject, OutputObject outputObject) { + joinCircleService.deleteById(inputObject, outputObject); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/dao/JoinCircleDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/dao/JoinCircleDao.java new file mode 100644 index 0000000..3c426af --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/dao/JoinCircleDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.joincircle.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.joincircle.entity.JoinCircle; + +/** + * @ClassName: JoinCircleDao + * @Description: 加入圈子信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JoinCircleDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/entity/JoinCircle.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/entity/JoinCircle.java new file mode 100644 index 0000000..9176d7f --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/entity/JoinCircle.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.joincircle.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: CircleCollect + * @Description: 加入圈子实体层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_join_circle") +@ApiModel(value = "加入圈子实体层") +public class JoinCircle extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id") + private String id; + + @TableField("circle_id") + @ApiModelProperty("圈子id") + private String circleId; + + @TableField("create_id") + @ApiModelProperty("创建人id") + private String createId; + + @TableField("create_time") + @ApiModelProperty("创建时间") + private String createTime; +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/JoinCircleService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/JoinCircleService.java new file mode 100644 index 0000000..b6886e2 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/JoinCircleService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.joincircle.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.joincircle.entity.JoinCircle; + +/** + * @ClassName: JoinCircleService + * @Description: 加入圈子服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface JoinCircleService extends SkyeyeBusinessService { + JoinCircle selectByCircleId(String circleId, String userId); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/impl/JoinCircleServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/impl/JoinCircleServiceImpl.java new file mode 100644 index 0000000..eac93e1 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/joincircle/service/impl/JoinCircleServiceImpl.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.joincircle.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.circle.service.CircleService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.joincircle.dao.JoinCircleDao; +import com.skyeye.joincircle.entity.JoinCircle; +import com.skyeye.joincircle.service.JoinCircleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: JoinCircleServiceImpl + * @Description: 加入圈子服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "加入圈子管理", groupName = "加入圈子管理") +public class JoinCircleServiceImpl extends SkyeyeBusinessServiceImpl implements JoinCircleService { + + @Autowired + private CircleService circleService; + + @Override + public void validatorEntity(JoinCircle joinCircle) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + joinCircle.setCreateId(userId); + joinCircle.setCreateTime(DateUtil.getTimeAndToString()); + } + + @Override + public void createPostpose(JoinCircle joinCircle, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JoinCircle::getCreateId), joinCircle.getCircleId()); + long count = count(queryWrapper); + circleService.updateJoinNum(joinCircle.getCircleId(), (int) count); + } + + @Override + public void deletePreExecution(JoinCircle joinCircle) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(joinCircle.getCreateId())) { + throw new CustomException("无权限!"); + } + } + + @Override + public void deletePostpose(JoinCircle joinCircle) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JoinCircle::getCreateId), joinCircle.getCircleId()); + long count = count(queryWrapper); + circleService.updateJoinNum(joinCircle.getCircleId(), (int) count); + } + + @Override + public JoinCircle selectByCircleId(String circleId, String userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(JoinCircle::getCircleId), circleId); + queryWrapper.eq(MybatisPlusUtil.toColumns(JoinCircle::getCreateId), userId); + JoinCircle joinCircle = getOne(queryWrapper); + return ObjectUtil.isEmpty(joinCircle) ? new JoinCircle(): joinCircle; + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/controller/MaterialController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/controller/MaterialController.java new file mode 100644 index 0000000..db1fcc6 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/controller/MaterialController.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.material.entity.Material; +import com.skyeye.material.service.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: MaterialController + * @Description: 资料信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "资料管理", tags = "资料管理", modelName = "资料管理") +public class MaterialController { + + @Autowired + private MaterialService materialService; + + /** + * 根据ID获取资料信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMaterialById", value = "根据ID获取资料信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/queryMaterialById") + public void queryMaterialById(InputObject inputObject, OutputObject outputObject) { + materialService.selectById(inputObject, outputObject); + } + + /** + * 新增/编辑资料信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "saveOrUpdateMaterial", value = "新增/编辑资料信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Material.class) + @RequestMapping("/post/MaterialController/saveOrUpdateMaterial") + public void saveOrUpdateMaterial(InputObject inputObject, OutputObject outputObject) { + materialService.saveOrUpdateEntity(inputObject, outputObject); + } + + /** + * 根据ID删除资料信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteMaterialById", value = "根据ID删除资料信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/MaterialController/deleteMaterialById") + public void deleteMaterialById(InputObject inputObject, OutputObject outputObject) { + materialService.deleteById(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java new file mode 100644 index 0000000..891644c --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/dao/MaterialDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.material.entity.Material; + +/** + * @ClassName: MaterialDao + * @Description: 资料信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/entity/Material.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/entity/Material.java new file mode 100644 index 0000000..074e54d --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/entity/Material.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.BaseGeneralInfo; +import lombok.Data; + +import java.util.Map; + +/** + * @ClassName: Material + * @Description: 资料实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_material") +@ApiModel(value = "资料实体类") +public class Material extends BaseGeneralInfo { + + @TableId("id") + @ApiModelProperty(value = "主键id") + private String id; + + @TableField("content") + @ApiModelProperty(value = "内容", required = "required") + private String content; + + @TableField("circle_id") + @ApiModelProperty(value = "圈子id", required = "required") + private String circleId; + + @TableField(exist = false) + @Property("圈子信息") + private Map circleMation; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/MaterialService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/MaterialService.java new file mode 100644 index 0000000..634c839 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/MaterialService.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.material.entity.Material; + +/** + * @ClassName: MaterialService + * @Description: 资料服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface MaterialService extends SkyeyeBusinessService { + void deleteByCircleId(String circleId); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java new file mode 100644 index 0000000..3733d7c --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/material/service/impl/MaterialServiceImpl.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.material.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.circle.entity.Circle; +import com.skyeye.circle.service.CircleService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.material.dao.MaterialDao; +import com.skyeye.material.entity.Material; +import com.skyeye.material.service.MaterialService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: MaterialServiceImpl + * @Description: 资料服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "资料管理", groupName = "资料管理") +public class MaterialServiceImpl extends SkyeyeBusinessServiceImpl implements MaterialService { + + @Autowired + private CircleService circleService; + + @Override + public Material selectById(String id) { + Material material = super.selectById(id); + circleService.setDataMation(material, Material::getCircleId); + return material; + } + + @Override + public void validatorEntity(Material material) { + //修改时的校验 + if (ObjectUtil.isNotEmpty(material.getId())) { + Circle circle = circleService.selectById(material.getCircleId()); + if (StrUtil.isEmpty(circle.getId())) { + throw new CustomException("圈子不存在"); + } + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(circle.getCreateId())) { + throw new CustomException("无权限"); + } + } else { + //新增校验 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getCircleId), material.getCircleId()); + Material flagMaterial = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(flagMaterial)) { + throw new CustomException("不可重复新增"); + } + } + } + + @Override + public void deletePreExecution(Material material) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(material.getCreateId())) { + throw new CustomException("无权限"); + } + } + + @Override + public void deleteByCircleId(String circleId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Material::getCircleId), circleId); + remove(queryWrapper); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/dao/PictureDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/dao/PictureDao.java new file mode 100644 index 0000000..2eaaeb2 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/dao/PictureDao.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.picture.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.picture.entity.Picture; + +/** + * @ClassName: PictureDao + * @Description: 图片信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PictureDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/entity/Picture.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/entity/Picture.java new file mode 100644 index 0000000..4c8e90f --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/entity/Picture.java @@ -0,0 +1,40 @@ +package com.skyeye.picture.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.features.OperatorUserInfo; +import lombok.Data; + +/** + * @ClassName: Picture + * @Description: 图片实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_picture") +@ApiModel(value = "图片实体类") +public class Picture extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("object_id") + @Property(value = "第三方业务数据id") + private String objectId; + + @TableField("img") + @ApiModelProperty(value = "图片内容", required = "required") + private String img; + + @TableField("order_by") + @ApiModelProperty(value = "排序方式") + private String orderBy; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/PictureService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/PictureService.java new file mode 100644 index 0000000..e3fd702 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/PictureService.java @@ -0,0 +1,28 @@ +package com.skyeye.picture.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.picture.entity.Picture; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: PictureService + * @Description: 图片服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PictureService extends SkyeyeBusinessService { + + Map> getPictureMapListByIds(List postIds); + + List queryLinkListByPostId(String id); + + void deleteByPostId(String id); + + void deleteByPostIds(List postIds); + + void deleteByCommentIds(List ids); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/impl/PictureServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/impl/PictureServiceImpl.java new file mode 100644 index 0000000..fa12557 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/picture/service/impl/PictureServiceImpl.java @@ -0,0 +1,77 @@ +package com.skyeye.picture.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.picture.dao.PictureDao; +import com.skyeye.picture.entity.Picture; +import com.skyeye.picture.service.PictureService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: PictureServiceImpl + * @Description: 图片服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "图片管理", groupName = "图片管理") +public class PictureServiceImpl extends SkyeyeBusinessServiceImpl implements PictureService { + + @Override + public Map> getPictureMapListByIds(List objectIds) { + if (CollectionUtil.isEmpty(objectIds)) { + return MapUtil.newHashMap(); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Picture::getObjectId), objectIds); + queryWrapper.orderByAsc(MybatisPlusUtil.toColumns(Picture::getOrderBy)); + List pictureList = list(queryWrapper); + Map> pictureMap = pictureList.stream() + .collect(Collectors.groupingBy(Picture::getObjectId)); + return pictureMap; + } + + @Override + public void deleteByPostId(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Picture::getObjectId), id); + remove(queryWrapper); + } + + @Override + public void deleteByPostIds(List postIds) { + if (CollectionUtil.isEmpty(postIds)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Picture::getObjectId), postIds); + remove(queryWrapper); + } + + @Override + public void deleteByCommentIds(List ids) { + if (CollectionUtil.isEmpty(ids)) { + return; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Picture::getObjectId), ids); + remove(queryWrapper); + } + + @Override + public List queryLinkListByPostId(String PostId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Picture::getObjectId), PostId); + return list(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/dao/PopularPostDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/dao/PopularPostDao.java new file mode 100644 index 0000000..06830d2 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/dao/PopularPostDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.popularpost.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.popularpost.entity.PopularPost; + +/** + * @ClassName: PopularPostDao + * @Description: ;历史帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PopularPostDao extends SkyeyeBaseMapper { +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/entity/PopularPost.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/entity/PopularPost.java new file mode 100644 index 0000000..13f10c0 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/entity/PopularPost.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.popularpost.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: PopularPost + * @Description: 热门帖子实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_popular_post") +@ApiModel(value = "帖子实体类") +public class PopularPost extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("post_id") + @ApiModelProperty(value = "被评论的帖子id", required = "required") + private String postId; + + @TableField("`top`") + @ApiModelProperty(value = "排名", required = "required") + private Integer top; + + @TableField("upvote_num") + @ApiModelProperty(value = "点赞次数", required = "required") + private Integer upvoteNum; + + @TableField("comment_num") + @ApiModelProperty(value = "评论次数", required = "required") + private Integer commentNum; + + @TableField("view_num") + @ApiModelProperty(value = "浏览次数", required = "required") + private Integer viewNum; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间", required = "required") + private String createTime; +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/PopularPostService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/PopularPostService.java new file mode 100644 index 0000000..04d435d --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/PopularPostService.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.popularpost.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.popularpost.entity.PopularPost; + +import java.util.List; + +/** + * @ClassName: PopularPostService + * @Description: 热门帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PopularPostService extends SkyeyeBusinessService { + void insertPopularPostList(); + + List queryTodayPopularPostList(); +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/impl/PopularPostServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/impl/PopularPostServiceImpl.java new file mode 100644 index 0000000..5ae0aa8 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/popularpost/service/impl/PopularPostServiceImpl.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.popularpost.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.popularpost.dao.PopularPostDao; +import com.skyeye.popularpost.entity.PopularPost; +import com.skyeye.popularpost.service.PopularPostService; +import com.skyeye.post.entity.Post; +import com.skyeye.post.service.PostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @ClassName: PopularPostServiceImpl + * @Description: 热门帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "热门帖子管理", groupName = "热门帖子管理") +public class PopularPostServiceImpl extends SkyeyeBusinessServiceImpl implements PopularPostService { + + @Autowired + private PostService postService; + + @Autowired + private PopularPostService popularPostService; + + @Override + public void insertPopularPostList() { + //取出前30天内的post + List postList = postService.getBeforeThirtyDaysPost(); + //取出点赞量、评论量、浏览量 + Map> listMap = getAll(postList); + //计算权重 + Map powerMap = calculatePower(listMap); + //排序权重 + List powerResult = sortByMapValue(powerMap); + //取出前十的帖子 + List popularPostList = getBeforeTenPopularPostList(powerResult, postList); + popularPostService.createEntity(popularPostList, null); + } + + + public Map> getAll(List postList) { + Map> listMap = new HashMap<>(); + for (Post post : postList) { + List flag = new ArrayList<>(); + flag.add(Integer.parseInt(post.getUpvoteNum())); + flag.add(Integer.parseInt(post.getCommentNum())); + if (StrUtil.isEmpty(post.getViewNum())) { + flag.add(CommonNumConstants.NUM_ZERO); + } else { + flag.add(Integer.parseInt(post.getViewNum())); + } + listMap.put(post.getId(), flag); + } + return listMap; + } + + public Map calculatePower(Map> listMap) { + Map powerMap = new HashMap<>(); + listMap.forEach((key, list) -> { + double power = list.get(CommonNumConstants.NUM_ZERO) * 0.5 + + list.get(CommonNumConstants.NUM_ONE) * 0.2 + list.get(CommonNumConstants.NUM_TWO) * 0.3; + powerMap.put(key, power); + }); + return powerMap; + } + + public List sortByMapValue(Map doubleMap) { + List> list = new LinkedList<>(doubleMap.entrySet()); + CollectionUtil.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue())); + List result = new ArrayList<>(list.size()); + for (Map.Entry entry : list) { + result.add(entry.getKey()); + } + return result; + } + + public List getBeforeTenPopularPostList(List powerResult, List postList) { + List popularPostList = new ArrayList<>(); + for (int i = 0; i < postList.size(); i++) { + for (String s : powerResult) { + if (postList.get(i).getId().equals(s)) { + PopularPost popularPost = new PopularPost(); + popularPost.setPostId(s); + popularPost.setTop(i + CommonNumConstants.NUM_ONE); + popularPost.setUpvoteNum(Integer.parseInt(postList.get(i).getUpvoteNum())); + popularPost.setCommentNum(Integer.parseInt(postList.get(i).getCommentNum())); + if (StrUtil.isNotEmpty(postList.get(i).getViewNum())) { + popularPost.setViewNum(Integer.parseInt(postList.get(i).getViewNum())); + } else { + popularPost.setViewNum(CommonNumConstants.NUM_ZERO); + } + popularPost.setCreateTime(DateUtil.getYmdTimeAndToString()); + popularPostList.add(popularPost); + } + } + } + return CollectionUtil.sub(popularPostList, 0, 10); + } + + @Override + public List queryTodayPopularPostList() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(PopularPost::getCreateTime), DateUtil.getYmdTimeAndToString()); + return list(queryWrapper); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/controller/PostController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/controller/PostController.java new file mode 100644 index 0000000..1e0d968 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/controller/PostController.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.post.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.post.entity.Post; +import com.skyeye.post.service.PostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: PostController + * @Description: 帖子信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "帖子管理", tags = "帖子管理", modelName = "帖子管理") +public class PostController { + + @Autowired + private PostService postService; + + /** + * 获取帖子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPostList", value = "获取帖子信息列表", method = "POST", allUse = "0") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PostController/queryPostList") + public void queryPostList(InputObject inputObject, OutputObject outputObject) { + postService.queryPageList(inputObject, outputObject); + } + + /** + * 根据ID获取帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPostById", value = "根据ID获取帖子信息", method = "GET", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PostController/queryPostById") + public void queryPostById(InputObject inputObject, OutputObject outputObject) { + postService.selectById(inputObject, outputObject); + } + + /** + * 新增帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "insertPost", value = "新增帖子信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Post.class) + @RequestMapping("/post/PostController/insertPost") + public void insertPost(InputObject inputObject, OutputObject outputObject) { + postService.createEntity(inputObject, outputObject); + } + + /** + * 根据ID删除帖子信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deletePostById", value = "根据ID删除帖子信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/PostController/deletePostById") + public void deletePostById(InputObject inputObject, OutputObject outputObject) { + postService.deleteById(inputObject, outputObject); + } + + /** + * 通过点赞获取帖子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPostListByUpvote", value = "通过点赞获取帖子信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PostController/queryPostListByUpvote") + public void queryPostListByUpvote(InputObject inputObject, OutputObject outputObject) { + postService.queryPostListByUpvote(inputObject, outputObject); + } + + /** + * 通过评论获取帖子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPostListByComment", value = "通过评论获取帖子信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PostController/queryPostListByComment") + public void queryPostListByComment(InputObject inputObject, OutputObject outputObject) { + postService.queryPostListByComment(inputObject, outputObject); + } + + /** + * 获取历史浏览的帖子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryPostListByHistoryPost", value = "获取历史浏览的帖子信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/PostController/queryPostListByHistoryPost") + public void queryPostListByHistoryPost(InputObject inputObject, OutputObject outputObject) { + postService.queryPostListByHistoryPost(inputObject, outputObject); + } + + /** + * 获取热门帖子信息列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryHotPostList", value = "获取热门帖子信息列表", method = "POST", allUse = "0") + @RequestMapping("/post/PostController/queryHotPostList") + public void queryHotPostList(InputObject inputObject, OutputObject outputObject) { + postService.queryHotPostList(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/dao/PostDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/dao/PostDao.java new file mode 100644 index 0000000..fd59b8d --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/dao/PostDao.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.post.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.post.entity.Post; + +/** + * @ClassName: PostDao + * @Description: 帖子信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PostDao extends SkyeyeBaseMapper { +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/entity/Post.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/entity/Post.java new file mode 100644 index 0000000..a876a54 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/entity/Post.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.post.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.comment.entity.Comment; +import com.skyeye.common.constans.RedisConstants; +import com.skyeye.common.entity.features.OperatorUserInfo; +import com.skyeye.picture.entity.Picture; +import lombok.Data; + +import java.util.List; + +/** + * @ClassName: Post + * @Description: 帖子实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@RedisCacheField(name = "wall:post", cacheTime = RedisConstants.TOW_MONTH_SECONDS) +@TableName(value = "wall_post") +@ApiModel(value = "帖子实体类") +public class Post extends OperatorUserInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("content") + @ApiModelProperty(value = "发帖内容", required = "required") + private String content; + + @TableField("ip") + @Property(value = "IP属地") + private String ip; + + @TableField("anonymity") + @ApiModelProperty(value = "是否匿名,参考#WhetherEnum", required = "required,num") + private Integer anonymity; + + @TableField("city") + @Property(value = "城市") + private String city; + + @TableField("address") + @Property(value = "地址") + private String address; + + @TableField("upvote_num") + @Property(value = "点赞数量") + private String upvoteNum; + + @TableField("comment_num") + @Property(value = "评论数量") + private String commentNum; + + @TableField("view_num") + @Property(value = "浏览数量") + private String viewNum; + + @TableField("type_id") + @ApiModelProperty(value = "帖子类型") + private String typeId; + + @TableField("circle_id") + @ApiModelProperty(value = "圈子id") + private String circleId; + + @TableField(exist = false) + @ApiModelProperty(value = "九宫格图片", required = "json") + private List pictureList; + + @TableField(exist = false) + @ApiModelProperty(value = "评论列表", required = "json") + private List commentList; + + @TableField(exist = false) + @Property(value = "当前登陆人是否点赞") + private Boolean checkUpvote; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/PostService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/PostService.java new file mode 100644 index 0000000..2e050ce --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/PostService.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.post.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.post.entity.Post; + +import java.util.List; + +/** + * @ClassName: PostService + * @Description: 帖子服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface PostService extends SkyeyeBusinessService { + + void updateCommentCount(String id, String count); + + void updateUpvoteCount(String id, String count); + + void updateViewCount(String id, String count); + + void queryPostListByUpvote(InputObject inputObject, OutputObject outputObject); + + void queryPostListByComment(InputObject inputObject, OutputObject outputObject); + + void queryPostListByHistoryPost(InputObject inputObject, OutputObject outputObject); + + List getBeforeThirtyDaysPost(); + + void deleteByCircleId(String circleId); + + void queryHotPostList(InputObject inputObject, OutputObject outputObject); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/impl/PostServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/impl/PostServiceImpl.java new file mode 100644 index 0000000..a2577ca --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/post/service/impl/PostServiceImpl.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.post.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.comment.entity.Comment; +import com.skyeye.comment.service.CommentService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.WhetherEnum; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.IPSeeker; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.historypost.entity.HistoryPost; +import com.skyeye.historypost.service.HistoryPostService; +import com.skyeye.joincircle.service.JoinCircleService; +import com.skyeye.picture.entity.Picture; +import com.skyeye.picture.service.PictureService; +import com.skyeye.popularpost.entity.PopularPost; +import com.skyeye.popularpost.service.PopularPostService; +import com.skyeye.post.dao.PostDao; +import com.skyeye.post.entity.Post; +import com.skyeye.post.service.PostService; +import com.skyeye.upvote.entity.Upvote; +import com.skyeye.upvote.service.UpvoteService; +import com.skyeye.user.service.UserService; +import com.xxl.job.core.util.IpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @ClassName: PostServiceImpl + * @Description: 帖子服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "帖子管理", groupName = "帖子管理") +public class PostServiceImpl extends SkyeyeBusinessServiceImpl implements PostService { + + @Autowired + private CommentService commentService; + + @Autowired + private PictureService pictureService; + + @Autowired + private UserService userService; + + @Autowired + private UpvoteService upvoteService; + + @Autowired + private HistoryPostService historyPostService; + + @Autowired + private PopularPostService popularPostService; + + @Autowired + private JoinCircleService joinCircleService; + + + private List> queryPostList(InputObject inputObject) { + Map params = inputObject.getParams(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (params.containsKey("holderId") && StrUtil.isNotEmpty(params.get("holderId").toString())) { + queryWrapper.eq(MybatisPlusUtil.toColumns(Post::getCircleId), params.get("holderId").toString()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Post::getCreateTime)); + List postList = list(queryWrapper); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(postList), null); + // 传holderId时,判断是否已加入该圈子 + String userId = InputObject.getLogParamsStatic().get("id").toString(); + String circleId = params.get("holderId").toString(); + String createId = joinCircleService.selectByCircleId(circleId, userId).getCreateId(); + return StrUtil.isEmpty(createId) ? CollectionUtil.sub(beans, CommonNumConstants.NUM_ZERO, CommonNumConstants.NUM_TEN) : beans; + } else if (params.containsKey("type") && StrUtil.isNotEmpty(params.get("type").toString())) { + String typeId = params.get("type").toString(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Post::getCreateId), typeId).or() + .eq(MybatisPlusUtil.toColumns(Post::getTypeId), typeId) + .orderByDesc(MybatisPlusUtil.toColumns(Post::getCreateTime)); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list(queryWrapper)), null); + return beans; + } else { + queryWrapper.eq(MybatisPlusUtil.toColumns(Post::getCircleId), null).or() + .eq(MybatisPlusUtil.toColumns(Post::getCircleId), "") + .orderByDesc(MybatisPlusUtil.toColumns(Post::getCreateTime)); + List> beans = JSONUtil.toList(JSONUtil.toJsonStr(list(queryWrapper)), null); + return beans; + } + } + + @Override + public List> queryPageDataList(InputObject inputObject) { + List> beans = queryPostList(inputObject); + List postIds = beans.stream() + .map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + // 获取评论信息 + Map> commentMap = commentService.getCommentMapListByIds(postIds); + // 获取帖子图片信息 + Map> pictureMap = pictureService.getPictureMapListByIds(postIds); + // 获取点赞信息 + String userId = inputObject.getLogParams().get("id").toString(); + Map checkUpvoteMap = upvoteService.checkUpvote(userId, postIds.toArray(new String[]{})); + beans.forEach(bean -> { + String id = bean.get("id").toString(); + // 是否匿名 + Integer anonymity = Integer.parseInt(bean.get("anonymity").toString()); + if (anonymity == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + bean.put("createId", StrUtil.EMPTY); + bean.put("lastUpdateId", StrUtil.EMPTY); + } + // 设置评论信息 + bean.put("commentList", CollectionUtil.sub(commentMap.get(id), CommonNumConstants.NUM_ZERO, CommonNumConstants.NUM_FIVE)); + // 设置图片信息 + bean.put("pictureList", CollectionUtil.sub(pictureMap.get(id), CommonNumConstants.NUM_ZERO, CommonNumConstants.NUM_NINE)); + bean.put("pictureSize", pictureMap.size()); + // 设置点赞信息 + bean.put("checkUpvote", checkUpvoteMap.get(id)); + }); + userService.setMationForMap(beans, "createId", "createMation"); + return beans; + } + + @Override + public void createPrepose(Post entity) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + entity.setCreateId(userId); + entity.setIp(IpUtil.getLocalAddress().toString()); + HttpServletRequest request = PutObject.getRequest(); + String ipAddress = ToolUtil.getIpByRequest(request); + String address = IPSeeker.getCountry(ipAddress); + entity.setAddress(address); + String city = IPSeeker.getCurCityByCountry(address); + entity.setCity(city); + entity.setUpvoteNum("0"); + entity.setCommentNum("0"); + entity.setViewNum("0"); + if (entity.getPictureList().size() > 20) { + throw new CustomException("超过可上传的图片数量"); + } + } + + @Override + public void createPostpose(Post entity, String userId) { + entity.getPictureList().forEach(picture -> { + picture.setObjectId(entity.getId()); + }); + pictureService.createEntity(entity.getPictureList(), userId); + } + + @Override + public Post getDataFromDb(String id) { + Post post = super.getDataFromDb(id); + post.setPictureList(pictureService.queryLinkListByPostId(id)); + return post; + } + + @Override + public Post selectById(String id) { + Post post = super.selectById(id); + if (post.getAnonymity() == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + post.setCreateId(StrUtil.EMPTY); + post.setLastUpdateId(StrUtil.EMPTY); + } else { + userService.setDataMation(post, Post::getCreateId); + } + return post; + } + + @Override + public void deletePreExecution(Post post) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(post.getCreateId())) { + throw new CustomException("无权限"); + } + } + + @Override + public void deletePostpose(String id) { + pictureService.deleteByPostId(id); + commentService.deleteByPostId(id); + } + + @Override + public void updateCommentCount(String id, String count) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Post::getCommentNum), count); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void updateUpvoteCount(String id, String count) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Post::getUpvoteNum), count); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void updateViewCount(String id, String count) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(Post::getViewNum), count); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void queryPostListByUpvote(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String userId = commonPageInfo.getObjectId(); + List upvoteList = upvoteService.queryUpvoteList(userId); + if (CollectionUtil.isEmpty(upvoteList)) { + return; + } + Map map = new HashMap<>(); + for (int i = 0; i < upvoteList.size(); i++) { + map.put(i, upvoteList.get(i).getObjectId()); + } + //分页 + Page page = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + List list = commentAndUpvoteOperationPost(userId, map); + outputObject.setBeans(list); + outputObject.settotal(page.size()); + } + + @Override + public void queryPostListByComment(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String userId = commonPageInfo.getObjectId(); + //查询自己的评论 + List myCommentList = commentService.queryCommentList(userId); + if (CollectionUtil.isEmpty(myCommentList)) { + return; + } + Map map = new HashMap<>(); + for (int i = 0; i < myCommentList.size(); i++) { + map.put(i, myCommentList.get(i).getPostId()); + } + //分页 + Page page = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + List list = commentAndUpvoteOperationPost(userId, map); + outputObject.setBeans(list); + outputObject.settotal(page.size()); + } + + public List commentAndUpvoteOperationPost(String userId, Map map) { + List postIds = new ArrayList<>(); + map.forEach((key, value) -> postIds.add(value)); + //查询post + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, postIds); + List list = list(queryWrapper); + List sortPostList = new ArrayList<>(); + map.forEach((key, value) -> { + for (Post post : list) { + if (value.equals(post.getId())) { + sortPostList.add(post); + } + } + }); + //查询PictureList、checkUpvote、commentList + Map> pictureMap = pictureService.getPictureMapListByIds(postIds); + Map booleanMap = upvoteService.checkUpvote(userId, postIds.toArray(new String[]{})); + Map> commentListMap = commentService.getCommentMapListByIds(postIds); + //设置PictureList、checkUpvote、commentList + sortPostList.forEach(post -> { + if (post.getAnonymity() == WhetherEnum.ENABLE_USING.getKey()) { + // 匿名 + post.setCreateId(StrUtil.EMPTY); + post.setLastUpdateId(StrUtil.EMPTY); + } + post.setPictureList(pictureMap.get(post.getId())); + post.setCheckUpvote(booleanMap.get(post.getId())); + post.setCommentList(CollectionUtil.sub(commentListMap.get(post.getId()), + CommonNumConstants.NUM_ZERO, CommonNumConstants.NUM_FIVE)); + }); + userService.setDataMation(list, Post::getCreateId); + return sortPostList; + } + + @Override + public void queryPostListByHistoryPost(InputObject inputObject, OutputObject outputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + Page pages = PageHelper.startPage(commonPageInfo.getPage(), commonPageInfo.getLimit()); + // 查询自己的历史记录 + List historyPostList = historyPostService.getHistoryPostById(userId); + if (CollectionUtil.isEmpty(historyPostList)) { + return; + } + List postIds = historyPostList.stream() + .map(HistoryPost::getPostId).collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, postIds); + List postList = list(queryWrapper); + //设置点赞信息 + Map checkUpvoteMap = upvoteService.checkUpvote(userId, postIds.toArray(new String[]{})); + checkUpvoteMap.forEach((key, value) -> { + postList.forEach(post -> { + if (post.getId().equals(key)) { + post.setCheckUpvote(value); + } + }); + }); + outputObject.setBeans(postList); + outputObject.settotal(pages.size()); + } + + @Override + public List getBeforeThirtyDaysPost() { + //获取前三十天以内的日期 + String beforeDay = getBeforeOrFutureDay(-29); + String today = DateUtil.getTimeAndToString(); + //查询近三十天的帖子 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper + // 取浏览量超过1的帖子 + .ge(MybatisPlusUtil.toColumns(Post::getViewNum), "1") + // 取前三十天以内的帖子 + .between(MybatisPlusUtil.toColumns(Post::getCreateTime), beforeDay, today) + .orderByDesc(MybatisPlusUtil.toColumns(Post::getCreateTime)); + return list(queryWrapper); + } + + public String getBeforeOrFutureDay(int num) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, num); + Date m = c.getTime(); + return format.format(m); + } + + @Override + public void deleteByCircleId(String circleId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Post::getCircleId), circleId); + List postList = list(queryWrapper); + List postIds = postList.stream() + .map(Post::getId).collect(Collectors.toList()); + pictureService.deleteByPostIds(postIds); + commentService.deleteByPostIds(postIds); + remove(queryWrapper); + } + + @Override + public void queryHotPostList(InputObject inputObject, OutputObject outputObject) { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + List popularPostList = popularPostService.queryTodayPopularPostList(); + List postIds = popularPostList.stream() + .map(PopularPost::getPostId).collect(Collectors.toList()); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(CommonConstants.ID, postIds); + List postList = list(queryWrapper); + //获取点赞信息 + Map checkUpvoteMap = upvoteService.checkUpvote(userId, postIds.toArray(new String[]{})); + checkUpvoteMap.forEach((key, value) -> { + postList.forEach(post -> { + if (key.equals(post.getId())) { + post.setCheckUpvote(value); + } + }); + }); + outputObject.setBeans(postList); + outputObject.settotal(popularPostList.size()); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/controller/UpvoteController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/controller/UpvoteController.java new file mode 100644 index 0000000..599fbb0 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/controller/UpvoteController.java @@ -0,0 +1,37 @@ +package com.skyeye.upvote.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.upvote.service.UpvoteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: UpvoteController + * @Description: 点赞信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/6 14:31. + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "点赞管理", tags = "点赞管理", modelName = "点赞管理") +public class UpvoteController { + + @Autowired + private UpvoteService upvoteService; + + @ApiOperation(id = "addOrCancelUpvote", value = "新增/删除点赞信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "objectId", name = "objectId", value = "第三方业务数据id", required = "required"), + @ApiImplicitParam(id = "objectKey", name = "objectKey", value = "第三方业务数据key", required = "required"),}) + @RequestMapping("/post/UpvoteController/addOrCancelUpvote") + public void addOrCancelUpvote(InputObject inputObject, OutputObject outputObject) { + upvoteService.addOrCancelUpvote(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/dao/UpvoteDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/dao/UpvoteDao.java new file mode 100644 index 0000000..b7f8361 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/dao/UpvoteDao.java @@ -0,0 +1,16 @@ +package com.skyeye.upvote.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.upvote.entity.Upvote; + +/** + * @ClassName: UpvoteDao + * @Description: 点赞信息数据层 + * @author: xqz + * @date: 2024/4/6 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UpvoteDao extends SkyeyeBaseMapper { + +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/entity/Upvote.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/entity/Upvote.java new file mode 100644 index 0000000..672fd05 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/entity/Upvote.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.upvote.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: Upvote + * @Description: 点赞实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/6 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@TableName(value = "wall_upvote") +@ApiModel(value = "点赞实体类") +public class Upvote extends CommonInfo { + + @TableField("user_id") + @Property(value = "点赞人id") + private String userId; + + @TableField("object_id") + @ApiModelProperty(value = "第三方业务数据id", required = "required") + private String objectId; + + @TableField("object_key") + @ApiModelProperty(value = "第三方业务数据key", required = "required") + private String objectKey; + + @TableField("create_time") + @ApiModelProperty(value = "创建时间") + private String createTime; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/UpvoteService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/UpvoteService.java new file mode 100644 index 0000000..e49f9c8 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/UpvoteService.java @@ -0,0 +1,33 @@ +package com.skyeye.upvote.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.upvote.entity.Upvote; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: UpvoteServiceImpl + * @Description: 点赞服务接口层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/6 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UpvoteService extends SkyeyeBusinessService { + + void addOrCancelUpvote(InputObject inputObject, OutputObject outputObject); + + /** + * 判断帖子/评论是否被指定用户点赞 + * + * @param userId 用户id + * @param objectIds 帖子/评论id + * @return + */ + Map checkUpvote(String userId, String... objectIds); + + List queryUpvoteList(String createId); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/impl/UpvoteServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/impl/UpvoteServiceImpl.java new file mode 100644 index 0000000..7dd7bd7 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/upvote/service/impl/UpvoteServiceImpl.java @@ -0,0 +1,149 @@ +package com.skyeye.upvote.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.comment.service.CommentService; +import com.skyeye.common.constans.CommonNumConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.post.service.PostService; +import com.skyeye.upvote.dao.UpvoteDao; +import com.skyeye.upvote.entity.Upvote; +import com.skyeye.upvote.service.UpvoteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: UpvoteServiceImpl + * @Description: 点赞服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/4/6 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "点赞管理", groupName = "点赞管理") +public class UpvoteServiceImpl extends SkyeyeBusinessServiceImpl implements UpvoteService { + + @Autowired + private UpvoteService upvoteService; + + @Autowired + private PostService postService; + + @Autowired + private CommentService commentService; + + public void addOrCancelUpvote(InputObject inputObject, OutputObject outputObject) { + Upvote upvote = inputObject.getParams(clazz); + String userId = InputObject.getLogParamsStatic().get("id").toString(); + upvote.setUserId(userId); + if (commentService.getServiceClassName().equals(upvote.getObjectKey())) { + if (estimateAddOrCancel(upvote)) { + addUpvoteComment(upvote); + } else { + updateUpvoteComment(upvote); + } + } else { + if (estimateAddOrCancel(upvote)) { + addUpvotePost(upvote); + } else { + updateUpvotePost(upvote); + } + } + outputObject.setBean(upvote); + outputObject.settotal(CommonNumConstants.NUM_ONE); + } + + public boolean estimateAddOrCancel(Upvote upvote) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getObjectId), upvote.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getUserId), upvote.getUserId()); + Upvote one = getOne(queryWrapper, false); + if (ObjectUtil.isEmpty(one)) { + return true; + } + return false; + } + + public void addUpvotePost(Upvote upvote) { + upvote.setCreateTime(DateUtil.getYmdTimeAndToString()); + upvoteService.createEntity(upvote, StrUtil.EMPTY); + postService.updateUpvoteCount(upvote.getObjectId(), String.valueOf(getUpvoteNum(upvote.getObjectId()))); + } + + public void updateUpvotePost(Upvote upvote) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getObjectId), upvote.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getUserId), upvote.getUserId()); + remove(queryWrapper); + postService.updateUpvoteCount(upvote.getObjectId(), String.valueOf(getUpvoteNum(upvote.getObjectId()))); + } + + public long getUpvoteNum(String id) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getObjectId), id); + return count(queryWrapper); + } + + public void addUpvoteComment(Upvote upvote) { + upvote.setCreateTime(DateUtil.getYmdTimeAndToString()); + upvoteService.createEntity(upvote, StrUtil.EMPTY); + commentService.updateCommentUpvoteNum(upvote.getObjectId(), String.valueOf(getUpvoteNum(upvote.getObjectId()))); + } + + public void updateUpvoteComment(Upvote upvote) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getObjectId), upvote.getObjectId()); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getUserId), upvote.getUserId()); + remove(queryWrapper); + commentService.updateCommentUpvoteNum(upvote.getObjectId(), String.valueOf(getUpvoteNum(upvote.getObjectId()))); + } + + @Override + public Map checkUpvote(String userId, String... objectIds) { + List objectIdList = Arrays.asList(objectIds).stream().distinct().collect(Collectors.toList()); + if (CollectionUtil.isEmpty(objectIdList)) { + return MapUtil.newHashMap(); + } + // 查询数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in(MybatisPlusUtil.toColumns(Upvote::getObjectId), objectIdList); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getUserId), userId); + List upvoteList = list(queryWrapper); + List inSqlObjectIds = upvoteList.stream().map(Upvote::getObjectId).collect(Collectors.toList()); + + // 构造结果数据,true代表已经点赞,false代表未点赞 + Map result = MapUtil.newHashMap(objectIdList.size()); + objectIdList.forEach(objectId -> { + if (inSqlObjectIds.contains(objectId)) { + result.put(objectId, true); + } else { + result.put(objectId, false); + } + }); + + return result; + } + + @Override + public List queryUpvoteList(String createId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getUserId), createId); + queryWrapper.eq(MybatisPlusUtil.toColumns(Upvote::getObjectKey), postService.getServiceClassName()); + queryWrapper.orderByDesc(MybatisPlusUtil.toColumns(Upvote::getCreateTime)); + return list(queryWrapper); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/controller/UserController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/controller/UserController.java new file mode 100644 index 0000000..8d7e41a --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/controller/UserController.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.user.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.user.entity.User; +import com.skyeye.user.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName: UserController + * @Description: 用户信息管理 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "用户管理", tags = "用户管理", modelName = "用户管理") +public class UserController { + + @Autowired + private UserService userService; + + /** + * 分页获取用户列表 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserList", value = "分页获取用户信息列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/UserController/queryUserList") + public void queryUserList(InputObject inputObject, OutputObject outputObject) { + userService.queryPageList(inputObject, outputObject); + } + + /** + * 根据id查询用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserById", value = "根据ID查询用户信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/UserController/queryUserById") + public void queryUserById(InputObject inputObject, OutputObject outputObject) { + userService.selectById(inputObject, outputObject); + } + + /** + * 根据ID批量查询用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryUserByIds", value = "根据ID批量查询用户信息", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "ids", name = "ids", value = "主键id", required = "required")}) + @RequestMapping("/post/UserController/queryUserByIds") + public void queryUserByIds(InputObject inputObject, OutputObject outputObject) { + userService.selectByIds(inputObject, outputObject); + } + + /** + * 更新用户信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "updateUserById", value = "编辑用户信息", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = User.class) + @RequestMapping("/post/UserController/updateUserById") + public void updateUserById(InputObject inputObject, OutputObject outputObject) { + userService.updateEntity(inputObject, outputObject); + } + + /** + * 用户登录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wallUserLogin", value = "用户登录", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "accountNumber", name = "accountNumber", value = "账号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required"), + @ApiImplicitParam(id = "cId", name = "cId", value = "cId,用于手机端消息通知")}) + @RequestMapping("/post/UserController/wallUserLogin") + public void wallUserLogin(InputObject inputObject, OutputObject outputObject) { + userService.wallUserLogin(inputObject, outputObject); + } + + /** + * 用户注册 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wallUserRegister", value = "用户注册", method = "POST", allUse = "0") + @ApiImplicitParams({ + @ApiImplicitParam(id = "name", name = "name", value = "姓名", required = "required"), + @ApiImplicitParam(id = "accountNumber", name = "accountNumber", value = "账号", required = "required"), + @ApiImplicitParam(id = "password", name = "password", value = "密码", required = "required")}) + @RequestMapping("/post/UserController/wallUserRegister") + public void wallUserRegister(InputObject inputObject, OutputObject outputObject) { + userService.wallUserRegister(inputObject, outputObject); + } + + /** + * 注销登录 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "wallUserExit", value = "注销登录", method = "POST", allUse = "2") + @RequestMapping("/post/UserController/wallUserExit") + public void wallUserExit(InputObject inputObject, OutputObject outputObject) { + userService.wallUserExit(inputObject, outputObject); + } + + /** + * 修改密码 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "editWallPassword", value = "修改密码", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "newPassword", name = "newPassword", value = "新密码", required = "required"), + @ApiImplicitParam(id = "oldPassword", name = "oldPassword", value = "旧密码", required = "required")}) + @RequestMapping("/post/UserController/editWallPassword") + public void editWallPassword(InputObject inputObject, OutputObject outputObject) { + userService.editWallPassword(inputObject, outputObject); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/dao/UserDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/dao/UserDao.java new file mode 100644 index 0000000..ff25d07 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/dao/UserDao.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.user.dao; + +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.user.entity.User; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: UserDao + * @Description: 用户信息数据层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UserDao extends SkyeyeBaseMapper { + List> queryUserList(CommonPageInfo commonPageInfo); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/entity/User.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/entity/User.java new file mode 100644 index 0000000..8dd68ea --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/entity/User.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.user.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.skyeye.annotation.api.ApiModel; +import com.skyeye.annotation.api.ApiModelProperty; +import com.skyeye.annotation.api.Property; +import com.skyeye.annotation.cache.RedisCacheField; +import com.skyeye.annotation.unique.UniqueField; +import com.skyeye.common.constans.CacheConstants; +import com.skyeye.common.entity.CommonInfo; +import lombok.Data; + +/** + * @ClassName: User + * @Description: 用户实体类 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Data +@UniqueField("accountNumber") +@RedisCacheField(name = CacheConstants.WALL_USER_CACHE_KEY) +@TableName(value = "wall_user") +@ApiModel(value = "表白墙实体类") +public class User extends CommonInfo { + + @TableId("id") + @ApiModelProperty("主键id。为空时新增,不为空时编辑") + private String id; + + @TableField("`name`") + @ApiModelProperty(value = "名字", required = "required") + private String name; + + @TableField("real_name") + @ApiModelProperty(value = "真实名字") + private String realName; + + @TableField("img") + @ApiModelProperty(value = "头像") + private String img; + + @TableField("sex") + @ApiModelProperty(value = "性别,參考#SexEnum") + private Integer sex; + + @TableField("student_number") + @ApiModelProperty(value = "学号") + private String studentNumber; + + @TableField("signature") + @ApiModelProperty(value = "签名") + private String signature; + + @TableField("background_image") + @ApiModelProperty(value = "背景图片") + private String backgroundImage; + + @TableField(value = "account_number", updateStrategy = FieldStrategy.NEVER) + @ApiModelProperty(value = "账号") + private String accountNumber; + + @TableField("password") + @ApiModelProperty(value = "密码") + private String password; + + @TableField("create_time") + @Property(value = "创建时间") + private String createTime; + + @TableField(exist = false) + @Property(value = "认证状态") + private Integer state; +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/UserService.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/UserService.java new file mode 100644 index 0000000..76f15ae --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/UserService.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.user.service; + +import com.skyeye.base.business.service.SkyeyeBusinessService; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.user.entity.User; + +import java.util.List; + +/** + * @ClassName: UserService + * @Description: 用户服务接口层 + * @author: xqz + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface UserService extends SkyeyeBusinessService { + + void wallUserLogin(InputObject inputObject, OutputObject outputObject); + + void wallUserRegister(InputObject inputObject, OutputObject outputObject); + + void wallUserExit(InputObject inputObject, OutputObject outputObject); + + void editWallPassword(InputObject inputObject, OutputObject outputObject); + + void updateBackgroundImage(String id, String image); + + void setCertification(String id, String studentNumber, String realName); +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/impl/UserServiceImpl.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..eb869b8 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/user/service/impl/UserServiceImpl.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.user.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.skyeye.annotation.service.SkyeyeService; +import com.skyeye.base.business.service.impl.SkyeyeBusinessServiceImpl; +import com.skyeye.certification.classenum.StateEnum; +import com.skyeye.certification.entity.Certification; +import com.skyeye.certification.service.CertificationService; +import com.skyeye.common.constans.CommonConstants; +import com.skyeye.common.constans.SysUserAuthConstants; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.enumeration.RequestType; +import com.skyeye.common.object.GetUserToken; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.common.object.PutObject; +import com.skyeye.common.util.DateUtil; +import com.skyeye.common.util.ToolUtil; +import com.skyeye.common.util.mybatisplus.MybatisPlusUtil; +import com.skyeye.exception.CustomException; +import com.skyeye.user.dao.UserDao; +import com.skyeye.user.entity.User; +import com.skyeye.user.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @ClassName: UserServiceImpl + * @Description: 用户服务层 + * @author: skyeye云系列--卫志强 + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@Service +@SkyeyeService(name = "用户管理", groupName = "用户管理") +public class UserServiceImpl extends SkyeyeBusinessServiceImpl implements UserService { + + @Autowired + private CertificationService certificationService; + + @Override + public List> queryPageDataList(InputObject inputObject) { + CommonPageInfo commonPageInfo = inputObject.getParams(CommonPageInfo.class); + List> beans = skyeyeBaseMapper.queryUserList(commonPageInfo); + return setCertification(beans); + } + + public List> setCertification(List> beans) { + List userIds = beans.stream() + .map(bean -> bean.get("id").toString()).collect(Collectors.toList()); + List CertificationList = certificationService.getCertificationListByIds(userIds); + beans.forEach(bean -> { + String userId = bean.get("id").toString(); + for (int i = 0; i < CertificationList.size(); i++) { + if (CertificationList.get(i).getUserId().equals(userId)) { + bean.put("state", CertificationList.get(i).getState()); + break; + } + bean.put("state", StateEnum.UNVERIFIED.getKey()); + } + }); + return beans; + } + + @Override + public void validatorEntity(User entity) { + super.validatorEntity(entity); + if (StrUtil.isEmpty(entity.getId())) { + if (StrUtil.isEmpty(entity.getAccountNumber())) { + throw new CustomException("账号不能为空。"); + } + if (StrUtil.isEmpty(entity.getPassword())) { + throw new CustomException("密码不能为空。"); + } + } else { + String userId = InputObject.getLogParamsStatic().get("id").toString(); + if (!userId.equals(entity.getId())) { + throw new CustomException("无权限,不可修改"); + } + } + } + + @Override + public void createPrepose(User entity) { + entity.setCreateTime(DateUtil.getTimeAndToString()); + } + + @Override + public void updatePrepose(User entity) { + User user = selectById(entity.getId()); + entity.setPassword(user.getPassword()); + entity.setRealName(user.getRealName()); + entity.setStudentNumber(user.getStudentNumber()); + } + + @Override + public User selectById(String id) { + User user = super.selectById(id); + Certification certification = certificationService.selectById(id); + if (certification == null) { + user.setState(StateEnum.UNVERIFIED.getKey()); + return user; + } else { + user.setState(certification.getState()); + } + user.setPassword(StrUtil.EMPTY); + return user; + } + + @Override + public List selectByIds(String... ids) { + List userList = super.selectByIds(ids); + userList.forEach(user -> { + user.setPassword(StrUtil.EMPTY); + }); + return userList; + } + + @Override + public void wallUserLogin(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String accountNumber = map.get("accountNumber").toString(); + String password = ToolUtil.MD5(map.get("password").toString()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(User::getAccountNumber), accountNumber); + User user = getOne(queryWrapper); + if (ObjectUtil.isEmpty(user)) { + outputObject.setreturnMessage("请确保账号输入无误!"); + } else { + if (password.equals(user.getPassword())) { + Map userMation = BeanUtil.beanToMap(user); + String requestType = InputObject.getRequest().getHeader("requestType"); + // 学生这里以学生id作为userToken,确保不会和后台登录用户的id重复 + String userToken; + if (RequestType.APP.getKey().equals(requestType)) { + SysUserAuthConstants.setUserLoginRedisCache(user.getId() + SysUserAuthConstants.APP_IDENTIFYING, userMation); + userToken = GetUserToken.createNewToken(user.getId() + SysUserAuthConstants.APP_IDENTIFYING, user.getPassword()); + } else { + SysUserAuthConstants.setUserLoginRedisCache(user.getId(), userMation); + userToken = GetUserToken.createNewToken(user.getId(), user.getPassword()); + } + userMation.put("userToken", userToken); + userMation.put("password", null); + outputObject.setBean(userMation); + } else { + outputObject.setreturnMessage("密码输入错误!"); + } + } + } + + @Override + public void wallUserRegister(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + String name = map.get("name").toString(); + String accountNumber = map.get("accountNumber").toString(); + String password = ToolUtil.MD5(map.get("password").toString()); + // 验证账号是否存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(MybatisPlusUtil.toColumns(User::getAccountNumber), accountNumber); + User temp = getOne(queryWrapper); + if (ObjectUtil.isNotEmpty(temp)) { + throw new CustomException("该账号已存在!"); + } + User user = new User(); + user.setName(name); + user.setAccountNumber(accountNumber); + user.setPassword(password); + createEntity(user, StrUtil.EMPTY); + } + + @Override + public void wallUserExit(InputObject inputObject, OutputObject outputObject) { + String userId = GetUserToken.getUserTokenUserId(PutObject.getRequest()); + SysUserAuthConstants.delUserLoginRedisCache(userId); + } + + @Override + public void editWallPassword(InputObject inputObject, OutputObject outputObject) { + Map map = inputObject.getParams(); + // 获取当前用户信息 + String stuId = inputObject.getLogParams().get("id").toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CommonConstants.ID, stuId); + User user = getOne(queryWrapper); + // 旧密码匹配 + if (user.getPassword().equals(ToolUtil.MD5(map.get("oldPassword").toString()))) { + String newPassword = ToolUtil.MD5(map.get("newPassword").toString()); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, stuId); + updateWrapper.set(MybatisPlusUtil.toColumns(User::getPassword), newPassword); + update(updateWrapper); + if (update(updateWrapper)) { + String userId = GetUserToken.getUserTokenUserId(PutObject.getRequest()); + SysUserAuthConstants.delUserLoginRedisCache(userId); + } + } else { + outputObject.setreturnMessage("旧密码输入错误."); + } + } + + @Override + public void updateBackgroundImage(String id, String image) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(User::getBackgroundImage), image); + update(updateWrapper); + refreshCache(id); + } + + @Override + public void setCertification(String id, String studentNumber, String realName) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq(CommonConstants.ID, id); + updateWrapper.set(MybatisPlusUtil.toColumns(User::getStudentNumber), studentNumber); + updateWrapper.set(MybatisPlusUtil.toColumns(User::getRealName), realName); + update(updateWrapper); + refreshCache(id); + } +} \ No newline at end of file diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/controller/VideoController.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/controller/VideoController.java new file mode 100644 index 0000000..41ece64 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/controller/VideoController.java @@ -0,0 +1,171 @@ +package com.skyeye.video.controller; + +import com.skyeye.annotation.api.Api; +import com.skyeye.annotation.api.ApiImplicitParam; +import com.skyeye.annotation.api.ApiImplicitParams; +import com.skyeye.annotation.api.ApiOperation; +import com.skyeye.common.entity.search.CommonPageInfo; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; +import com.skyeye.video.entity.Video; +import com.skyeye.video.service.VideoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * @ClassName: VideoController + * @Description: 视频管理 + * @author: skyeye云系列--lqy + * @date: 2024/3/9 14:31 + * @Copyright: 2024 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +@RestController +@Api(value = "视频管理", tags = "视频管理", modelName = "视频管理") +public class VideoController { + + @Autowired + private VideoService videoService; + + /** + * 新增视频 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "writeVideo", value = "新增视频", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = Video.class) + @RequestMapping("/post/VideoController/writeVideo") + public void writeVideo(InputObject inputObject, OutputObject outputObject) { + videoService.createEntity(inputObject, outputObject); + } + + /** + * 根据id查询视频信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryVideoById", value = "根据id查询视频信息", method = "GET", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VideoController/queryVideoById") + public void queryVideoById(InputObject inputObject, OutputObject outputObject) { + videoService.selectById(inputObject, outputObject); + } + + /** + * 根据id删除视频信息 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "deleteVideoById", value = "根据id删除视频信息", method = "DELETE", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "id", name = "id", value = "主键id", required = "required")}) + @RequestMapping("/post/VideoController/deleteVideoById") + public void deleteVideoById(InputObject inputObject, OutputObject outputObject) { + videoService.deleteById(inputObject, outputObject); + } + + /** + * 分页获取我的视频列表 + * + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyVideoList", value = "分页获取我的视频列表", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VideoController/queryMyVideoList") + public void queryMyVideoList(InputObject inputObject, OutputObject outputObject) { + videoService.queryMyVideoList(inputObject, outputObject); + } + + + /** + * 点赞或取消点赞 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "supportOrNotVideo", value = "点赞或取消点赞", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "videoId", name = "videoId", value = "视频id", required = "required") + }) + @RequestMapping("/post/VideoController/supportOrNotVideo") + public void supportOrNotVideo(InputObject inputObject, OutputObject outputObject) { + videoService.supportOrNotVideo(inputObject, outputObject); + } + + /** + * 收藏或取消收藏 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "collectOrNotVideo", value = "收藏或取消收藏", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "videoId", name = "videoId", value = "视频id", required = "required") + }) + @RequestMapping("/post/VideoController/collectOrNotVideo") + public void collectOrNotVideo(InputObject inputObject, OutputObject outputObject) { + videoService.collectOrNotVideo(inputObject, outputObject); + } + + /** + * 分页获取我点赞的视频 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMySupportVideo", value = "分页获取我点赞的视频", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VideoController/queryMySupportVideo") + public void queryMySupportVideo(InputObject inputObject, OutputObject outputObject) { + videoService.queryMySupportVideo(inputObject, outputObject); + } + + /** + * 分页获取我收藏的视频 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryMyCollectVideo", value = "分页获取我收藏的视频", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VideoController/queryMyCollectVideo") + public void queryMyCollectVideo(InputObject inputObject, OutputObject outputObject) { + videoService.queryMyCollectVideo(inputObject, outputObject); + } + + /** + * 刷新浏览量 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "refreshVisitVideo", value = "刷新浏览量", method = "POST", allUse = "2") + @ApiImplicitParams({ + @ApiImplicitParam(id = "videoId", name = "videoId", value = "视频id", required = "required") + }) + @RequestMapping("/post/VideoController/refreshVisitVideo") + public void refreshVisitVideo(InputObject inputObject, OutputObject outputObject) { + videoService.refreshVisitVideo(inputObject, outputObject); + } + + /** + * 分页获取全部视频 + * + * @param inputObject 入参以及用户信息等获取对象 + * @param outputObject 出参以及提示信息的返回值对象 + */ + @ApiOperation(id = "queryAllVideoList", value = "分页获取全部视频,更具点赞数量倒序排序", method = "POST", allUse = "2") + @ApiImplicitParams(classBean = CommonPageInfo.class) + @RequestMapping("/post/VideoController/queryAllVideoList") + public void queryAllVideoList(InputObject inputObject, OutputObject outputObject) { + videoService.queryAllVideoList(inputObject, outputObject); + } +} diff --git a/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/dao/VideoDao.java b/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/dao/VideoDao.java new file mode 100644 index 0000000..ef7e069 --- /dev/null +++ b/skyeye-wall/wall-pro/src/main/java/com/skyeye/video/dao/VideoDao.java @@ -0,0 +1,16 @@ +package com.skyeye.video.dao; + +import com.skyeye.eve.dao.SkyeyeBaseMapper; +import com.skyeye.video.entity.Video; + + +/** + * @ClassName: VideoDao + * @Description: 视频管理数据层 + * @author: lqy + * @date: 2024/3/9 14:31 + * @Copyright: 2023 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public interface VideoDao extends SkyeyeBaseMapper

+ +

XXL-JOB

+

+ XXL-JOB, a distributed task scheduling framework. +
+
-- Home Page -- +
+
+ + + + + + + + + + + + + + + + + + + + + +

+

+ + +## Introduction +XXL-JOB is a distributed task scheduling framework. +It's core design goal is to develop quickly and learn simple, lightweight, and easy to expand. +Now, it's already open source, and many companies use it in production environments, real "out-of-the-box". + +XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 + + +## Documentation +- [中文文档](https://www.xuxueli.com/xxl-job/) +- [English Documentation](https://www.xuxueli.com/xxl-job/en/) + + +## Communication +- [社区交流](https://www.xuxueli.com/page/community.html) + + +## Features +- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手; +- 2、动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效; +- 3、调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA; +- 4、执行器HA(分布式):任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA; +- 5、注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址; +- 6、弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务; +- 7、触发策略:提供丰富的任务触发策略,包括:Cron触发、固定间隔触发、固定延时触发、API(事件)触发、人工触发、父子任务触发; +- 8、调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等; +- 9、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度; +- 10、任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务; +- 11、任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试; +- 12、任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式; +- 13、路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等; +- 14、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务; +- 15、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。 +- 16、故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。 +- 17、任务进度监控:支持实时监控任务进度; +- 18、Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志; +- 19、GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。支持30个版本的历史版本回溯。 +- 20、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS、PHP、PowerShell等类型脚本; +- 21、命令行任务:原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可; +- 22、任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔; +- 23、一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行; +- 24、自定义任务参数:支持在线配置调度任务入参,即时生效; +- 25、调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞; +- 26、数据加密:调度中心和执行器之间的通讯进行数据加密,提升调度信息安全性; +- 27、邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件; +- 28、推送maven中央仓库: 将会把最新稳定版推送到maven中央仓库, 方便用户接入和使用; +- 29、运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等; +- 30、全异步:任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行; +- 31、跨语言:调度中心与执行器提供语言无关的 RESTful API 服务,第三方任意语言可据此对接调度中心或者实现执行器。除此之外,还提供了 “多任务模式”和“httpJobHandler”等其他跨语言方案; +- 32、国际化:调度中心支持国际化设置,提供中文、英文两种可选语言,默认为中文; +- 33、容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用; +- 34、线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性; +- 35、用户管理:支持在线管理系统用户,存在管理员、普通用户两种角色; +- 36、权限控制:执行器维度进行权限控制,管理员拥有全量权限,普通用户需要分配执行器权限后才允许相关操作; + + +## Development +于2015年中,我在github上创建XXL-JOB项目仓库并提交第一个commit,随之进行系统结构设计,UI选型,交互设计…… + +于2015-11月,XXL-JOB终于RELEASE了第一个大版本V1.0, 随后我将之发布到OSCHINA,XXL-JOB在OSCHINA上获得了@红薯的热门推荐,同期分别达到了OSCHINA的“热门动弹”排行第一和git.oschina的开源软件月热度排行第一,在此特别感谢红薯,感谢大家的关注和支持。 + +于2015-12月,我将XXL-JOB发表到我司内部知识库,并且得到内部同事认可。 + +于2016-01月,我司展开XXL-JOB的内部接入和定制工作,在此感谢袁某和尹某两位同事的贡献,同时也感谢内部其他给与关注与支持的同事。 + +于2017-05-13,在上海举办的 "[第62期开源中国源创会](https://www.oschina.net/event/2236961)" 的 "放码过来" 环节,我登台对XXL-JOB做了演讲,台下五百位在场观众反响热烈([图文回顾](https://www.oschina.net/question/2686220_2242120) )。 + +于2017-10-22,又拍云 Open Talk 联合 Spring Cloud 中国社区举办的 "[进击的微服务实战派上海站](https://opentalk.upyun.com/303.html)",我登台对XXL-JOB做了演讲,现场观众反响热烈并在会后与XXL-JOB用户热烈讨论交流。 + +于2017-12-11,XXL-JOB有幸参会《[InfoQ ArchSummit全球架构师峰会](http://bj2017.archsummit.com/)》,并被拍拍贷架构总监"杨波老师"在专题 "[微服务原理、基础架构和开源实践](http://bj2017.archsummit.com/training/2)" 中现场介绍。 + +于2017-12-18,XXL-JOB参与"[2017年度最受欢迎中国开源软件](http://www.oschina.net/project/top_cn_2017?sort=1)"评比,在当时已录入的约九千个国产开源项目中角逐,最终进入了前30强。 + +于2018-01-15,XXL-JOB参与"[2017码云最火开源项目](https://www.oschina.net/news/92438/2017-mayun-top-50)"评比,在当时已录入的约六千五百个码云项目中角逐,最终进去了前20强。 + +于2018-04-14,iTechPlus在上海举办的 "[2018互联网开发者大会](http://www.itdks.com/eventlist/detail/2065)",我登台对XXL-JOB做了演讲,现场观众反响热烈并在会后与XXL-JOB用户热烈讨论交流。 + +于2018-05-27,在上海举办的 "[第75期开源中国源创会](https://www.oschina.net/event/2278742)" 的 "架构" 主题专场,我登台进行“基础架构与中间件图谱”主题演讲,台下上千位在场观众反响热烈([图文回顾](https://www.oschina.net/question/3802184_2280606) )。 + +于2018-12-05,XXL-JOB参与"[2018年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2018?sort=1)"评比,在当时已录入的一万多个开源项目中角逐,最终排名第19名。 + +于2019-12-10,XXL-JOB参与"[2019年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2019)"评比,在当时已录入的一万多个开源项目中角逐,最终排名"开发框架和基础组件类"第9名。 + +于2020-11-16,XXL-JOB参与"[2020年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2020)"评比,在当时已录入的一万多个开源项目中角逐,最终排名"开发框架和基础组件类"第8名。 + +> 我司大众点评目前已接入XXL-JOB,内部别名《Ferrari》(Ferrari基于XXL-JOB的V1.1版本定制而成,新接入应用推荐升级最新版本)。 +据最新统计, 自2016-01-21接入至2017-12-01期间,该系统已调度约100万次,表现优异。新接入应用推荐使用最新版本,因为经过数十个版本的更新,系统的任务模型、UI交互模型以及底层调度通讯模型都有了较大的优化和提升,核心功能更加稳定高效。 + +至今,XXL-JOB已接入多家公司的线上产品线,接入场景如电商业务,O2O业务和大数据作业等,截止最新统计时间为止,XXL-JOB已接入的公司包括不限于: + + - 1、大众点评【美团点评】 + - 2、山东学而网络科技有限公司; + - 3、安徽慧通互联科技有限公司; + - 4、人人聚财金服; + - 5、上海棠棣信息科技股份有限公司 + - 6、运满满【运满满】 + - 7、米其林 (中国区)【米其林】 + - 8、妈妈联盟 + - 9、九樱天下(北京)信息技术有限公司 + - 10、万普拉斯科技有限公司【一加手机】 + - 11、上海亿保健康管理有限公司 + - 12、海尔馨厨【海尔】 + - 13、河南大红包电子商务有限公司 + - 14、成都顺点科技有限公司 + - 15、深圳市怡亚通 + - 16、深圳麦亚信科技股份有限公司 + - 17、上海博莹科技信息技术有限公司 + - 18、中国平安科技有限公司【中国平安】 + - 19、杭州知时信息科技有限公司 + - 20、博莹科技(上海)有限公司 + - 21、成都依能股份有限责任公司 + - 22、湖南高阳通联信息技术有限公司 + - 23、深圳市邦德文化发展有限公司 + - 24、福建阿思可网络教育有限公司 + - 25、优信二手车【优信】 + - 26、上海悠游堂投资发展股份有限公司【悠游堂】 + - 27、北京粉笔蓝天科技有限公司 + - 28、中秀科技(无锡)有限公司 + - 29、武汉空心科技有限公司 + - 30、北京蚂蚁风暴科技有限公司 + - 31、四川互宜达科技有限公司 + - 32、钱包行云(北京)科技有限公司 + - 33、重庆欣才集团 + - 34、咪咕互动娱乐有限公司【中国移动】 + - 35、北京诺亦腾科技有限公司 + - 36、增长引擎(北京)信息技术有限公司 + - 37、北京英贝思科技有限公司 + - 38、刚泰集团 + - 39、深圳泰久信息系统股份有限公司 + - 40、随行付支付有限公司 + - 41、广州瀚农网络科技有限公司 + - 42、享点科技有限公司 + - 43、杭州比智科技有限公司 + - 44、圳临界线网络科技有限公司 + - 45、广州知识圈网络科技有限公司 + - 46、国誉商业上海有限公司 + - 47、海尔消费金融有限公司,嗨付、够花【海尔】 + - 48、广州巴图鲁信息科技有限公司 + - 49、深圳市鹏海运电子数据交换有限公司 + - 50、深圳市亚飞电子商务有限公司 + - 51、上海趣医网络有限公司 + - 52、聚金资本 + - 53、北京父母邦网络科技有限公司 + - 54、中山元赫软件科技有限公司 + - 55、中商惠民(北京)电子商务有限公司 + - 56、凯京集团 + - 57、华夏票联(北京)科技有限公司 + - 58、拍拍贷【拍拍贷】 + - 59、北京尚德机构在线教育有限公司 + - 60、任子行股份有限公司 + - 61、北京时态电子商务有限公司 + - 62、深圳卷皮网络科技有限公司 + - 63、北京安博通科技股份有限公司 + - 64、未来无线网 + - 65、厦门瓷禧网络有限公司 + - 66、北京递蓝科软件股份有限公司 + - 67、郑州创海软件科技公司 + - 68、北京国槐信息科技有限公司 + - 69、浪潮软件集团 + - 70、多立恒(北京)信息技术有限公司 + - 71、广州极迅客信息科技有限公司 + - 72、赫基(中国)集团股份有限公司 + - 73、海投汇 + - 74、上海润益创业孵化器管理股份有限公司 + - 75、汉纳森(厦门)数据股份有限公司 + - 76、安信信托 + - 77、岚儒财富 + - 78、捷道软件 + - 79、湖北享七网络科技有限公司 + - 80、湖南创发科技责任有限公司 + - 81、深圳小安时代互联网金融服务有限公司 + - 82、湖北享七网络科技有限公司 + - 83、钱包行云(北京)科技有限公司 + - 84、360金融【360】 + - 85、易企秀 + - 86、摩贝(上海)生物科技有限公司 + - 87、广东芯智慧科技有限公司 + - 88、联想集团【联想】 + - 89、怪兽充电 + - 90、行圆汽车 + - 91、深圳店店通科技邮箱公司 + - 92、京东【京东】 + - 93、米庄理财 + - 94、咖啡易融 + - 95、梧桐诚选 + - 96、恒大地产【恒大】 + - 97、昆明龙慧 + - 98、上海涩瑶软件 + - 99、易信【网易】 + - 100、铜板街 + - 101、杭州云若网络科技有限公司 + - 102、特百惠(中国)有限公司 + - 103、常山众卡运力供应链管理有限公司 + - 104、深圳立创电子商务有限公司 + - 105、杭州智诺科技股份有限公司 + - 106、北京云漾信息科技有限公司 + - 107、深圳市多银科技有限公司 + - 108、亲宝宝 + - 109、上海博卡软件科技有限公司 + - 110、智慧树在线教育平台 + - 111、米族金融 + - 112、北京辰森世纪 + - 113、云南滇医通 + - 114、广州市分领网络科技有限责任公司 + - 115、浙江微能科技有限公司 + - 116、上海馨飞电子商务有限公司 + - 117、上海宝尊电子商务有限公司 + - 118、直客通科技技术有限公司 + - 119、科度科技有限公司 + - 120、上海数慧系统技术有限公司 + - 121、我的医药网 + - 122、多粉平台 + - 123、铁甲二手机 + - 124、上海海新得数据技术有限公司 + - 125、深圳市珍爱网信息技术有限公司【珍爱网】 + - 126、小蜜蜂 + - 127、吉荣数科技 + - 128、上海恺域信息科技有限公司 + - 129、广州荔支网络有限公司【荔枝FM】 + - 130、杭州闪宝科技有限公司 + - 131、北京互联新网科技发展有限公司 + - 132、誉道科技 + - 133、山西兆盛房地产开发有限公司 + - 134、北京蓝睿通达科技有限公司 + - 135、月亮小屋(中国)有限公司【蓝月亮】 + - 136、青岛国瑞信息技术有限公司 + - 137、博雅云计算(北京)有限公司 + - 138、华泰证券香港子公司 + - 139、杭州东方通信软件技术有限公司 + - 140、武汉博晟安全技术股份有限公司 + - 141、深圳市六度人和科技有限公司 + - 142、杭州趣维科技有限公司(小影) + - 143、宁波单车侠之家科技有限公司【单车侠】 + - 144、丁丁云康信息科技(北京)有限公司 + - 145、云钱袋 + - 146、南京中兴力维 + - 147、上海矽昌通信技术有限公司 + - 148、深圳萨科科技 + - 149、中通服创立科技有限责任公司 + - 150、深圳市对庄科技有限公司 + - 151、上证所信息网络有限公司 + - 152、杭州火烧云科技有限公司【婚礼纪】 + - 153、天津青芒果科技有限公司【芒果头条】 + - 154、长飞光纤光缆股份有限公司 + - 155、世纪凯歌(北京)医疗科技有限公司 + - 156、浙江霖梓控股有限公司 + - 157、江西腾飞网络技术有限公司 + - 158、安迅物流有限公司 + - 159、肉联网 + - 160、北京北广梯影广告传媒有限公司 + - 161、上海数慧系统技术有限公司 + - 162、大志天成 + - 163、上海云鹊医 + - 164、上海云鹊医 + - 165、墨迹天气【墨迹天气】 + - 166、上海逸橙信息科技有限公司 + - 167、沅朋物联 + - 168、杭州恒生云融网络科技有限公司 + - 169、绿米联创 + - 170、重庆易宠科技有限公司 + - 171、安徽引航科技有限公司(乐职网) + - 172、上海数联医信企业发展有限公司 + - 173、良彬建材 + - 174、杭州求是同创网络科技有限公司 + - 175、荷马国际 + - 176、点雇网 + - 177、深圳市华星光电技术有限公司 + - 178、厦门神州鹰软件科技有限公司 + - 179、深圳市招商信诺人寿保险有限公司 + - 180、上海好屋网信息技术有限公司 + - 181、海信集团【海信】 + - 182、信凌可信息科技(上海)有限公司 + - 183、长春天成科技发展有限公司 + - 184、用友金融信息技术股份有限公司【用友】 + - 185、北京咖啡易融有限公司 + - 186、国投瑞银基金管理有限公司 + - 187、晋松(上海)网络信息技术有限公司 + - 188、深圳市随手科技有限公司【随手记】 + - 189、深圳水务科技有限公司 + - 190、易企秀【易企秀】 + - 191、北京磁云科技 + - 192、南京蜂泰互联网科技有限公司 + - 193、章鱼直播 + - 194、奖多多科技 + - 195、天津市神州商龙科技股份有限公司 + - 196、岩心科技 + - 197、车码科技(北京)有限公司 + - 198、贵阳市投资控股集团 + - 199、康旗股份 + - 200、龙腾出行 + - 201、杭州华量软件 + - 202、合肥顶岭医疗科技有限公司 + - 203、重庆表达式科技有限公司 + - 204、上海米道信息科技有限公司 + - 205、北京益友会科技有限公司 + - 206、北京融贯电子商务有限公司 + - 207、中国外汇交易中心 + - 208、中国外运股份有限公司 + - 209、中国上海晓圈教育科技有限公司 + - 210、普联软件股份有限公司 + - 211、北京科蓝软件股份有限公司 + - 212、江苏斯诺物联科技有限公司 + - 213、北京搜狐-狐友【搜狐】 + - 214、新大陆网商金融 + - 215、山东神码中税信息科技有限公司 + - 216、河南汇顺网络科技有限公司 + - 217、北京华夏思源科技发展有限公司 + - 218、上海东普信息科技有限公司 + - 219、上海鸣勃网络科技有限公司 + - 220、广东学苑教育发展有限公司 + - 221、深圳强时科技有限公司 + - 222、上海云砺信息科技有限公司 + - 223、重庆愉客行网络有限公司 + - 224、数云 + - 225、国家电网运检部 + - 226、杭州找趣 + - 227、浩鲸云计算科技股份有限公司 + - 228、科大讯飞【科大讯飞】 + - 229、杭州行装网络科技有限公司 + - 230、即有分期金融 + - 231、深圳法司德信息科技有限公司 + - 232、上海博复信息科技有限公司 + - 233、杭州云嘉云计算有限公司 + - 234、有家民宿(有家美宿) + - 235、北京赢销通软件技术有限公司 + - 236、浙江聚有财金融服务外包有限公司 + - 237、易族智汇(北京)科技有限公司 + - 238、合肥顶岭医疗科技开发有限公司 + - 239、车船宝(深圳)旭珩科技有限公司) + - 240、广州富力地产有限公司 + - 241、氢课(上海)教育科技有限公司 + - 242、武汉氪细胞网络技术有限公司 + - 243、杭州有云科技有限公司 + - 244、上海仙豆智能机器人有限公司 + - 245、拉卡拉支付股份有限公司【拉卡拉】 + - 246、虎彩印艺股份有限公司 + - 247、北京数微科技有限公司 + - 248、广东智瑞科技有限公司 + - 249、找钢网 + - 250、九机网 + - 251、杭州跑跑网络科技有限公司 + - 252、深圳未来云集 + - 253、杭州每日给力科技有限公司 + - 254、上海齐犇信息科技有限公司 + - 255、滴滴出行【滴滴】 + - 256、合肥云诊信息科技有限公司 + - 257、云知声智能科技股份有限公司 + - 258、南京坦道科技有限公司 + - 259、爱乐优(二手平台) + - 260、猫眼电影(私有化部署)【猫眼电影】 + - 261、美团大象(私有化部署)【美团大象】 + - 262、作业帮教育科技(北京)有限公司【作业帮】 + - 263、北京小年糕互联网技术有限公司 + - 264、山东矩阵软件工程股份有限公司 + - 265、陕西国驿软件科技有限公司 + - 266、君开信息科技 + - 267、村鸟网络科技有限责任公司 + - 268、云南国际信托有限公司 + - 269、金智教育 + - 270、珠海市筑巢科技有限公司 + - 271、上海百胜软件股份有限公司 + - 272、深圳市科盾科技有限公司 + - 273、哈啰出行【哈啰】 + - 274、途虎养车【途虎】 + - 275、卡思优派人力资源集团 + - 276、南京观为智慧软件科技有限公司 + - 277、杭州城市大脑科技有限公司 + - 278、猿辅导【猿辅导】 + - 279、洛阳健创网络科技有限公司 + - 280、魔力耳朵 + - 281、亿阳信通 + - 282、上海招鲤科技有限公司 + - 283、四川商旅无忧科技服务有限公司 + - 284、UU跑腿 + - 285、北京老虎证券【老虎证券】 + - 286、悠活省吧(北京)网络科技有限公司 + - 287、F5未来商店 + - 288、深圳环阳通信息技术有限公司 + - 289、遠傳電信 + - 290、作业帮(北京)教育科技有限公司【作业帮】 + - 291、成都科鸿智信科技有限公司 + - 292、北京木屋时代科技有限公司 + - 293、大学通(哈尔滨)科技有限责任公司 + - 294、浙江华坤道威数据科技有限公司 + - 295、吉祥航空【吉祥航空】 + - 296、南京圆周网络科技有限公司 + - 297、广州市洋葱omall电子商务 + - 298、天津联物科技有限公司 + - 299、跑哪儿科技(北京)有限公司 + - 300、深圳市美西西餐饮有限公司(喜茶) + - 301、平安不动产有限公司【平安】 + - 302、江苏中海昇物联科技有限公司 + - 303、湖南牙医帮科技有限公司 + - 304、重庆民航凯亚信息技术有限公司(易通航) + - 305、递易(上海)智能科技有限公司 + - 306、亚朵 + - 307、浙江新课堂教育股份有限公司 + - 308、北京蜂创科技有限公司 + - 309、德一智慧城市信息系统有限公司 + - 310、北京翼点科技有限公司 + - 311、湖南智数新维度信息科技有限公司 + - 312、北京玖扬博文文化发展有限公司 + - 313、上海宇珩信息科技有限公司 + - 314、全景智联(武汉)科技有限公司 + - 315、天津易客满国际物流有限公司 + - 316、南京爱福路汽车科技有限公司 + - 317、我房旅居集团 + - 318、湛江亲邻科技有限公司 + - 319、深圳市姜科网络有限公司 + - 320、青岛日日顺物流有限公司 + - 321、南京太川信息技术有限公司 + - 322、美图之家科技优先公司【美图】 + - 323、南京太川信息技术有限公司 + - 324、众薪科技(北京)有限公司 + - 325、武汉安安物联科技有限公司 + - 326、北京智客朗道网络科技有限公司 + - 327、深圳市超级猩猩健身管理管理有限公司 + - 328、重庆达志科技有限公司 + - 329、上海享评信息科技有限公司 + - 330、薪得付信息科技 + - 331、跟谁学 + - 332、中道(苏州)旅游网络科技有限公司 + - 333、广州小卫科技有限公司 + - 334、上海非码网络科技有限公司 + - 335、途家网网络技术(北京)有限公司【途家】 + - 336、广州辉凡信息科技有限公司 + - 337、天维尔信息科技股份有限公司 + - 338、上海极豆科技有限公司 + - 339、苏州触达信息技术有限公司 + - 340、北京热云科技有限公司 + - 341、中智企服(北京)科技有限公司 + - 342、易联云计算(杭州)有限责任公司 + - 343、青岛航空股份有限公司【青岛航空】 + - 344、山西博睿通科技有限公司 + - 345、网易杭州网络有限公司【网易】 + - 346、北京果果乐学科技有限公司 + - 347、百望股份有限公司 + - 348、中保金服(深圳)科技有限公司 + - 349、天津运友物流科技股份有限公司 + - 350、广东创能科技股份有限公司 + - 351、上海倚博信息科技有限公司 + - 352、深圳百果园实业(集团)股份有限公司 + - 353、广州细刻网络科技有限公司 + - 354、武汉鸿业众创科技有限公司 + - 355、金锡科技(广州)有限公司 + - 356、易瑞国际电子商务有限公司 + - 357、奇点云 + - 358、中视信息科技有限公司 + - 359、开源项目:datax-web + - 360、云知声智能科技股份有限公司 + - 361、开源项目:bboss + - 362、成都深驾科技有限公司 + - 363、FunPlus【趣加】 + - 364、杭州创匠信科技有限公司 + - 365、龙匠(北京)科技发展有限公司 + - 366、广州一链通互联网科技有限公司 + - 367、上海星艾网络科技有限公司 + - 368、虎博网络技术(上海)有限公司 + - 369、青岛优米信息技术有限公司 + - 370、八维通科技有限公司 + - 371、烟台合享智星数据科技有限公司 + - 372、东吴证券股份有限公司 + - 373、中通云仓股份有限公司【中通】 + - 374、北京加菲猫科技有限公司 + - 375、北京匠心演绎科技有限公司 + - 376、宝贝走天下 + - 377、厦门众库科技有限公司 + - 378、海通证券数据中心 + - 389、湖南快乐通宝小额贷款有限公司 + - 380、浙江大华技术股份有限公司 + - 381、杭州魔筷科技有限公司 + - 382、青岛掌讯通区块链科技有限公司 + - 383、新大陆金融科技 + - 384、常州玺拓软件科技有限公司 + - 385、北京正保网格教育科技有限公司 + - 386、统一企业(中国)投资有限公司【统一】 + - 387、微革网络科技有限公司 + - 388、杭州融易算科技有限公司 + - 399、青岛上啥班网络科技有限公司 + - 390、京东酒世界 + - 391、杭州爱博仕科技有限公司 + - 392、五星金服控股有限公司 + - 393、福建乐摩物联科技有限公司 + - 394、百炼智能科技有限公司 + - 395、山东能源数智云科技有限公司 + - 396、招商局能源运输股份有限公司 + - 397、三一集团【三一】 + - 398、东巴文(深圳)健康管理有限公司 + - 399、索易软件 + - 400、深圳市宁远科技有限公司 + - 401、熙牛医疗 + - 402、南京智鹤电子科技有限公司 + - 403、嘀嗒出行【嘀嗒出行】 + - 404、广州虎牙信息科技有限公司【虎牙】 + - 405、广州欧莱雅百库网络科技有限公司【欧莱雅】 + - 406、微微科技有限公司 + - 407、我爱我家房地产经纪有限公司【我爱我家】 + - 408、九号发现 + - 409、薪人薪事 + - 410、武汉氪细胞网络技术有限公司 + - 411、广州市斯凯奇商业有限公司 + - 412、微淼商学院 + - 413、杭州车盛科技有限公司 + - 414、深兰科技(上海)有限公司 + - 415、安徽中科美络信息技术有限公司 + - 416、比亚迪汽车工业有限公司【比亚迪】 + - 417、湖南小桔信息技术有限公司 + - 418、安徽科大国创软件科技有限公司 + - 419、克而瑞 + - 420、陕西云基华海信息技术有限公司 + - 421、安徽深宁科技有限公司 + - 422、广东康爱多数字健康有限公司 + - 423、嘉里电子商务 + - 424、上海时代光华教育发展有限公司 + - 425、CityDo + - 426、上海禹知信息科技有限公司 + - 427、广东智瑞科技有限公司 + - 428、西安爱铭网络科技有限公司 + - 429、心医国际数字医疗系统(大连)有限公司 + - 430、乐其电商 + - 431、锐达科技 + - 432、天津长城滨银汽车金融有限公司 + - 433、代码网 + - 434、东莞市东城乔伦软件开发工作室 + - 435、浙江百应科技有限公司 + - 436、上海力爱帝信息技术有限公司(Red E) + - 437、云徙科技有限公司 + - 438、北京康智乐思网络科技有限公司【大姨吗APP】 + - 439、安徽开元瞬视科技有限公司 + - 440、立方 + - 441、厦门纵行科技 + - 442、乐山-菲尼克斯半导体有限公司 + - 443、武汉光谷联合集团有限公司 + - 444、上海金仕达软件科技有限公司 + - 445、深圳易世通达科技有限公司 + - 446、爱动超越人工智能科技(北京)有限责任公司 + - …… + +> 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。 + +欢迎大家的关注和使用,XXL-JOB也将拥抱变化,持续发展。 + + +## Contributing +Contributions are welcome! Open a pull request to fix a bug, or open an [Issue](https://github.com/xuxueli/xxl-job/issues/) to discuss a new feature or change. + +欢迎参与项目贡献!比如提交PR修复一个bug,或者新建 [Issue](https://github.com/xuxueli/xxl-job/issues/) 讨论新特性或者变更。 + + +## Copyright and License +This product is open source and free, and will continue to provide free community technical support. Individual or enterprise users are free to access and use. + +- Licensed under the GNU General Public License (GPL) v3. +- Copyright (c) 2015-present, xuxueli. + +产品开源免费,并且将持续提供免费的社区技术支持。个人或企业内部可自由的接入和使用。 + + +## Donate +No matter how much the donation amount is enough to express your thought, thank you very much :) [To donate](https://www.xuxueli.com/page/donate.html ) + +无论捐赠金额多少都足够表达您这份心意,非常感谢 :) [前往捐赠](https://www.xuxueli.com/page/donate.html ) diff --git a/xxl-job-2.3.0/doc/XXL-JOB-English-Documentation.md b/xxl-job-2.3.0/doc/XXL-JOB-English-Documentation.md new file mode 100644 index 0000000..792f3ea --- /dev/null +++ b/xxl-job-2.3.0/doc/XXL-JOB-English-Documentation.md @@ -0,0 +1,1247 @@ +## 《Distributed task scheduling framework XXL-JOB》 + +[![Actions Status](https://github.com/xuxueli/xxl-job/workflows/Java%20CI/badge.svg)](https://github.com/xuxueli/xxl-job/actions) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/) +[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases) +[![GitHub stars](https://img.shields.io/github/stars/xuxueli/xxl-job)](https://github.com/xuxueli/xxl-job/) +[![Docker Status](https://img.shields.io/docker/pulls/xuxueli/xxl-job-admin)](https://hub.docker.com/r/xuxueli/xxl-job-admin/) +[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html) +[![donate](https://img.shields.io/badge/%24-donate-ff69b4.svg?style=flat)](https://www.xuxueli.com/page/donate.html) + +[TOCM] + +[TOC] + +## 1. Brief introduction + +### 1.1 Overview +XXL-JOB is a distributed task scheduling framework, the core design goal is to develop quickly, learning simple, lightweight, easy to expand. Is now open source and access to a number of companies online product line, download and use it now. + +> English document update slightly delayed, Please check the Chinese version for the latest document. + +### 1.2 Features +- 1.Simple: support through the Web page on the task CRUD operation, simple operation, a minute to get started; +- 2.Dynamic: support dynamic modification of task status, pause / resume tasks, and termination of running tasks,immediate effect; +- 3.Dispatch center HA (center type): Dispatch with central design, "dispatch center" based on the cluster of Quartz implementation, can guarantee the scheduling - center HA; +- 4.Executor HA (Distributed): Task Distributed Execution, Task " Executer " supports cluster deployment to ensure that tasks perform HA; +- 5.Task Failover: Deploy the Excutor cluster,tasks will be smooth to switch excuter when the strategy of the router choose ‘failover’; +- 6.Consistency: "Dispatch Center" through the DB lock to ensure the consistency of cluster distributed scheduling,one task excuted for once; +- 7.Custom task parameters: support online configuration scheduling tasks into the parameters, immediate effect; +- 8.Scheduling thread pool: scheduling system multi-threaded trigger scheduling operation, to ensure accurate scheduling, not blocked; +- 9.Elastic expansion capacity: once the new executor machine on the line or off the assembly line, the next time scheduling will be re-assigned tasks; +- 10.Mail alarm: the task fails to support e-mail alarm, support configuring multiple email addresses to send bulk alert messages; +- 11.Status monitoring: support real-time monitoring of the progress of the task; +- 12.Rolling execution log: support online view scheduling results, and support Rolling real-time view of the executer output of the complete implementation of the log; +- 13.GLUE: provide Web IDE, support online development task logic code, dynamic release, real-time compiler effective, omit the deployment of the on-line process. Supports historical versions of 30 versions back; +- 14.Data Encryption: The communication between the dispatching center and the executor is used for data encryption, Enhancing the security of dispatching information; +- 15.Task Dependency: Support configuration subtask dependencies, When the parent task executed end and after the success of the implementation will take the initiative to trigger a second task execution, multiple sub tasks are separated by commas; +- 16.Push the Maven central warehouse: The latest stable version will be sent to the Maven central warehouse to facilitate user access and use; +- 17.Task registration: The executor automatically registers tasks periodically, and the dispatch center automatically finds the registered tasks and triggers execution. It also supports manual input of executor address; +- 18.Router strategy: A rich routing strategy is provided when the executor cluster is deployed, these include: first, last, poll, random, consistent HASH, least frequently used, least recently used, failover, busy over, sharding broadcast,etc.; +- 19.Report monitor: Support real-time view of running data, such as the number of tasks, the number of dispatch, the number of executors, etc .; and scheduling reports, such as scheduling date distribution, scheduling success map; +- 20.Script task: Support the development and operation of script tasks in GLUE mode, including shell, Python and other types of script; +- 21.Blocking handling strategy: The scheduling is too dense and the executor is too late to handle. The strategy includes: single machine serial (default), discarding the following scheduling, and Override the previous scheduling; +- 22.Failure handling strategy:Handling strategy when scheduling fails, the strategy includes: failure alarm (default), failure retry; +- 23.Sharding broadcast task: When an executor cluster is deployed, task routing strategy select "sharding broadcast", a task schedule will broadcast all the actuators in the cluster to perform it once, you can develop sharding tasks based on sharding parameters; +- 24.Dynamic sharding: The sharding broadcast task is sharded by the executors to support the dynamic expansion of the executor cluster to dynamically increase the number of shardings and cooperate with the business handle; In the large amount of data operations can significantly improve the task processing capacity and speed. +- 25、Event trigger:In addition to "Cron" and "Task Dependency" to trigger tasks, support event-based triggering tasks. The dispatch center provides API service that triggers a single execution of the task, it can be triggered flexibly according to business events. + + +### 1.3 Development +In 2015, I created the XXL-JOB project repository on github and submitted the first commit, followed by the system structure design, UI selection, interactive design ... +In 2015 - November, XXL-JOB finally RELEASE the first big version of V1.0, then I will be released to OSCHINA, XXL-JOB OSCHINA won the popular recommendation of @红薯, the same period reached OSCHINA's " Popular move "ranked first and git.oschina open source software monthly heat ranked first, especially thanks for @红薯, thank you for the attention and support. +In 2015 - December, I will XXL-JOB published to our internal knowledge base, and get internal colleagues recognized. +In 2016 - 01 months, my company started XXL-JOB internal access and custom work, in this thank Yuan and Yin two colleagues contribution, but also to thank the internal other attention and support colleagues. +In 2017-05-13, the link of "let the code run" in "[the 62nd source of open source China Genesis](https://www.oschina.net/event/2236961)" held in Shanghai,, I stepped on and made a speech about the XXL-JOB, five hundred spectators in the audience reacted enthusiastically ([pictorial review](https://www.oschina.net/question/2686220_2242120)). +> Our company have access to XXL-JOB, internal alias "Ferrari" (Ferrari based on XXL-JOB V1.1 version customization, new access application recommended to upgrade the latest version). +According to the latest statistics, from 2016-01-21 to 2017-07-07 period, the system has been scheduled about 600,000 times, outstanding performance. New access applications recommend the latest version, because after several major updates, the system's task model, UI interaction model and the underlying scheduling communication model has a greater optimization and upgrading, the core function more stable and efficient. + +So far, XXL-JOB has access to a number of companies online product line, access to scenes such as electronic commerce, O2O business and large data operations, as of 2016-07-19, XXL-JOB has access to the company But not limited to: + + - 1、大众点评【美团点评】 + - 2、山东学而网络科技有限公司; + - 3、安徽慧通互联科技有限公司; + - 4、人人聚财金服; + - 5、上海棠棣信息科技股份有限公司 + - 6、运满满【运满满】 + - 7、米其林 (中国区)【米其林】 + - 8、妈妈联盟 + - 9、九樱天下(北京)信息技术有限公司 + - 10、万普拉斯科技有限公司【一加手机】 + - 11、上海亿保健康管理有限公司 + - 12、海尔馨厨【海尔】 + - 13、河南大红包电子商务有限公司 + - 14、成都顺点科技有限公司 + - 15、深圳市怡亚通 + - 16、深圳麦亚信科技股份有限公司 + - 17、上海博莹科技信息技术有限公司 + - 18、中国平安科技有限公司【中国平安】 + - 19、杭州知时信息科技有限公司 + - 20、博莹科技(上海)有限公司 + - 21、成都依能股份有限责任公司 + - 22、湖南高阳通联信息技术有限公司 + - 23、深圳市邦德文化发展有限公司 + - 24、福建阿思可网络教育有限公司 + - 25、优信二手车【优信】 + - 26、上海悠游堂投资发展股份有限公司【悠游堂】 + - 27、北京粉笔蓝天科技有限公司 + - 28、中秀科技(无锡)有限公司 + - 29、武汉空心科技有限公司 + - 30、北京蚂蚁风暴科技有限公司 + - 31、四川互宜达科技有限公司 + - 32、钱包行云(北京)科技有限公司 + - 33、重庆欣才集团 + - 34、咪咕互动娱乐有限公司【中国移动】 + - 35、北京诺亦腾科技有限公司 + - 36、增长引擎(北京)信息技术有限公司 + - 37、北京英贝思科技有限公司 + - 38、刚泰集团 + - 39、深圳泰久信息系统股份有限公司 + - 40、随行付支付有限公司 + - 41、广州瀚农网络科技有限公司 + - 42、享点科技有限公司 + - 43、杭州比智科技有限公司 + - 44、圳临界线网络科技有限公司 + - 45、广州知识圈网络科技有限公司 + - 46、国誉商业上海有限公司 + - 47、海尔消费金融有限公司,嗨付、够花【海尔】 + - 48、广州巴图鲁信息科技有限公司 + - 49、深圳市鹏海运电子数据交换有限公司 + - 50、深圳市亚飞电子商务有限公司 + - 51、上海趣医网络有限公司 + - 52、聚金资本 + - 53、北京父母邦网络科技有限公司 + - 54、中山元赫软件科技有限公司 + - 55、中商惠民(北京)电子商务有限公司 + - 56、凯京集团 + - 57、华夏票联(北京)科技有限公司 + - 58、拍拍贷【拍拍贷】 + - 59、北京尚德机构在线教育有限公司 + - 60、任子行股份有限公司 + - 61、北京时态电子商务有限公司 + - 62、深圳卷皮网络科技有限公司 + - 63、北京安博通科技股份有限公司 + - 64、未来无线网 + - 65、厦门瓷禧网络有限公司 + - 66、北京递蓝科软件股份有限公司 + - 67、郑州创海软件科技公司 + - 68、北京国槐信息科技有限公司 + - 69、浪潮软件集团 + - 70、多立恒(北京)信息技术有限公司 + - 71、广州极迅客信息科技有限公司 + - 72、赫基(中国)集团股份有限公司 + - 73、海投汇 + - 74、上海润益创业孵化器管理股份有限公司 + - 75、汉纳森(厦门)数据股份有限公司 + - 76、安信信托 + - 77、岚儒财富 + - 78、捷道软件 + - 79、湖北享七网络科技有限公司 + - 80、湖南创发科技责任有限公司 + - 81、深圳小安时代互联网金融服务有限公司 + - 82、湖北享七网络科技有限公司 + - 83、钱包行云(北京)科技有限公司 + - 84、360金融【360】 + - 85、易企秀 + - 86、摩贝(上海)生物科技有限公司 + - 87、广东芯智慧科技有限公司 + - 88、联想集团【联想】 + - 89、怪兽充电 + - 90、行圆汽车 + - 91、深圳店店通科技邮箱公司 + - 92、京东【京东】 + - 93、米庄理财 + - 94、咖啡易融 + - 95、梧桐诚选 + - 96、恒大地产【恒大】 + - 97、昆明龙慧 + - 98、上海涩瑶软件 + - 99、易信【网易】 + - 100、铜板街 + - 101、杭州云若网络科技有限公司 + - 102、特百惠(中国)有限公司 + - 103、常山众卡运力供应链管理有限公司 + - 104、深圳立创电子商务有限公司 + - 105、杭州智诺科技股份有限公司 + - 106、北京云漾信息科技有限公司 + - 107、深圳市多银科技有限公司 + - 108、亲宝宝 + - 109、上海博卡软件科技有限公司 + - 110、智慧树在线教育平台 + - 111、米族金融 + - 112、北京辰森世纪 + - 113、云南滇医通 + - 114、广州市分领网络科技有限责任公司 + - 115、浙江微能科技有限公司 + - 116、上海馨飞电子商务有限公司 + - 117、上海宝尊电子商务有限公司 + - 118、直客通科技技术有限公司 + - 119、科度科技有限公司 + - 120、上海数慧系统技术有限公司 + - 121、我的医药网 + - 122、多粉平台 + - 123、铁甲二手机 + - 124、上海海新得数据技术有限公司 + - 125、深圳市珍爱网信息技术有限公司【珍爱网】 + - 126、小蜜蜂 + - 127、吉荣数科技 + - 128、上海恺域信息科技有限公司 + - 129、广州荔支网络有限公司【荔枝FM】 + - 130、杭州闪宝科技有限公司 + - 131、北京互联新网科技发展有限公司 + - 132、誉道科技 + - 133、山西兆盛房地产开发有限公司 + - 134、北京蓝睿通达科技有限公司 + - 135、月亮小屋(中国)有限公司【蓝月亮】 + - 136、青岛国瑞信息技术有限公司 + - 137、博雅云计算(北京)有限公司 + - 138、华泰证券香港子公司 + - 139、杭州东方通信软件技术有限公司 + - 140、武汉博晟安全技术股份有限公司 + - 141、深圳市六度人和科技有限公司 + - 142、杭州趣维科技有限公司(小影) + - 143、宁波单车侠之家科技有限公司【单车侠】 + - 144、丁丁云康信息科技(北京)有限公司 + - 145、云钱袋 + - 146、南京中兴力维 + - 147、上海矽昌通信技术有限公司 + - 148、深圳萨科科技 + - 149、中通服创立科技有限责任公司 + - 150、深圳市对庄科技有限公司 + - 151、上证所信息网络有限公司 + - 152、杭州火烧云科技有限公司【婚礼纪】 + - 153、天津青芒果科技有限公司【芒果头条】 + - 154、长飞光纤光缆股份有限公司 + - 155、世纪凯歌(北京)医疗科技有限公司 + - 156、浙江霖梓控股有限公司 + - 157、江西腾飞网络技术有限公司 + - 158、安迅物流有限公司 + - 159、肉联网 + - 160、北京北广梯影广告传媒有限公司 + - 161、上海数慧系统技术有限公司 + - 162、大志天成 + - 163、上海云鹊医 + - 164、上海云鹊医 + - 165、墨迹天气【墨迹天气】 + - 166、上海逸橙信息科技有限公司 + - 167、沅朋物联 + - 168、杭州恒生云融网络科技有限公司 + - 169、绿米联创 + - 170、重庆易宠科技有限公司 + - 171、安徽引航科技有限公司(乐职网) + - 172、上海数联医信企业发展有限公司 + - 173、良彬建材 + - 174、杭州求是同创网络科技有限公司 + - 175、荷马国际 + - 176、点雇网 + - 177、深圳市华星光电技术有限公司 + - 178、厦门神州鹰软件科技有限公司 + - 179、深圳市招商信诺人寿保险有限公司 + - 180、上海好屋网信息技术有限公司 + - 181、海信集团【海信】 + - 182、信凌可信息科技(上海)有限公司 + - 183、长春天成科技发展有限公司 + - 184、用友金融信息技术股份有限公司【用友】 + - 185、北京咖啡易融有限公司 + - 186、国投瑞银基金管理有限公司 + - 187、晋松(上海)网络信息技术有限公司 + - 188、深圳市随手科技有限公司【随手记】 + - 189、深圳水务科技有限公司 + - 190、易企秀【易企秀】 + - 191、北京磁云科技 + - 192、南京蜂泰互联网科技有限公司 + - 193、章鱼直播 + - 194、奖多多科技 + - 195、天津市神州商龙科技股份有限公司 + - 196、岩心科技 + - 197、车码科技(北京)有限公司 + - 198、贵阳市投资控股集团 + - 199、康旗股份 + - 200、龙腾出行 + - 201、杭州华量软件 + - 202、合肥顶岭医疗科技有限公司 + - 203、重庆表达式科技有限公司 + - 204、上海米道信息科技有限公司 + - 205、北京益友会科技有限公司 + - 206、北京融贯电子商务有限公司 + - 207、中国外汇交易中心 + - 208、中国外运股份有限公司 + - 209、中国上海晓圈教育科技有限公司 + - 210、普联软件股份有限公司 + - 211、北京科蓝软件股份有限公司 + - 212、江苏斯诺物联科技有限公司 + - 213、北京搜狐-狐友【搜狐】 + - 214、新大陆网商金融 + - 215、山东神码中税信息科技有限公司 + - 216、河南汇顺网络科技有限公司 + - 217、北京华夏思源科技发展有限公司 + - 218、上海东普信息科技有限公司 + - 219、上海鸣勃网络科技有限公司 + - 220、广东学苑教育发展有限公司 + - 221、深圳强时科技有限公司 + - 222、上海云砺信息科技有限公司 + - 223、重庆愉客行网络有限公司 + - 224、数云 + - 225、国家电网运检部 + - 226、杭州找趣 + - 227、浩鲸云计算科技股份有限公司 + - 228、科大讯飞【科大讯飞】 + - 229、杭州行装网络科技有限公司 + - 230、即有分期金融 + - 231、深圳法司德信息科技有限公司 + - 232、上海博复信息科技有限公司 + - 233、杭州云嘉云计算有限公司 + - 234、有家民宿(有家美宿) + - 235、北京赢销通软件技术有限公司 + - 236、浙江聚有财金融服务外包有限公司 + - 237、易族智汇(北京)科技有限公司 + - 238、合肥顶岭医疗科技开发有限公司 + - 239、车船宝(深圳)旭珩科技有限公司) + - 240、广州富力地产有限公司 + - 241、氢课(上海)教育科技有限公司 + - 242、武汉氪细胞网络技术有限公司 + - 243、杭州有云科技有限公司 + - 244、上海仙豆智能机器人有限公司 + - 245、拉卡拉支付股份有限公司【拉卡拉】 + - 246、虎彩印艺股份有限公司 + - 247、北京数微科技有限公司 + - 248、广东智瑞科技有限公司 + - 249、找钢网 + - 250、九机网 + - 251、杭州跑跑网络科技有限公司 + - 252、深圳未来云集 + - 253、杭州每日给力科技有限公司 + - 254、上海齐犇信息科技有限公司 + - 255、滴滴出行【滴滴】 + - 256、合肥云诊信息科技有限公司 + - 257、云知声智能科技股份有限公司 + - 258、南京坦道科技有限公司 + - 259、爱乐优(二手平台) + - 260、猫眼电影(私有化部署)【猫眼电影】 + - 261、美团大象(私有化部署)【美团大象】 + - 262、作业帮教育科技(北京)有限公司【作业帮】 + - 263、北京小年糕互联网技术有限公司 + - 264、山东矩阵软件工程股份有限公司 + - 265、陕西国驿软件科技有限公司 + - 266、君开信息科技 + - 267、村鸟网络科技有限责任公司 + - 268、云南国际信托有限公司 + - 269、金智教育 + - 270、珠海市筑巢科技有限公司 + - 271、上海百胜软件股份有限公司 + - 272、深圳市科盾科技有限公司 + - 273、哈啰出行 + - 274、途虎养车 + - 275、卡思优派人力资源集团 + - 276、南京观为智慧软件科技有限公司 + - 277、杭州城市大脑科技有限公司 + - 278、猿辅导 + - …… + +> The company that access and use this product is welcome to register at the [address](https://github.com/xuxueli/xxl-job/issues/1 ), only for product promotion. + +Welcome everyone's attention and use, XXL-JOB will also embrace changes, sustainable development. + +### 1.4 Download + +#### Documentation +- [中文文档](https://www.xuxueli.com/xxl-job/) +- [English Documentation](https://www.xuxueli.com/xxl-job/en/) + +#### Source repository address (The latest code will be released in the two git warehouse in the same time) + +Source repository address | Release Download +--- | --- +[https://github.com/xuxueli/xxl-job](https://github.com/xuxueli/xxl-job) | [Download](https://github.com/xuxueli/xxl-job/releases) +[http://gitee.com/xuxueli0323/xxl-job](http://gitee.com/xuxueli0323/xxl-job) | [Download](http://gitee.com/xuxueli0323/xxl-job/releases) + +#### Center repository address (The latest Release version:1.8.1) +``` + + + com.xuxueli + xxl-job-core + 1.8.2 + +``` + +#### Technical exchange group +- [社区交流](https://www.xuxueli.com/page/community.html) +- [Gitter](https://gitter.im/xuxueli/xxl-job) + +### 1.5 Environment +- JDK:1.7+ +- Servlet/JSP Spec:3.1/2.3 +- Tomcat:8.5.x/Jetty9.2.x +- Spring-boot:1.5.x/Spring4.x +- Mysql:5.6+ +- Maven:3+ + + +## 2. Quick Start + +### 2.1 Init database +Please download project source code,get db scripts and execute, it will generate 16 tables if succeed. + +The relative path of db scripts is as follows: + + /xxl-job/doc/db/tables_xxl_job.sql + +The xxl-job-admin can be deployed as a cluster,all nodes of the cluster must connect to the same mysql instance. + +If mysql instances is deployed in master-slave mode,all nodes of the cluster must connect to master instace. + +### 2.2 Compile +Source code is organized by maven,unzip it and structure is as follows: + + xxl-job-admin:schedule admin center + xxl-job-core:public common dependent library + xxl-job-executor:executor Sample(Select appropriate version of executor,Can be used directly,You can also refer to it and transform existing projects into executors) + :xxl-job-executor-sample-spring:Spring version,executors managed by Spring,general and recommend; + :xxl-job-executor-sample-springboot:Springboot version,executors managed by Springboot; + +### 2.3 Configure and delploy "Schedule Center" + + schedule center project:xxl-job-admin + target:Centralized management、Schedule and trigger task + +#### Step 1:Configure Schedule Center +Configure file’s path of schedule center is as follows: + + /xxl-job/xxl-job-admin/src/main/resources/application.properties + + +The concrete contet describe as follows: + + ### JDBC connection info of schedule center:keep Consistent with chapter 2.1 + xxl.job.db.driverClass=com.mysql.jdbc.Driver + xxl.job.db.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + xxl.job.db.user=root + xxl.job.db.password=root_pwd + + ### Alarm mailbox + xxl.job.mail.host=smtp.163.com + xxl.job.mail.port=25 + xxl.job.mail.username=ovono802302@163.com + xxl.job.mail.password=asdfzxcv + xxl.job.mail.sendFrom=ovono802302@163.com + xxl.job.mail.sendNick=《任务调度平台XXL-JOB》 + + ### Login account + xxl.job.login.username=admin + xxl.job.login.password=123456 + + ### TOKEN used for communication between the executor and schedule center, enabled if it’s not null + xxl.job.accessToken= + + ### Internationalized Settings, the default is Chinese version,Switch to English when the value is "en". + xxl.job.i18n=en + +#### Step 2:Deploy: +If you has finished step 1,then you can compile the project in maven and deploy the war package to tomcat. +the url to visit is :http://localhost:8080/xxl-job-admin (this address will be used by executor and use it as callback url),the index page after login in is as follow + +![index page after login in](https://www.xuxueli.com/doc/static/xxl-job/images/img_6yC0.png "index page after login in") + +Now,the “xxl-job-admin” project is deployed success. + +#### Step3:schedule center Cluster(Option): +xxl-job-admin can be deployed as a cluster to improve system availability. + +Prerequisites for cluster is to keep all node configuration(db and login account info) consistent with each other. Different xxl-job-admin cluster distinguish with each other by db configuration. + +xxl-job-admin can be visited through nginx proxy and configure a domain for nginx,and the domain url can be configured as the executor’s callback url. + +### 2.4 Configur and Deploy "xxl-job-executor-example" + + Executor Project:xxl-job-executor-example (if you want to create new executor project you can refer this demo); + Target:receive xxl-job-admin’s schedule command and execute it; + +#### Step 1:import maven dependence +Pleast confirm import xxl-job-core jar in pom.xml; + +#### Step 2:Executor Configuration +Relative path of the executor configuration file is as follows: + + /xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-spring/src/main/resources/xxl-job-executor.properties + +The concret content of configuration file as follows: + + ### xxl-job admin address list:xxl-job-admin address list: Multiple addresses are separated by commas,this address is used for "heart beat and register" and "task execution result callback" between the executor and xxl-job-admin. + xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin + + ### xxl.job.executor.appname is used to group by executors + xxl.job.executor.appname=xxl-job-executor-sample + ### xxl.job.executor.ip :1,used to register with xxl-job-admin;2,xxl-job-admin dispatch task to executor through it;3,if it is blank executor will get ip automatically, multi network card need to be configured. + xxl.job.executor.ip= + ### xxl.job.executor.port :the port of the executor runned by,if multiple executor instance run on the same computer the port must different with each other + xxl.job.executor.port=9999 + + ### xxl-job log path:runtime log path of the job instance + xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/ + + ### xxl-job, access token:xxl-job access token,enabled if it not blank + xxl.job.accessToken= + + +#### Step 3:executor configuration + +configure file path of executor: + + /xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-spring/src/main/resources/applicationcontext-xxl-job.xml + +Concrete contet describe as follows: + +``` + + + + + + + + + + + + + + + + + + +``` + +#### Step 4:deploy executor project +You can compile and package the project If have done all the steps above successfully,the project supply two executor demo projects,you can choose any one to deploy: + + xxl-job-executor-sample-spring:compile and package in WAR,can be deployed to tomcat; + xxl-job-executor-sample-springboot:compile and package in JAR,and run in springboot mode; + +Now you have deployed the executor project. + +#### Step 5:executor cluster(optional) +In order to improve system availability and job process capacity,executor project can be deployed as cluster. + +Prerequisites:keep all node’s configuration item "xxl.job.admin.addresses" exactly the same with each other,all executors can be register automatically. + + +### 2.5 Start first job "Hello World" +Now let’s create a "GLUE模式(Java)" job,if you want to learn more about it , please see “chapter 3:Task details”。( "GLUE模式(Java)"'s code is maintained online through xxl-job-admin,compare with "Bean模式任务" it’s not need to develop, deploy the code on the executor and it’s not need to restart the executor, so it’s lightweight) + +#### Prerequisites:please confirm xxl-job-admin and executor project has been deployed successfully. + +#### Step 1:Create new job +Login in xxl-job-admin,click on the"新建任务" button, configure the job params as follows and click "保存" button to save the job info. + +![task management](https://www.xuxueli.com/doc/static/xxl-job/images/img_o8HQ.png "task management") + +![create task](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png "create task") + +#### Step 2:develop “GLUE模式(Java)” job +Click “GLUE” button on the right of the job to go to GLUE editor view as shown below。“GLUE模式(Java)” mode task has been inited with default task code for printing Hello World。 ( “GLUE模式(Java)” mode task is a java code fragment implements IJobHandler interface,it will be executed in executor,you can use @Resource/@Autowire to inject other java bean instance,if you want to see more info please go to chapter 3) + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Fgql.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_dNUJ.png "在这里输入图片标题") + +#### Step 3:trigger task +If you want to run the job manually please click "执行" button on the right of the job(usually we trigger job by Cron expression) + +#### Step 4:view log +Click “日志” button on the right side of the task you will go to the task log list ,you will see the schedule history records of the task and the schedule detail info,execution info and execution params.If you click the “执行日志” button on the right side of the task log record,you will go to log console and view the execute log in the course of task execution. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_inc8.png "在这里输入图片标题") + +On the log console,you can view task execution log on the executor immediately after it dump to log file,so you can monitor the task execution process by Rolling way. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_eYrv.png "在这里输入图片标题") + +## 3. Task details + +### Description of configuration item: + + - 执行器:the container where job executed in,it will be discovered automaticly if it has registered success when job was scheduled,and the job will be executed automaticly through this way.On the other side all tasks was grouped by this way.Tasks must be binded to a executor and it can be configured on "执行器管理" page; + - 描述:the decription of task + - 路由策略:when executors deployed as a cluster,it can configure multi route policys,include: + FIRST(第一个):default select the first executor; + LAST(最后一个):default select the last executor; + ROUND(轮询):round select the executor;; + RANDOM(随机):random select the executor; + CONSISTENT_HASH(一致性HASH):all jobs was evenly scheduled on different machines,make sure load balance of executors under the same group and the same job will be scheduled to the same machine. + LEAST_FREQUENTLY_USED(最不经常使用):default select the least often used executor. + LEAST_RECENTLY_USED(最近最久未使用):defalut select the longest not used executor. + FAILOVER(故障转移):beat with the executor in order and select the first beat success executor as target executor. + BUSYOVER(忙碌转移):check the executor busy or not in order,the first executor checked not busy is to be select as the target scheduled executor. + SHARDING_BROADCAST(分片广播):broadcast all executor nodes under the same executor group execute the job, slice number will be transferred at the same time,shard task will be executed accordate with the shard number. + + - Cron:Cron expression used to trigger job execution; + - 运行模式: + BEAN模式:job was maintained on the side of executor by as JobHandler instance,it will be executed accordate with "JobHandler" properties. + GLUE模式(Java):task source code is maintened in the schedule center,it must implement IJobHandler and explain by "groovy" in the executor instance,inject other bean instace by annotation @Resource/@Autowire. + GLUE模式(Shell):it’s source code is a shell script and maintained in the schedule center. + GLUE模式(Python):it’s source code is a python script and maintained in the schedule center. + - JobHandler:it’s used in "BEAN模式",it’s instance is defined by annotation @JobHandler on the JobHandler class name. + - 子任务Key:every task has a unique key (task Key can acquire from task list),when main task is done successfully it’s child task stand for by this key will be scheduled. + - 阻塞处理策略:the stategy handle the task when this task is scheduled too frequently and the task is block to wait for cpu time. + 单机串行(默认):task schedule request go into the FIFO queue and execute serially. + 丢弃后续调度:the schedule request will be discarded and marked as fail when the same task’s instance scheduled befor is running in the target executor. + 覆盖之前调度:the schedule request will be executed and clear before task queue when the same task’s instance scheduled befor is running in the target executor. + - 失败处理策略:handle policy for schedule fail + 失败告警(默认):it will trigger alarm such as send alarm mail when it’s scheduled fail. + 失败重试:it will try another time when it’s scheduled fai,if try fail it will trigger alarm for fail.every time it will trigger a new schedule request. + - 执行参数:the params needed in the run time of the task, multiple values are separated by commas,it will be passed to task instace as an array when task is scheduled. + - 报警邮件:the email used to receive the alarm mail when task is scheduled fail or execute fail, multiple values are separated by commas. + - 负责人:The person name response for the task. + +### 3.1 BEAN模式 +The task logic exist in the executor project as JobHandler,the develop steps as shown below: + +#### Step 1:develp obHandler in the executor project + - 1, create new java class implent com.xxl.job.core.handler.IJobHandler; + - 2, if you add @Component annotation on the top of the class name it’s will be managed as a bean instance by spring container; + - 3, add “@JobHandler(value=" customize jobhandler name")” annotation,the value stand for JobHandler name,it will be used as JobHandler property when create a new task in the schedule center. + + +#### Step 2:create task in schedule center +If you want learn more about configure item please go and sedd “Description of configuration item”,select "BEAN模式" as run mode,property JobHandler please fill in the value defined by @JobHande. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png "在这里输入图片标题") + +### 3.2 GLUE模式(Java) +Task source code is maintained in the schedule center and can be updated by Web IDE online, it will be compiled and effective real-time,didn’t need to assign JobHandler,develop flow shown as below: + +#### Step 1:create task in schedule center +If you want learn more about configure item please go and sedd “Description of configuration item”,select "GLUE模式(Java)" as run mode. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_tJOq.png "在这里输入图片标题") + +#### Step 2:develop task source code +Select the task record and click “GLUE” button on the righe of it,it will go to GLUE task’s WEB IDE page,on this page yo can edit you task code(also can edit in other IDE tools,copy and paste into this page). + +Version backtrack(support 30 versions while backtrack):on the WEB IDE page of GLUE task,on upper right corner drop down box please select “版本回溯”,it will display GLUE updated history,select the version you want it will display the source code of this version,it will backtrace the version while click save button. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_dNUJ.png "在这里输入图片标题") + +### 3.3 GLUE模式(Shell) + +#### Step 1:create new task in schedule center +If you want learn more about configure item please go and sedd “Description of configuration item”,select "GLUE模式(Shell)"as run mode. + +#### Step 2:develop task source code +Select the task record and click “GLUE” button on the righe of it,it will go to GLUE task’s WEB IDE page,on this page yo can edit you task code(also can edit in other IDE tools,copy and paste into this page). + +Actually it is a shell script fragment. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_iUw0.png "在这里输入图片标题") + +### 3.4 GLUE模式(Python) + +#### Step 1:create new task in schedule center +If you want learn more about configure item please go and sedd “Description of configuration item”,select "GLUE模式(Python)"as run mode. + +#### Step 2:develop task source code +Select the task record and click “GLUE” button on the righe of it,it will go to GLUE task’s WEB IDE page,on this page yo can edit you task code(also can edit in other IDE tools,copy and paste into this page). + +Actually it is a python script fragment. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_BPLG.png "在这里输入图片标题") + + +## 4. Task Management +### 4.0 configure executor +click"执行器管理" on the left menu,it will go to the page as shown below: +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Hr2T.png "在这里输入图片标题") + +    1,"调度中心OnLine”:display schedule center machine list,when task is scheduled it will callback schedule center for notify the execution result in failover mode, so that it can avoid a single point scheduler; +    2,"执行器列表" :display all nodes under this executor group. + +If you want to create a new executor,please click "+新增执行器" button: +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_V3vF.png "在这里输入图片标题") + +### Description of executor attributes + + Appname: the unique identity of the executor cluster,executor will registe automatically and periodically by appname so that it can be scheduled. + 名称: the name of ther executor,it is used to describe the executor. + 排序: the order of executor,it will be used in the place where need to select executor. + 注册方式:which way the schedule center used to acquire executor address through; + 自动注册:executor will register automatically,through this schedule center can discover executor dynamically. + 手动录入:fill in executor address manually and it will be used by schedule center, multiple address separated by commas. + 机器地址:only effective when "注册方式" is "手动录入",support fill in executor address manually. + +### 4.1 create new task +Go to task management list page,click “新增任务” button on the upper right corner,on the pop-up window“新增任务”page configure task property and save.learn more info please go and see "3,task details". + +### 4.2 edit task +Go to task management list page and choose the task you want to edit ,click”编辑”button on the right side of the task,on the pop-up window “编辑任务”page edit task property and save. + +### 4.3 edit GLUE source code + +Only fit to GLUE task. + +choose the task you want to edit and click” GLUE”button on the right side of the task, it will go to the Web IDE page of GLUE task,then you can edit task source code on this page.you can read "3.2 GLUE模式(Java)" for more info. + +### 4.4 pause/recover task +You can pause or recover task but it just fit to follow up schedule trigger and won’t affect scheduled tasks,if you want to stop tasks which has been triggered,please go and see “4.8 stop the running task” + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAhX.png "在这里输入图片标题") + +### 4.5 manually trigger +You can trigger a task manually by Click “执行”button,it won’t affect original scheduling rules. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Z5wp.png "在这里输入图片标题") + +### 4.6 view schedule log +You can view task’s history schedule log by click “日志” button,on the history schedule log list page you can view every time of task’s schedule result,execution result and so on,click “执行日志” button can view the task’s full execute log. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_9235.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_inc8.png "在这里输入图片标题") + + 调度时间:schedule center trigger time when schedule and send execution signal to executor; + 调度结果:schedule center trigger task’s result, 200 represent success,500 or other number stands for fail; + 调度备注:schedule center trigger task’s remark info; + 执行器地址:the machine address where the task was executed; + 运行模式:run mode of triggered task,go and see "3,Task Details" for more info; + 任务参数:the input params of the executed task; + 执行时间:the callback time task was done in the executor; + 执行结果:task’s execute result in the executor, 200 represent success,500 or other number stands for fail; + 执行备注:task’s execute remark info in the executor; + 操作: + "执行日志"button:click this button you can view task’s execution detail log,go and see chapter 4.7 “view execution log” for more info; + "终止任务"button:click this button you can stop the task’s execution thread on this executor,include bloked task instance which didn’t has started; + +### 4.7 view execution log +Click the “执行日志” button on the right side of the record,you can go to the execution log page,you can view the full execution log of the logic business code, shown as below: + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_tvGI.png "在这里输入图片标题") + +### 4.8 stop running tasks +Just fit to running tasks,on the task log list page,click “终止任务” button on the right side of the record, it will send stop command to the executor where the task was executed,finally the task was killed and the task instance execute queue of this task will be clear. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_hIci.png "在这里输入图片标题") + +It is implemented by interrupt execute thread, it will trigger InterruptedException.so if JobHandler catch this execuption and handle this exception this function is unavailable. + +So if you want stop the running task ,the JobHandler need to handle InterruptedException separately by throw this exception.the right logic is as shown below: +``` +try{ + // do something +} catch (Exception e) { + if (e instanceof InterruptedException) { + throw e; + } + logger.warn("{}", e); +} +``` + +If JobHandler start child thread,child thread also must not catch InterruptedException,and it should throw exception. + + +### 4.9 delete execution log +On the task log list page, after you select executor and task, you can click"删除" button on the right side and it will pop-up "日志清理" window,on the pop-up window you can choose different log delete policy,choose the policy you want to execute and click "确定" button it will delele relative logs: +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Ypik.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_EB65.png "在这里输入图片标题") + +### 4.10 delete task +Click the delete button on the right side of the task,the task will be deteted. + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Z9Qr.png "在这里输入图片标题") + +## 5. Overall design +### 5.1 Source directory introduction + - /doc :documentation and material + - /db :db scripts + - /xxl-job-admin :schedule and admin center + - /xxl-job-core :common core Jar +    - /xxl-job-executor-samples :executor,Demo project(you can develop on this demo project or adjust your own exist project to executor project) + +### 5.2 configure database +XXL-JOB schedule module is implemented based on Quartz cluster,it’s “database” is extended based on Quartz’s 11 mysql tables. + +XXL-JOB custom Quartz table structure prefix(XXL_JOB_QRTZ_). + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_bNwm.png "在这里输入图片标题") + +The added tables as shown below: + - XXL_JOB_QRTZ_TRIGGER_GROUP:executor basic table, maintain the info about the executor; + - XXL_JOB_QRTZ_TRIGGER_REGISTRY:executor register table, maintain addressed of online executors and schedule center machines. + - XXL_JOB_QRTZ_TRIGGER_INFO:schedule extend table,it is used to save XXL-JOB schedule extended info,such as task group,task name,machine address,executor,input params of task and alarm email and so on. + - XXL_JOB_QRTZ_TRIGGER_LOG:schedule log table,it is used to save XXL-JOB task’s histry schedule info,such as :schedule result,execution result,input param of scheduled task,scheduled machine and executor and so on. + - XXL_JOB_QRTZ_TRIGGER_LOGGLUE:schedule log table,it is used to save XXL-JOB task’s histry schedule info,such as :schedule result,execution result,input param of scheduled task,scheduled machine and executor and so on. + +So XXL-JOB database total has 16 tables. + +### 5.3 Architecture design +#### 5.3.1 Design target +All schedule behavior has been abstracted into “schedule center” common platform , it dosen’t include business logic and just responsible for starting schedule requests. + +All tasks was abstracted into separate JobHandler and was managed by executors, executor is responsible for receiving schedule request and execute the relative JobHandler business. + +So schedule and task can be decoupled from each other, by the way it can improve the overall stability and scalability of the system. + +#### 5.3.2 System composition +- **Schedule module(schedule center)**: + it is responsible for manage schedule info,send schedule request accord task configuration and it is not include an business code.schedule system decouple with the task, improve the overall stability and scalability of the system, at the same time schedule system performance is no longer limited to task modules. + Support visualization, simple and dynamic management schedule information, include create,update,delete, GLUE develop and task alarm and so on, All of the above operations will take effect in real time,support monitor schedule result and execution log and executor failover. +- **Executor module(Executor)**: + it is responsible for receive schedule request and execute task logic,task module focuses on the execution of the task, Development and maintenance is simpler and more efficient. + Receive execution request, end request and log request from schedule center. + +#### 5.3.3 Architecture diagram + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Qohm.png "在这里输入图片标题") + +### 5.4 Schedule module analysis +#### 5.4.1 Disadvantage of quartz +Quartz is a good open source project and was often as the first choice for job schedule.Tasks was managed by api in quartz cluster so it can avoid some disadvantages of single quartz instance,but it also has some disadvantage as shown below: + - problem 1:it is not humane while operate task by call apill. + - problem 2:it is need to store business QuartzJobBean into database, System Invasion is quite serious. + - problem 3:schedule logic and couple with QuartzJobBean in the same project,it will lead a problem in case that if schedule tasks gradually increased and task logic gradually increased,under this situation the performance of the schedule system will be greatly limited by business. +XXL-JOB solve above problems of quartz. + +#### 5.4.2 RemoteHttpJobBean +Under Quartz develop,task logic often was maintained by QuartzJobBean, couple is very serious.in XXL-JOB"Schedule module" and "task module" are completely decoupled,all scheduled tasks in schedule module use the same QuartzJobBean called RemoteHttpJobBean.the params of the tasks was maintained in the extended tables,when trigger RemoteHttpJobBean,it will parse different params and start remote cal l and it wil call relative remote executor. + +This call module is like RPC,RemoteHttpJobBean provide call proxy functionality,the executor is provided as remote service. + +#### 5.4.3 Schedule Center HA(Cluster) +It is based on Quartz cluster,databse use Mysql;while QUARTZ task schedule is used in Clustered Distributed Concurrent Environment,all nodes will report task info and store into database.it will fetch trigger from database while execute task,if trigger name and execute time is the same only one node will execute the task. + +``` +# for cluster +org.quartz.jobStore.tablePrefix = XXL_JOB_QRTZ_ +org.quartz.scheduler.instanceId: AUTO +org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX +org.quartz.jobStore.isClustered: true +org.quartz.jobStore.clusterCheckinInterval: 1000 +``` + +#### 5.4.4 Schedule threadpool +Default threads in the threadpool is 10 so it can avoid task schedule delay because of single thread block. + +``` +org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool +org.quartz.threadPool.threadCount: 10 +org.quartz.threadPool.threadPriority: 5 +org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true +``` + +business logic was executed on remote executor in XXL-JOB,schedule center just start one schedule request at every schedule time,executor will inqueue the request and response schedule center immediately. There is a huge difference from run business logic in quartz’s QuartzJobBean directly,just as Elephants and feathers; + +the logic of task in XXL-JOB schedule center is very light and single job average run time alaways under 100ms,(most is network time consume).so it can use limited threads to support a large mount of job run concurrently, 10 threads configured above can support at least 100 JOB normal execution. + +#### 5.4.5 @DisallowConcurrentExecution +This annotation is not used default by the schedule center of XXL-JOB schedule module, it use concurrent policy default,because RemoteHttpJobBean is common QuartzJobBean,so it greatly improve the capacity of schedule system and decrease the blocked chance of schedule module in the case of multi-threaded schedule. + +Every schedule module was scheduled and executed parallel in XXL-JOB,but tasks in executor is executed serially and support stop task. + +#### 5.4.6 misfire +The handle policy when miss the job’s trigger time. +he reason may be:restart service,schedule thread was blocked by QuartzJobBean, threads was exhausted,some task enable @DisallowConcurrentExecution,the last schedule was blocked and next schedule was missed. + +The default value of misfire in quartz.properties as shown below, unit in milliseconds: +``` +org.quartz.jobStore.misfireThreshold: 60000 +``` + +Misfire rule: + withMisfireHandlingInstructionDoNothing:does not trigger execute immediately and wait for next time schedule. + withMisfireHandlingInstructionIgnoreMisfires:execute immediately at the first frequency of the missed time. + withMisfireHandlingInstructionFireAndProceed:trigger task execution immediately at the frequency of the current time. + +XXL-JOB’s default misfire rule:withMisfireHandlingInstructionDoNothing + +``` +CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getJobCron()).withMisfireHandlingInstructionDoNothing(); +CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); +``` + +#### 5.4.7 log callback service +When schedule center of the schedule module was deployed as web service, on one side it play as schedule center, on the other side it also provide api service for executor. + +The source code location of schedule center’s “log callback api service” as shown below: +``` +xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback +``` + +Executor will execute task when it receive task execute request.it will notify the task execute result to schedule center when the task is done. + +#### 5.4.8 task HA(Failover) +If executor project was deployed as cluster schedule center will known all online executor nodes,such as:“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”. + +When "路由策略" select "故障转移(FAILOVER)",it will send heart beat check request in order while schedule center start schedule request. The first alive checked executor node will be selected and send schedule request to it. + +“调度备注” can be viewed on the monitor page when schedule success. As shown below: +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_jrdI.png "在这里输入图片标题") + +“调度备注” will display local schedule route path、executor’s "注册方式"、"地址列表" and task’s "路由策略"。Under "故障转移(FAILOVER)" policy, schedule center take first address to do heartbeat detection, heat beat fail will automatically skip, the second address heart beat fail…… until the third address “127.0.0.1:9999” heart beat success, it was selected as target executor, then send schedule request to target executor, now the schedule process is end wait for the executor’s callback execution result. + +#### 5.4.9 schedule log +Every time when task was scheduled in the schedule center it will record a task log, the task log include three part as shown below: + +- 任务信息:include executor address、JobHandler and executor params,accord these parameters it can locate specific machine and task code that the task will be executed. +- 调度信息:include schedule time、schedule result and schedule log and so on,accord these parameters you can understand some task schedule info of schedule center. +- 执行信息:include execute time、execute result and execute log and so on, accord these parameters you can understand the task execution info in the executor. + +Schedule log stands fo single task schedule, attribute description is as follows: +- 执行器地址:machine addresses on which task will be executed. +- JobHandler:JobHandler name of task under Bean module. +- 任务参数:the input parameters of task +- 调度时间:the schedule time started by schedule center. +- 调度结果:schedule result of schedule center,SUCCESS or FAIL. +- 调度备注:remark info of task scheduled by schedule center, such as address heart beat log. +- 执行时间:the callback time when the task is done in the executor. +- 执行结果:task execute result in the executor,SUCCESS or FAIL. +- 执行备注:task execute remark info in the executor,such as exception log. +- 执行日志:full execution log of the business code during execution of the task,go and see “4.7 view execution log”. + +#### 5.4.10 Task dependency +principle:every task has a task key in XXL-JOB, every task can configure property “child task Key”,it can match task dependency relationship through task key. + +When parent task end execute and success, it will match child task dependency accord child task key, it will trigger child task execute once if it matched child task. + +On the task log page ,you can see matched child task and triggered child task’s log info when you “查看”button of “执行备注”,otherwise the child task didin’t execute, as shown beleow: + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Wb2o.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_jOAU.png "在这里输入图片标题") + +### 5.5 Task "run mode" analysis +#### 5.5.1 "Bean模式" task +Development steps:go and see "chapter 3" . +principle: every Bean mode task is a Spring Bean instance and it is maintained in executor project’s Spring container. task class nedd to add “@JobHandler(value="name")” annotation, because executor identify task bean instance in spring container through annotation. Task class nedd to implements interface IJobHandler, task logic code in method execute(), the task logic in execute() method will be executed when executor received a schedule request from schedule center. + +#### 5.5.2 "GLUE模式(Java)" task +Development steps:go and see "chapter 3" . +Principle : every "GLUE模式(Java)" task code is a class implemets interface IJobHandler, when executor received schedule request from schedule center these code will be loaded by Groovy classloader and instantiate into a Java object and inject spring bean service declared in this code at the same time(please confirm service and class reference in Glue code exist in executor project), then call the object’s execute() method and execute task logic. + +#### 5.5.3 GLUE模式(Shell) + GLUE模式(Python) +Development steps:go and see "chapter 3" . +principle:the source code of script task is maintained in schedule center and script logic will be executed in executor. when script task was triggered, executor will load script source code and generate a script file on the machine where executor was deployed, the script will be called by java code, the script output log will be written to the task log file in real time so that we can monitor script execution in real time through schedule center, the return code 0 stands for success other for fail. + +All supported types of scripts as shown beloes: + + - shell script:shell script task will be enabled when select "GLUE模式(Shell)"as task run mode. + - python script: python script task will be enabled when select " GLUE模式(Python)"as task run mode. + + +#### 5.5.4 executor +Executor is actually an embedded Jetty server with default port 9999, as shown below(parameter:xxl.job.executor.port). + +Executor will identify Bean mode task in spring container through @JobHandler When project start, it will be managed use the value of annotation as key. + +When executor received schedule request from schedule center, if task type is “Bean模式” it will match bean mode task in Spring container and call it’s execute() method and execute task logic. if task type is “GLUE模式”, it will load Glue code, instantiate a Java object and inject other spring service(notice: the spring service injected in Glue code must exist in the same executor project), then call execute() method and execute task logic. + +#### 5.5.5 task log +XXL-JOB will generate a log file for every schedule request, the log info will be recorded by XxlJobLogger.log() method, the log file will be loaded when view log info through schedule center. + +(history version is implemented by overriding LOG4J’s Appender so it exists dependency restrictions, The way has been discraded in the new version) + +The location of log file can be specified in executor configuration file, default pattern is : /data/applogs/xxl-job/jobhandler/formatted date/primary key for database scheduling log records.log”. + +When start child thread in JobHandler, child thread will print log in parent JobHandler thread’s execute log in order to trace execute log. + +### 5.6 Communication module analysis + +#### 5.6.1 A complete task schedule communication process + - 1,schedule center send http request to executor, and the service in executor in fact is a jetty server with default port 9999. + - 2,executor execute task logic. + - 3,executor http callback with schedule center for schedule result, the service in schedule center used to receive callback request from executor is a set of api opended to executor. + +#### 5.6.2 Encrypt Communication data +When scheduler center send request to executor, it will use RequestModel and ResponseModel object to encapsulate schedule request parameters and response data, these two object will be serialized before communication, data protocol and time stamp will be checked so that achieve data encryption target. + +### 5.7 task register and task auto discover +Task executor machine property has been canceled from v1.5, instead of task register and auto discovery, get remote machine address dynamic. + + AppName: unique identify of executor cluster, executor is minimal unite of task register, every task recognize machine addresses under the executor on which it was binded. + Beat: heartbeat cycle of task register, default is 15s, and the time executor usedto register is twice the time, the time used to auto task discover is twice the beat time, the invalid time of register is twice the Beat time. + registry table: see XXL_JOB_QRTZ_TRIGGER_REGISTRY table, it will maintain a register record periodically while task register, such as the bind relationship between machine address and AppName, so that schedule center can recognize machine list by AppName dynamicly. + +To ensure system lightweight and reduce learning costs, it did not use Zookeeper as register center, Use DB as register center to do task registration. + +### 5.8 task execute result +Since v1.6.2, the task execute result is recognized through ReturnT of IJobHandler, it executes success when return value meets the condition "ReturnT.code == ReturnT.SUCCESS_CODE" , or it executes fail, and it can callback error message info to schedule center through ReturnT.msg, so it can control task execute results in the task logic. + +### 5.9 slice broadcat & dynamic slice +When “分片广播” is selected as route policy in executor cluster, one task schedule will broadcast all executor node in cluster to trigger task execute in every executor, pass slice parameter at the same time, so we can develop slice task by slice parameters. + +"分片广播" break the task by the dimensions of executor, support dynamic extend executor cluster so that it can add slice number dynamically to do business process, In case of large amount of data process can significantly improve task processing capacity and speed. + +The develop process of "分片广播" is the same as general task, The difference is that you can get slice parameters,code as shown below(go and see ShardingJobHandler in execuotr example ): + + int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex(); + int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal(); + +This slice parameter object has two properties: + + index:the current slice number(start with 0),stands for the number of current executor in the executor cluster. + total:total slice number,stands for total slices in the executor cluster. + +This feature applies to scenes as shown below: +- 1、slice task scene:when 10 executor to handle 10w records, 1w records need to be handled per machine, time-consuming 10 times lower; +- 2、Broadcast task scene:broadcast all cluster nodes to execute shell script、broadcast all cluster nodes to update cache. + +### 5.10 AccessToken +To improve system security it is need to check security between schedule center and executor, just allow communication between them when AccessToken of each other matched. + +The AccessToken of scheduler center and executor can be configured by xxl.job.accessToken. + +There are only two settings when communication between scheduler center and executor just: + +- one:do not configure AccessToken on both, close security check. +- two:configure the same AccessToken on both; + +### 5.11 Dispatching center API services +The scheduling center provides API services for executors and business parties to choose to use, and the currently available API services are available. + + 1. Job result callback service; + 2. Executor registration service; + 3. Executor registration remove services; + 4. Triggers a single execution service, and support the task to be triggered according to the business event; + +The scheduling center API service location: com.xxl.job.core.biz.AdminBiz.java + +The scheduling center API service requests reference code:com.xxl.job.adminbiz.AdminBizTest.java + + +## 6 Version update log +### 6.1 version V1.1.x,New features [2015-12-05] +**【since V1.1.x,XXL-JOB was used by company hiring me,alias Ferrari inner company,the latest version is recommended for new project】** +- 1、simple:support CRUD operation through Web page, simple and one minute to get started; +- 2、dynamic:support dynamic update task status,pause/recover task and effective in real time; +- 3、service HA:task info stored in mysql, Job service support cluster to make sure service HA; +- 4、task HA:when some Job services hangs up, tasks will be assigned to some other alive machines, if all nodes of the cluster hangs up, it will compensate for the execution of lost task when restart; +- 5、one task instance will only be executed on one executor; +- 6、task is executed serially; +- 7、support for custom parameters; +- 8、Support pause task execution remotely . + +### 6.2 version V1.2.x,New features [2016-01-17] +- 1、support task group; +- 2、suport local task, remote task; +- 3、support two types underlying communication ,Servlet or JETTY; +- 4、support task log; +- 5、support serially execution,parallel execution; + + Description:system architecture of V1.2 divided by function as shown below: + + - schedule module(schedule center):Responsible for managing schedule information,send schedule request according to the schedule configuration; + - execute module(executor):Responsible for receiving schedule request and execute task logic; + - communication module:Responsible for the communication between the schedule module and execute module; + advantage: + + - Decouple:execute module supply task api, schedule module maintains schedule information, The business is independent of each other; + - High scalability; + - stability; + +### 6.3 version V1.3.0,New features [2016-05-19] +- 1、discard local task module, remote task was recommended, easy to decouple system, the JobHandler of task was called executor. +- 2、dicard underlying communication type servlet, JETTY was recommended, schedule and callback bidirectional communication, rebuild the communication logic; +- 3、UI interactive optimization:optimize left menu expansion and menu item selected status , task list opens the table with compression optimization; +- 4、【important】executor is subdivided into two develop mode:BEAN、GLUE: + + Introduction to the executor mode: + - BEAN mode executor:every executor is a Spring Bean instance,it was recognized and scheduled by XXL-JOB through @JobHandler annotation; + -GLUE mode executor:every executor corresponds to a piece of code,edited and maintained online by Web, Dynamic compile and takes effect in real time, executor is responsible for loading GLUE code and executing; + +### 6.4 version V1.3.1,New features [2016-05-23] +- 1、Update project directory structure: + - /xxl-job-admin -------------------- 【schedule center】:Responsible for managing schedule information,send schedule request according to schedule configuration; + - /xxl-job-core ----------------------- Public core dependence + - /xxl-job-executor-example ------ 【executor】:Responsible for receiving scheduling request and execute task logic; + - /db ---------------------------------- create table script + - /doc --------------------------------- user manual +- 2、Upgrade the user manual under the new directory structure; +- 3、Optimize some interactions and UI; + +### 6.5 version V1.3.2,New features [2016-05-28] +- 1、Schedule logic for transactional handle; +- 2、executor asynchronous callback execution log; +- 3、【important】based on HA support of schedule center,extend executor’s Failover support,Support configure multiple execution addresses; + +### 6.6 version V1.4.0 New features [2016-07-24] +- 1、Task dependency: it is implemented by trigger event, it will automatically trigger a child task schedule after Task execute success and callback, multiple child tasks are separated by commas; +- 2、executor source code has been reconstructed, optimize underlying db script; +- 3、optimize task thread group logic of executor, before it is group by executor’s JobHandler so when multiple task reuse Jobhanlder will cause block with each other. Now it is grouped by task of schedule center so tasks are isolated from task execution. +- 4、optimize communication scheme between executor and schedule center, a simple RPC protocol was implemented through Hex + HC, optimize the maintenance and analysis process of communication parameters. +- 5、schedule center, create/edit task, page attribute adjustment: + - 5.1、the property JobName was removed from task add/edit page and it is changed to automatically generate by system: this field before is used to identify a task in schedule center and did not use in other scenes, so remove it to simplify the task creation; + - 5.2、adjust "GLUE模式" property in task add/edit page to near JobHandler input box; + - 5.3、"报警阈值" property was removed from task add/edit page; + - 5.4、"子任务Key" property was removed from task add/edit page, the key of task can be acquired from task list page, child task will be triggered by child task key when main task execute success. +- 6、bug fix: + - 6.1、optimize jetty executor shutdown, solve one problem may cause jetty could not shutdown. + - 6.2、optimize callback of executor task queue when task execute finish. Solve a problem which may cause task could not callback. + - 6.3、Optimize Page List Parameters of Schedule Center, solve one problem which may be caused by post length limit of server. + - 6.4、optmize executor Jobhandler annotation, solve a problem that container could not load the JobHandler caused by the transaction proxy. + - 6.5、optimize remote schedule, disable retry policy, solve a problem may caused repeat call; + +Tips: V1.3.x release has been published , enter the maintenance phase, branch address is [V1.3](https://github.com/xuxueli/xxl-job/tree/v1.3) .New features will be updated continuously in the master branch. + +### 6.7 version V1.4.1 New features [2016-09-06] +- 1、project successfully pushed to maven central warehouse, Central warehouse address and dependency as shown below: + ``` + + + com.xuxueli + xxl-job-core + ${最新稳定版} + + ``` +- 2、To adapt to the rules of central warehouse, groupId has been changed from com.xxl to com.xuxueli. +- 3、to resolve the problem that sub-modules can not be compiled separately, system version is not maintained in the project root pom, each sub-module is configured separately for version configuration; +- 4、optimize data byte length statistics rule of RPC communication it may reduce 50% of data traffic; +- 5、IJobHandler cancel task return value, before the execution status is judged by the return value, now it instead of task was executed successfully by default only when exception was caught the task execution was judged failed. +- 6、optimize system public pop-up box as a plugin; +- 7、optimize table structure and the table name now is upper case; +- 8、modify ContentType of JSON response from exception handler of schedule center to fix the bug that it is could not recognized by browser. + +### 6.8 version V1.4.2 New features [2016-09-29] +- 1、push V1.4.2 to maven central warehouse, main version V1.4 enter maintenance phase; +- 2、fix problem task list offset when add task; +- 3、fix a style disorder problem that caused by bootstrap does not support the modal frame overlap , the problem occurs when the task is edited; +- 4、optimize schedule status when schedule timeout and Handler could not matched; +- 5、the task could not stop problem caused by catch exception has given solution; + +### 6.9 version V1.5.0 New features [2016-11-13] +- 1、task register: executor registers the task automatically, schedule center will automatically discover the registered task and trigger execution. +- 2、add parameter AppName for executor: AppName is the unique identifier of each executor cluster, register periodically and automatically with AppName. +- 3、add column executor management in schedule center : manage online executors, automatically discover registered executors via the property AppName。Only managed executors are allowed to be used; +- 4、change Task group attribute to executor : each task needs to be bound to the specified exector, schedule address is obtained by binded executor; +- 5、discard property task machine: by the way of binding task with executor, automatically discovers registered remote executor address and triggers schedule request. +- 6、add DBGlueLoader in public dependency, it implement GLUE source code calssloader based on native jdbc, Reduce third party reliance (mybatis,spring-orm etc); simplify and optimize executor configuration (for GLUE task), Reduce the difficulty of getting started; +- 7、adjust table structure, reconstruct the project; +- 8、schedule center automatically registered and found, failover: schedule center periodically registered automatically, task callback can recognize all online schedule center addresses, task callback support failover so that it can avoid single point of risk. + +### 6.10 version V1.5.1 New features [2016-11-13] +- 1、Reconstruct the underlying code and optimize logic, clean POM and Clean Code; +- 2、Servlet/JSP Spec selected 3.0/2.2; +- 3、Spring updated to 3.2.17.RELEASE version; +- 4、Jetty updated to version 8.2.0.v20160908; +- 5、has push V1.5.0 and V1.5.1 to maven central warehouse; + +### 6.10 version V1.5.2 New features [2017-02-28] +- 1、optimize IP tools class which used to gets IP address,IP static cache; +- 2、both executor and schedule center support customize registered IP address;Solve problem when machine has multiple network card and get the wrong card; +- 3、solve the problem that it will generate multiple log files when executed across days; +- 4、the non-sensitive log level is adjusted to debug; +- 5、Upgrade the database connection pool to c3p0; +- 6、optimize log4j property of executor,remove invalid attribute; +- 7、reconstruct underlying code and optimize logic and Clean Code; +- 8、optimize Dependency Injection Logic of GLUE, support injected as alias; + +### 6.11 version V1.6.0 New features [2017-03-13] +- 1、upgrade communication scheme,the HEX communication model is adjusted to the B-RPC model based on HTTP; +- 2、executor supports set execution address list manually,provide switch to use automatically registered address or manually set address; +- 3、executor route rules:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移; +- 4、unified thread model and thread destruction scheme (by the way of listener or stop() method,Destroy the thread when container is destroyed;Daemon is sometimes not ideal); +- 5、unified system configuration data,Unified managed by configuration files; +- 6、CleanCode,Clean up invalid historical parameters; +- 7、extend data structure and adjust related table structure; +- 8、new created task defaults to a non-running state; +- 9、optimize update logic of GLUE mode task instance , The original update is based on the timeout value and now is updated according to the version number,version number plus one while source changed; + +### 6.12 version V1.6.1 New features [2017-03-25] +- 1、Rolling log; +- 2、reconstruct WebIDE interactive; +- 3、enhanced communication check,filter unnormal requests effectively; +- 4、enhanced permission check,Using dynamic login TOKEN(recommend instead of internal SSO); +- 5、optimize database configuration,solve garbled problem; + +### 6.13 version V1.6.2 New features [2017-04-25] +- 1、execution report:support view run time data in real time, such as task number, total schedule number, executor number etc., include schedule report , such as scheduled distribution graph on date, scheduled success distribution graph etc; +- 2、JobHandler support set return value for tasks, it is easy to control task execute result in task logic; +- 3、the problem could not view exception info when resource path include space or chinese word casused resource file could not be loaded; +- 4、optimize route policy:fix problems that Loop and LFU routing policy counters are no limit and first route is focused on the first machine; + +### 6.14 version V1.7.0 New features [2017-05-02] +- 1、script task:support develop and run script task by GLUE, include script type such as Shell、Python and Groovy; +- 2、add spring-boot type executor example project; +- 3、upgrade jetty to version 9.2; +- 4、task execute log remove log4j dependency, instead of self-realization,Thus eliminate the dependency on the log component; +- 5、executor remove GlueLoader dependency,instead of push mode,thus GLUE source code load no longer rely on JDBC; +- 6、get the project name when login and redirect, solve 404 problem when it is not deployed by the directory; + +### 6.15 version V1.7.1 New features [2017-05-08] +- 1、unified write and read code of execute log as UTF-8,solve log garbled problem under windows environment; +- 2、communication timeout period is limited to 10s,To avoid schedule thread is occupied under abnormal situation; +- 3、adjust executor , server stat, destroy and register logic; +- 4、optimize Jetty Server shutdown logic, repair port occupation caused by executor could not be closed normally and frequent printe c3p0 log probleam; +- 5、start child thread in JobHandler,support child thread print execute log and view by Rolling; +- 6、task log cleanup; +- 7、pop-up component is replaced by layer; +- 8、upgrade quartz to version 2.3.0; + +### 6.16 version V1.7.2 New features [2017-05-17] +- 1、block handle policy:the policy when schedule is too frequently and the executor it too late to handle, include multiple strategies:single machine serially execute(default)、discard subsequent schedule、override before schedule; +- 2、fail handle policy:handle policy when scheduled fail, include :failure alarm(default)、failed to retry; +- 3、The communication timeout is adjusted to 180s; +- 4、executor and database are completely decoupled,But the executor needs to configure schedule center cluster address。schedule center provides APIs for executor callbacks and heartbeat registration services,cancel jetty inner schedule center, heartbeat cycle is adjusted to 30s,heartbeat failure is triple heartbeat; +- 5、fix executor parameters lost bug when edit; +- 6、add task test Demo to make task logic test easier; + +### 6.17 version V1.8.0 New features [2017-07-17] +- 1、optimize update logic of task Cron,instead of rescheduleJob,at the same time preventing set cron repeatedly; +- 2、optimize API callback service failed status code,facilitate troubleshooting; +- 3、XxlJobLogger support multi-parameter; +- 4、route policy add "忙碌转移" mode:Perform idle detection in sequence,The first idle test successfully machine is selected as the target executor and trigger schedule; +- 5、reconstruct route policy code; +- 6、fix executor repeat registration problem; +- 7、Task thread will be destroyed after 30 times idle turn, reduce the inefficient thread consumption of low frequency tasks; +- 8、Executor task execution result batch callback so that reduce callback frequency to improve actuator performance; +- 9、cancle XML configuration of springboot executor project,instead of class configuration; +- 10、supports filter execute log based on running status; +- 11、optimize scheduling Center Task Registration Detection Logic; + +### 6.18 version V1.8.1 New features [2017-07-30] +- 1、slice broadcast task:When slice broadcast is selected as route policy in executor cluster, one task schedule will broadcast all executor node in cluster to trigger task execute in every executor, pass slice parameter at the same time, so we can develop slice task by slice parameters; +- 2、dynamic slice: break the task by the dimensions of executor, support dynamic extend executor cluster so that it can add slice number dynamically to do business process, In case of large amount of data process can significantly improve task processing capacity and speed; +- 3、executor JobHandler disables name conflicts; +- 4、executor cluster address list for natural sorting; +- 5、add test cases and optimize DAO layer code for Scheduling center; +- 6、schedule Center API service change to self-study RPC framework to u nify communication model; +- 7、add schedule center API service test Demo, convenient in dispatch center API extension and testing; +- 8、Task list page interaction optimization,The task list is automatically refreshed when the executor group is replaced,create new job defaults to locate current executor position; +- 9、access Token:To improve system security,it is used for safety check between schedule center and executor, communication allowed just when Both Access Token matched; +- 10、upgrade springboot version to 1.5.6.RELEASE of executor; +- 11、unify maven version dependency management; + +### 6.19 version V1.8.2 New features[Coding] +- 1,support configuring the HTTPS for executor callback URL; +- 2,Standardize project directory for extend multi executors; +- 3,add JFinal type executor sample project; + +### TODO LIST +- 1,Task privilege management:control privilege on executor, check privilege on core operations; +- 2,Task slice routing:using consistent Hash algorithm to calculate slice order as stable as possible, even if there is fluctuation in the registration machine will not cause large fluctuations in the order of slice. Currently using IP natural sorting can meet the demand,to be determined; +- 3,Failure retry optimization:The current failure to retry logic is execute the request logic once again after the scheduled request fails。The optimization point is retry for both scheduling and execution failures, retry a full schedule when retrying,This may lead schedule failure to an infinite loop,to be determined; +- 4,write file when callback failed,read the log when viewing the log,callback confirm after rebooting; +- 5,Task dependency,flow chart,child task + aggregation task,log of each node; +- 6,Scheduled task priority; +- 7,Remove quartz dependencies and rewrite scheduld module:insert the next execution record into delayqueue when add or resume task, schedule center cluster compete distributed lock,successful nodes bulk load expired delayqueue data and batch execution; +- 8,springboot and docker image,and push docker image to the central warehouse,further realize product out of the box; +- 9,globalization:schedule center interface and Official documents,add English version; +- 10,executor removal:notify schedule center and remove the corresponding execute node when executor is destroyed, improve the timeliness of executor state recognized; + +## 7. Other + +### 7.1 Contributing +Contributions are welcome! Open a pull request to fix a bug, or open an [Issue](https://github.com/xuxueli/xxl-job/issues/) to discuss a new feature or change. + +### 7.2 used records(record just for spread,Product is open source and free of charge) +Record for spread product and product is free and open source. +Welcome to [check in](https://github.com/xuxueli/xxl-job/issues/1 )on github. + +### 7.3 Copyright and License +This product is open source and free, and will continue to provide free community technical support. Individual or enterprise users are free to access and use. + +- Licensed under the GNU General Public License (GPL) v3. +- Copyright (c) 2015-present, xuxueli. + +--- +### Donate +No matter how much the amount is enough to express your thought, thank you very much :) [To donate](https://www.xuxueli.com/page/donate.html ) diff --git a/xxl-job-2.3.0/doc/XXL-JOB官方文档.md b/xxl-job-2.3.0/doc/XXL-JOB官方文档.md new file mode 100644 index 0000000..0fd435d --- /dev/null +++ b/xxl-job-2.3.0/doc/XXL-JOB官方文档.md @@ -0,0 +1,2203 @@ +## 《分布式任务调度平台XXL-JOB》 + +[![Actions Status](https://github.com/xuxueli/xxl-job/workflows/Java%20CI/badge.svg)](https://github.com/xuxueli/xxl-job/actions) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xuxueli/xxl-job/) +[![GitHub release](https://img.shields.io/github/release/xuxueli/xxl-job.svg)](https://github.com/xuxueli/xxl-job/releases) +[![GitHub stars](https://img.shields.io/github/stars/xuxueli/xxl-job)](https://github.com/xuxueli/xxl-job/) +[![Docker Status](https://img.shields.io/docker/pulls/xuxueli/xxl-job-admin)](https://hub.docker.com/r/xuxueli/xxl-job-admin/) +[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0.html) +[![donate](https://img.shields.io/badge/%24-donate-ff69b4.svg?style=flat)](https://www.xuxueli.com/page/donate.html) + +[TOCM] + +[TOC] + +## 一、简介 + +### 1.1 概述 +XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 + +### 1.2 社区交流 +- [社区交流](https://www.xuxueli.com/page/community.html) + +### 1.3 特性 +- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手; +- 2、动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效; +- 3、调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA; +- 4、执行器HA(分布式):任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA; +- 5、注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址; +- 6、弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务; +- 7、触发策略:提供丰富的任务触发策略,包括:Cron触发、固定间隔触发、固定延时触发、API(事件)触发、人工触发、父子任务触发; +- 8、调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等; +- 9、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度; +- 10、任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务; +- 11、任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试; +- 12、任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式; +- 13、路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等; +- 14、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务; +- 15、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。 +- 16、故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。 +- 17、任务进度监控:支持实时监控任务进度; +- 18、Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志; +- 19、GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。支持30个版本的历史版本回溯。 +- 20、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS、PHP、PowerShell等类型脚本; +- 21、命令行任务:原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可; +- 22、任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔; +- 23、一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行; +- 24、自定义任务参数:支持在线配置调度任务入参,即时生效; +- 25、调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞; +- 26、数据加密:调度中心和执行器之间的通讯进行数据加密,提升调度信息安全性; +- 27、邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件; +- 28、推送maven中央仓库: 将会把最新稳定版推送到maven中央仓库, 方便用户接入和使用; +- 29、运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等; +- 30、全异步:任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行; +- 31、跨语言:调度中心与执行器提供语言无关的 RESTful API 服务,第三方任意语言可据此对接调度中心或者实现执行器。除此之外,还提供了 “多任务模式”和“httpJobHandler”等其他跨语言方案; +- 32、国际化:调度中心支持国际化设置,提供中文、英文两种可选语言,默认为中文; +- 33、容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用; +- 34、线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性; +- 35、用户管理:支持在线管理系统用户,存在管理员、普通用户两种角色; +- 36、权限控制:执行器维度进行权限控制,管理员拥有全量权限,普通用户需要分配执行器权限后才允许相关操作; + +### 1.4 发展 +于2015年中,我在github上创建XXL-JOB项目仓库并提交第一个commit,随之进行系统结构设计,UI选型,交互设计…… + +于2015-11月,XXL-JOB终于RELEASE了第一个大版本V1.0, 随后我将之发布到OSCHINA,XXL-JOB在OSCHINA上获得了@红薯的热门推荐,同期分别达到了OSCHINA的“热门动弹”排行第一和git.oschina的开源软件月热度排行第一,在此特别感谢红薯,感谢大家的关注和支持。 + +于2015-12月,我将XXL-JOB发表到我司内部知识库,并且得到内部同事认可。 + +于2016-01月,我司展开XXL-JOB的内部接入和定制工作,在此感谢袁某和尹某两位同事的贡献,同时也感谢内部其他给与关注与支持的同事。 + +于2017-05-13,在上海举办的 "[第62期开源中国源创会](https://www.oschina.net/event/2236961)" 的 "放码过来" 环节,我登台对XXL-JOB做了演讲,台下五百位在场观众反响热烈([图文回顾](https://www.oschina.net/question/2686220_2242120) )。 + +于2017-10-22,又拍云 Open Talk 联合 Spring Cloud 中国社区举办的 "[进击的微服务实战派上海站](https://opentalk.upyun.com/303.html)",我登台对XXL-JOB做了演讲,现场观众反响热烈并在会后与XXL-JOB用户热烈讨论交流。 + +于2017-12-11,XXL-JOB有幸参会《[InfoQ ArchSummit全球架构师峰会](http://bj2017.archsummit.com/)》,并被拍拍贷架构总监"杨波老师"在专题 "[微服务原理、基础架构和开源实践](http://bj2017.archsummit.com/training/2)" 中现场介绍。 + +于2017-12-18,XXL-JOB参与"[2017年度最受欢迎中国开源软件](http://www.oschina.net/project/top_cn_2017?sort=1)"评比,在当时已录入的约九千个国产开源项目中角逐,最终进入了前30强。 + +于2018-01-15,XXL-JOB参与"[2017码云最火开源项目](https://www.oschina.net/news/92438/2017-mayun-top-50)"评比,在当时已录入的约六千五百个码云项目中角逐,最终进去了前20强。 + +于2018-04-14,iTechPlus在上海举办的 "[2018互联网开发者大会](http://www.itdks.com/eventlist/detail/2065)",我登台对XXL-JOB做了演讲,现场观众反响热烈并在会后与XXL-JOB用户热烈讨论交流。 + +于2018-05-27,在上海举办的 "[第75期开源中国源创会](https://www.oschina.net/event/2278742)" 的 "架构" 主题专场,我登台进行“基础架构与中间件图谱”主题演讲,台下上千位在场观众反响热烈([图文回顾](https://www.oschina.net/question/3802184_2280606) )。 + +于2018-12-05,XXL-JOB参与"[2018年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2018?sort=1)"评比,在当时已录入的一万多个开源项目中角逐,最终排名第19名。 + +于2019-12-10,XXL-JOB参与"[2019年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2019)"评比,在当时已录入的一万多个开源项目中角逐,最终排名"开发框架和基础组件类"第9名。 + +于2020-11-16,XXL-JOB参与"[2020年度最受欢迎中国开源软件](https://www.oschina.net/project/top_cn_2020)"评比,在当时已录入的一万多个开源项目中角逐,最终排名"开发框架和基础组件类"第8名。 + +> 我司大众点评目前已接入XXL-JOB,内部别名《Ferrari》(Ferrari基于XXL-JOB的V1.1版本定制而成,新接入应用推荐升级最新版本)。 +据最新统计, 自2016-01-21接入至2017-12-01期间,该系统已调度约100万次,表现优异。新接入应用推荐使用最新版本,因为经过数十个版本的更新,系统的任务模型、UI交互模型以及底层调度通讯模型都有了较大的优化和提升,核心功能更加稳定高效。 + +至今,XXL-JOB已接入多家公司的线上产品线,接入场景如电商业务,O2O业务和大数据作业等,截止最新统计时间为止,XXL-JOB已接入的公司包括不限于: + + - 1、大众点评【美团点评】 + - 2、山东学而网络科技有限公司; + - 3、安徽慧通互联科技有限公司; + - 4、人人聚财金服; + - 5、上海棠棣信息科技股份有限公司 + - 6、运满满【运满满】 + - 7、米其林 (中国区)【米其林】 + - 8、妈妈联盟 + - 9、九樱天下(北京)信息技术有限公司 + - 10、万普拉斯科技有限公司【一加手机】 + - 11、上海亿保健康管理有限公司 + - 12、海尔馨厨【海尔】 + - 13、河南大红包电子商务有限公司 + - 14、成都顺点科技有限公司 + - 15、深圳市怡亚通 + - 16、深圳麦亚信科技股份有限公司 + - 17、上海博莹科技信息技术有限公司 + - 18、中国平安科技有限公司【中国平安】 + - 19、杭州知时信息科技有限公司 + - 20、博莹科技(上海)有限公司 + - 21、成都依能股份有限责任公司 + - 22、湖南高阳通联信息技术有限公司 + - 23、深圳市邦德文化发展有限公司 + - 24、福建阿思可网络教育有限公司 + - 25、优信二手车【优信】 + - 26、上海悠游堂投资发展股份有限公司【悠游堂】 + - 27、北京粉笔蓝天科技有限公司 + - 28、中秀科技(无锡)有限公司 + - 29、武汉空心科技有限公司 + - 30、北京蚂蚁风暴科技有限公司 + - 31、四川互宜达科技有限公司 + - 32、钱包行云(北京)科技有限公司 + - 33、重庆欣才集团 + - 34、咪咕互动娱乐有限公司【中国移动】 + - 35、北京诺亦腾科技有限公司 + - 36、增长引擎(北京)信息技术有限公司 + - 37、北京英贝思科技有限公司 + - 38、刚泰集团 + - 39、深圳泰久信息系统股份有限公司 + - 40、随行付支付有限公司 + - 41、广州瀚农网络科技有限公司 + - 42、享点科技有限公司 + - 43、杭州比智科技有限公司 + - 44、圳临界线网络科技有限公司 + - 45、广州知识圈网络科技有限公司 + - 46、国誉商业上海有限公司 + - 47、海尔消费金融有限公司,嗨付、够花【海尔】 + - 48、广州巴图鲁信息科技有限公司 + - 49、深圳市鹏海运电子数据交换有限公司 + - 50、深圳市亚飞电子商务有限公司 + - 51、上海趣医网络有限公司 + - 52、聚金资本 + - 53、北京父母邦网络科技有限公司 + - 54、中山元赫软件科技有限公司 + - 55、中商惠民(北京)电子商务有限公司 + - 56、凯京集团 + - 57、华夏票联(北京)科技有限公司 + - 58、拍拍贷【拍拍贷】 + - 59、北京尚德机构在线教育有限公司 + - 60、任子行股份有限公司 + - 61、北京时态电子商务有限公司 + - 62、深圳卷皮网络科技有限公司 + - 63、北京安博通科技股份有限公司 + - 64、未来无线网 + - 65、厦门瓷禧网络有限公司 + - 66、北京递蓝科软件股份有限公司 + - 67、郑州创海软件科技公司 + - 68、北京国槐信息科技有限公司 + - 69、浪潮软件集团 + - 70、多立恒(北京)信息技术有限公司 + - 71、广州极迅客信息科技有限公司 + - 72、赫基(中国)集团股份有限公司 + - 73、海投汇 + - 74、上海润益创业孵化器管理股份有限公司 + - 75、汉纳森(厦门)数据股份有限公司 + - 76、安信信托 + - 77、岚儒财富 + - 78、捷道软件 + - 79、湖北享七网络科技有限公司 + - 80、湖南创发科技责任有限公司 + - 81、深圳小安时代互联网金融服务有限公司 + - 82、湖北享七网络科技有限公司 + - 83、钱包行云(北京)科技有限公司 + - 84、360金融【360】 + - 85、易企秀 + - 86、摩贝(上海)生物科技有限公司 + - 87、广东芯智慧科技有限公司 + - 88、联想集团【联想】 + - 89、怪兽充电 + - 90、行圆汽车 + - 91、深圳店店通科技邮箱公司 + - 92、京东【京东】 + - 93、米庄理财 + - 94、咖啡易融 + - 95、梧桐诚选 + - 96、恒大地产【恒大】 + - 97、昆明龙慧 + - 98、上海涩瑶软件 + - 99、易信【网易】 + - 100、铜板街 + - 101、杭州云若网络科技有限公司 + - 102、特百惠(中国)有限公司 + - 103、常山众卡运力供应链管理有限公司 + - 104、深圳立创电子商务有限公司 + - 105、杭州智诺科技股份有限公司 + - 106、北京云漾信息科技有限公司 + - 107、深圳市多银科技有限公司 + - 108、亲宝宝 + - 109、上海博卡软件科技有限公司 + - 110、智慧树在线教育平台 + - 111、米族金融 + - 112、北京辰森世纪 + - 113、云南滇医通 + - 114、广州市分领网络科技有限责任公司 + - 115、浙江微能科技有限公司 + - 116、上海馨飞电子商务有限公司 + - 117、上海宝尊电子商务有限公司 + - 118、直客通科技技术有限公司 + - 119、科度科技有限公司 + - 120、上海数慧系统技术有限公司 + - 121、我的医药网 + - 122、多粉平台 + - 123、铁甲二手机 + - 124、上海海新得数据技术有限公司 + - 125、深圳市珍爱网信息技术有限公司【珍爱网】 + - 126、小蜜蜂 + - 127、吉荣数科技 + - 128、上海恺域信息科技有限公司 + - 129、广州荔支网络有限公司【荔枝FM】 + - 130、杭州闪宝科技有限公司 + - 131、北京互联新网科技发展有限公司 + - 132、誉道科技 + - 133、山西兆盛房地产开发有限公司 + - 134、北京蓝睿通达科技有限公司 + - 135、月亮小屋(中国)有限公司【蓝月亮】 + - 136、青岛国瑞信息技术有限公司 + - 137、博雅云计算(北京)有限公司 + - 138、华泰证券香港子公司 + - 139、杭州东方通信软件技术有限公司 + - 140、武汉博晟安全技术股份有限公司 + - 141、深圳市六度人和科技有限公司 + - 142、杭州趣维科技有限公司(小影) + - 143、宁波单车侠之家科技有限公司【单车侠】 + - 144、丁丁云康信息科技(北京)有限公司 + - 145、云钱袋 + - 146、南京中兴力维 + - 147、上海矽昌通信技术有限公司 + - 148、深圳萨科科技 + - 149、中通服创立科技有限责任公司 + - 150、深圳市对庄科技有限公司 + - 151、上证所信息网络有限公司 + - 152、杭州火烧云科技有限公司【婚礼纪】 + - 153、天津青芒果科技有限公司【芒果头条】 + - 154、长飞光纤光缆股份有限公司 + - 155、世纪凯歌(北京)医疗科技有限公司 + - 156、浙江霖梓控股有限公司 + - 157、江西腾飞网络技术有限公司 + - 158、安迅物流有限公司 + - 159、肉联网 + - 160、北京北广梯影广告传媒有限公司 + - 161、上海数慧系统技术有限公司 + - 162、大志天成 + - 163、上海云鹊医 + - 164、上海云鹊医 + - 165、墨迹天气【墨迹天气】 + - 166、上海逸橙信息科技有限公司 + - 167、沅朋物联 + - 168、杭州恒生云融网络科技有限公司 + - 169、绿米联创 + - 170、重庆易宠科技有限公司 + - 171、安徽引航科技有限公司(乐职网) + - 172、上海数联医信企业发展有限公司 + - 173、良彬建材 + - 174、杭州求是同创网络科技有限公司 + - 175、荷马国际 + - 176、点雇网 + - 177、深圳市华星光电技术有限公司 + - 178、厦门神州鹰软件科技有限公司 + - 179、深圳市招商信诺人寿保险有限公司 + - 180、上海好屋网信息技术有限公司 + - 181、海信集团【海信】 + - 182、信凌可信息科技(上海)有限公司 + - 183、长春天成科技发展有限公司 + - 184、用友金融信息技术股份有限公司【用友】 + - 185、北京咖啡易融有限公司 + - 186、国投瑞银基金管理有限公司 + - 187、晋松(上海)网络信息技术有限公司 + - 188、深圳市随手科技有限公司【随手记】 + - 189、深圳水务科技有限公司 + - 190、易企秀【易企秀】 + - 191、北京磁云科技 + - 192、南京蜂泰互联网科技有限公司 + - 193、章鱼直播 + - 194、奖多多科技 + - 195、天津市神州商龙科技股份有限公司 + - 196、岩心科技 + - 197、车码科技(北京)有限公司 + - 198、贵阳市投资控股集团 + - 199、康旗股份 + - 200、龙腾出行 + - 201、杭州华量软件 + - 202、合肥顶岭医疗科技有限公司 + - 203、重庆表达式科技有限公司 + - 204、上海米道信息科技有限公司 + - 205、北京益友会科技有限公司 + - 206、北京融贯电子商务有限公司 + - 207、中国外汇交易中心 + - 208、中国外运股份有限公司 + - 209、中国上海晓圈教育科技有限公司 + - 210、普联软件股份有限公司 + - 211、北京科蓝软件股份有限公司 + - 212、江苏斯诺物联科技有限公司 + - 213、北京搜狐-狐友【搜狐】 + - 214、新大陆网商金融 + - 215、山东神码中税信息科技有限公司 + - 216、河南汇顺网络科技有限公司 + - 217、北京华夏思源科技发展有限公司 + - 218、上海东普信息科技有限公司 + - 219、上海鸣勃网络科技有限公司 + - 220、广东学苑教育发展有限公司 + - 221、深圳强时科技有限公司 + - 222、上海云砺信息科技有限公司 + - 223、重庆愉客行网络有限公司 + - 224、数云 + - 225、国家电网运检部 + - 226、杭州找趣 + - 227、浩鲸云计算科技股份有限公司 + - 228、科大讯飞【科大讯飞】 + - 229、杭州行装网络科技有限公司 + - 230、即有分期金融 + - 231、深圳法司德信息科技有限公司 + - 232、上海博复信息科技有限公司 + - 233、杭州云嘉云计算有限公司 + - 234、有家民宿(有家美宿) + - 235、北京赢销通软件技术有限公司 + - 236、浙江聚有财金融服务外包有限公司 + - 237、易族智汇(北京)科技有限公司 + - 238、合肥顶岭医疗科技开发有限公司 + - 239、车船宝(深圳)旭珩科技有限公司) + - 240、广州富力地产有限公司 + - 241、氢课(上海)教育科技有限公司 + - 242、武汉氪细胞网络技术有限公司 + - 243、杭州有云科技有限公司 + - 244、上海仙豆智能机器人有限公司 + - 245、拉卡拉支付股份有限公司【拉卡拉】 + - 246、虎彩印艺股份有限公司 + - 247、北京数微科技有限公司 + - 248、广东智瑞科技有限公司 + - 249、找钢网 + - 250、九机网 + - 251、杭州跑跑网络科技有限公司 + - 252、深圳未来云集 + - 253、杭州每日给力科技有限公司 + - 254、上海齐犇信息科技有限公司 + - 255、滴滴出行【滴滴】 + - 256、合肥云诊信息科技有限公司 + - 257、云知声智能科技股份有限公司 + - 258、南京坦道科技有限公司 + - 259、爱乐优(二手平台) + - 260、猫眼电影(私有化部署)【猫眼电影】 + - 261、美团大象(私有化部署)【美团大象】 + - 262、作业帮教育科技(北京)有限公司【作业帮】 + - 263、北京小年糕互联网技术有限公司 + - 264、山东矩阵软件工程股份有限公司 + - 265、陕西国驿软件科技有限公司 + - 266、君开信息科技 + - 267、村鸟网络科技有限责任公司 + - 268、云南国际信托有限公司 + - 269、金智教育 + - 270、珠海市筑巢科技有限公司 + - 271、上海百胜软件股份有限公司 + - 272、深圳市科盾科技有限公司 + - 273、哈啰出行【哈啰】 + - 274、途虎养车【途虎】 + - 275、卡思优派人力资源集团 + - 276、南京观为智慧软件科技有限公司 + - 277、杭州城市大脑科技有限公司 + - 278、猿辅导【猿辅导】 + - 279、洛阳健创网络科技有限公司 + - 280、魔力耳朵 + - 281、亿阳信通 + - 282、上海招鲤科技有限公司 + - 283、四川商旅无忧科技服务有限公司 + - 284、UU跑腿 + - 285、北京老虎证券【老虎证券】 + - 286、悠活省吧(北京)网络科技有限公司 + - 287、F5未来商店 + - 288、深圳环阳通信息技术有限公司 + - 289、遠傳電信 + - 290、作业帮(北京)教育科技有限公司【作业帮】 + - 291、成都科鸿智信科技有限公司 + - 292、北京木屋时代科技有限公司 + - 293、大学通(哈尔滨)科技有限责任公司 + - 294、浙江华坤道威数据科技有限公司 + - 295、吉祥航空【吉祥航空】 + - 296、南京圆周网络科技有限公司 + - 297、广州市洋葱omall电子商务 + - 298、天津联物科技有限公司 + - 299、跑哪儿科技(北京)有限公司 + - 300、深圳市美西西餐饮有限公司(喜茶) + - 301、平安不动产有限公司【平安】 + - 302、江苏中海昇物联科技有限公司 + - 303、湖南牙医帮科技有限公司 + - 304、重庆民航凯亚信息技术有限公司(易通航) + - 305、递易(上海)智能科技有限公司 + - 306、亚朵 + - 307、浙江新课堂教育股份有限公司 + - 308、北京蜂创科技有限公司 + - 309、德一智慧城市信息系统有限公司 + - 310、北京翼点科技有限公司 + - 311、湖南智数新维度信息科技有限公司 + - 312、北京玖扬博文文化发展有限公司 + - 313、上海宇珩信息科技有限公司 + - 314、全景智联(武汉)科技有限公司 + - 315、天津易客满国际物流有限公司 + - 316、南京爱福路汽车科技有限公司 + - 317、我房旅居集团 + - 318、湛江亲邻科技有限公司 + - 319、深圳市姜科网络有限公司 + - 320、青岛日日顺物流有限公司 + - 321、南京太川信息技术有限公司 + - 322、美图之家科技优先公司【美图】 + - 323、南京太川信息技术有限公司 + - 324、众薪科技(北京)有限公司 + - 325、武汉安安物联科技有限公司 + - 326、北京智客朗道网络科技有限公司 + - 327、深圳市超级猩猩健身管理管理有限公司 + - 328、重庆达志科技有限公司 + - 329、上海享评信息科技有限公司 + - 330、薪得付信息科技 + - 331、跟谁学 + - 332、中道(苏州)旅游网络科技有限公司 + - 333、广州小卫科技有限公司 + - 334、上海非码网络科技有限公司 + - 335、途家网网络技术(北京)有限公司【途家】 + - 336、广州辉凡信息科技有限公司 + - 337、天维尔信息科技股份有限公司 + - 338、上海极豆科技有限公司 + - 339、苏州触达信息技术有限公司 + - 340、北京热云科技有限公司 + - 341、中智企服(北京)科技有限公司 + - 342、易联云计算(杭州)有限责任公司 + - 343、青岛航空股份有限公司【青岛航空】 + - 344、山西博睿通科技有限公司 + - 345、网易杭州网络有限公司【网易】 + - 346、北京果果乐学科技有限公司 + - 347、百望股份有限公司 + - 348、中保金服(深圳)科技有限公司 + - 349、天津运友物流科技股份有限公司 + - 350、广东创能科技股份有限公司 + - 351、上海倚博信息科技有限公司 + - 352、深圳百果园实业(集团)股份有限公司 + - 353、广州细刻网络科技有限公司 + - 354、武汉鸿业众创科技有限公司 + - 355、金锡科技(广州)有限公司 + - 356、易瑞国际电子商务有限公司 + - 357、奇点云 + - 358、中视信息科技有限公司 + - 359、开源项目:datax-web + - 360、云知声智能科技股份有限公司 + - 361、开源项目:bboss + - 362、成都深驾科技有限公司 + - 363、FunPlus【趣加】 + - 364、杭州创匠信科技有限公司 + - 365、龙匠(北京)科技发展有限公司 + - 366、广州一链通互联网科技有限公司 + - 367、上海星艾网络科技有限公司 + - 368、虎博网络技术(上海)有限公司 + - 369、青岛优米信息技术有限公司 + - 370、八维通科技有限公司 + - 371、烟台合享智星数据科技有限公司 + - 372、东吴证券股份有限公司 + - 373、中通云仓股份有限公司【中通】 + - 374、北京加菲猫科技有限公司 + - 375、北京匠心演绎科技有限公司 + - 376、宝贝走天下 + - 377、厦门众库科技有限公司 + - 378、海通证券数据中心 + - 389、湖南快乐通宝小额贷款有限公司 + - 380、浙江大华技术股份有限公司 + - 381、杭州魔筷科技有限公司 + - 382、青岛掌讯通区块链科技有限公司 + - 383、新大陆金融科技 + - 384、常州玺拓软件科技有限公司 + - 385、北京正保网格教育科技有限公司 + - 386、统一企业(中国)投资有限公司【统一】 + - 387、微革网络科技有限公司 + - 388、杭州融易算科技有限公司 + - 399、青岛上啥班网络科技有限公司 + - 390、京东酒世界 + - 391、杭州爱博仕科技有限公司 + - 392、五星金服控股有限公司 + - 393、福建乐摩物联科技有限公司 + - 394、百炼智能科技有限公司 + - 395、山东能源数智云科技有限公司 + - 396、招商局能源运输股份有限公司 + - 397、三一集团【三一】 + - 398、东巴文(深圳)健康管理有限公司 + - 399、索易软件 + - 400、深圳市宁远科技有限公司 + - 401、熙牛医疗 + - 402、南京智鹤电子科技有限公司 + - 403、嘀嗒出行【嘀嗒出行】 + - 404、广州虎牙信息科技有限公司【虎牙】 + - 405、广州欧莱雅百库网络科技有限公司【欧莱雅】 + - 406、微微科技有限公司 + - 407、我爱我家房地产经纪有限公司【我爱我家】 + - 408、九号发现 + - 409、薪人薪事 + - 410、武汉氪细胞网络技术有限公司 + - 411、广州市斯凯奇商业有限公司 + - 412、微淼商学院 + - 413、杭州车盛科技有限公司 + - 414、深兰科技(上海)有限公司 + - 415、安徽中科美络信息技术有限公司 + - 416、比亚迪汽车工业有限公司【比亚迪】 + - 417、湖南小桔信息技术有限公司 + - 418、安徽科大国创软件科技有限公司 + - 419、克而瑞 + - 420、陕西云基华海信息技术有限公司 + - 421、安徽深宁科技有限公司 + - 422、广东康爱多数字健康有限公司 + - 423、嘉里电子商务 + - 424、上海时代光华教育发展有限公司 + - 425、CityDo + - 426、上海禹知信息科技有限公司 + - 427、广东智瑞科技有限公司 + - 428、西安爱铭网络科技有限公司 + - 429、心医国际数字医疗系统(大连)有限公司 + - 430、乐其电商 + - 431、锐达科技 + - 432、天津长城滨银汽车金融有限公司 + - 433、代码网 + - 434、东莞市东城乔伦软件开发工作室 + - 435、浙江百应科技有限公司 + - 436、上海力爱帝信息技术有限公司(Red E) + - 437、云徙科技有限公司 + - 438、北京康智乐思网络科技有限公司【大姨吗APP】 + - 439、安徽开元瞬视科技有限公司 + - 440、立方 + - 441、厦门纵行科技 + - 442、乐山-菲尼克斯半导体有限公司 + - 443、武汉光谷联合集团有限公司 + - 444、上海金仕达软件科技有限公司 + - 445、深圳易世通达科技有限公司 + - 446、爱动超越人工智能科技(北京)有限责任公司 + - …… + +> 更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。 + +欢迎大家的关注和使用,XXL-JOB也将拥抱变化,持续发展。 + + +### 1.5 下载 + +#### 文档地址 + +- [中文文档](https://www.xuxueli.com/xxl-job/) +- [English Documentation](https://www.xuxueli.com/xxl-job/en/) + +#### 源码仓库地址 + +源码仓库地址 | Release Download +--- | --- +[https://github.com/xuxueli/xxl-job](https://github.com/xuxueli/xxl-job) | [Download](https://github.com/xuxueli/xxl-job/releases) +[http://gitee.com/xuxueli0323/xxl-job](http://gitee.com/xuxueli0323/xxl-job) | [Download](http://gitee.com/xuxueli0323/xxl-job/releases) + + +#### 中央仓库地址 + +``` + + + com.xuxueli + xxl-job-core + ${最新稳定版本} + +``` + + +### 1.6 环境 +- Maven3+ +- Jdk1.8+ +- Mysql5.7+ + + +## 二、快速入门 + +### 2.1 初始化“调度数据库” +请下载项目源码并解压,获取 "调度数据库初始化SQL脚本" 并执行即可。 + +"调度数据库初始化SQL脚本" 位置为: + + /xxl-job/doc/db/tables_xxl_job.sql + +调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例; + +如果mysql做主从,调度中心集群节点务必强制走主库; + +### 2.2 编译源码 +解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下: + + xxl-job-admin:调度中心 + xxl-job-core:公共依赖 + xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器) + :xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式; + :xxl-job-executor-sample-frameless:无框架版本; + + +### 2.3 配置部署“调度中心” + + 调度中心项目:xxl-job-admin + 作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。 + +#### 步骤一:调度中心配置: +调度中心配置文件地址: + + /xxl-job/xxl-job-admin/src/main/resources/application.properties + + +调度中心配置内容说明: + + ### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致 + spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + spring.datasource.username=root + spring.datasource.password=root_pwd + spring.datasource.driver-class-name=com.mysql.jdbc.Driver + + ### 报警邮箱 + spring.mail.host=smtp.qq.com + spring.mail.port=25 + spring.mail.username=xxx@qq.com + spring.mail.password=xxx + spring.mail.properties.mail.smtp.auth=true + spring.mail.properties.mail.smtp.starttls.enable=true + spring.mail.properties.mail.smtp.starttls.required=true + spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory + + ### 调度中心通讯TOKEN [选填]:非空时启用; + xxl.job.accessToken= + + ### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文; + xxl.job.i18n=zh_CN + + ## 调度线程池最大线程配置【必填】 + xxl.job.triggerpool.fast.max=200 + xxl.job.triggerpool.slow.max=100 + + ### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能; + xxl.job.logretentiondays=30 + + + +#### 步骤二:部署项目: +如果已经正确进行上述配置,可将项目编译打包部署。 + +调度中心访问地址:http://localhost:8080/xxl-job-admin (该地址执行器将会使用到,作为回调地址) + +默认登录账号 "admin/123456", 登录后运行界面如下图所示。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_6yC0.png "在这里输入图片标题") + +至此“调度中心”项目已经部署成功。 + +#### 步骤三:调度中心集群(可选): +调度中心支持集群部署,提升调度系统容灾和可用性。 + +调度中心集群部署时,几点要求和建议: +- DB配置保持一致; +- 集群机器时钟保持一致(单机集群忽视); +- 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。 + + +#### 其他:Docker 镜像方式搭建调度中心: + +- 下载镜像 + +``` +// Docker地址:https://hub.docker.com/r/xuxueli/xxl-job-admin/ (建议指定版本号) +docker pull xuxueli/xxl-job-admin +``` + +- 创建容器并运行 + +``` +docker run -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:{指定版本} + +/** +* 如需自定义 mysql 等配置,可通过 "-e PARAMS" 指定,参数格式 PARAMS="--key=value --key2=value2" ; +* 配置项参考文件:/xxl-job/xxl-job-admin/src/main/resources/application.properties +* 如需自定义 JVM内存参数 等配置,可通过 "-e JAVA_OPTS" 指定,参数格式 JAVA_OPTS="-Xmx512m" ; +*/ +docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai" -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:{指定版本} +``` + + +### 2.4 配置部署“执行器项目” + + “执行器”项目:xxl-job-executor-sample-springboot (提供多种版本执行器供选择,现以 springboot 版本为例,可直接使用,也可以参考其并将现有项目改造成执行器) + 作用:负责接收“调度中心”的调度并执行;可直接部署执行器,也可以将执行器集成到现有业务项目中。 + +#### 步骤一:maven依赖 +确认pom文件中引入了 "xxl-job-core" 的maven依赖; + +#### 步骤二:执行器配置 +执行器配置,配置文件地址: + + /xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties + +执行器配置,配置内容说明: + + ### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; + xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin + + ### 执行器通讯TOKEN [选填]:非空时启用; + xxl.job.accessToken= + + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + xxl.job.executor.appname=xxl-job-executor-sample + ### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。 + xxl.job.executor.address= + ### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; + xxl.job.executor.ip= + ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + xxl.job.executor.port=9999 + ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler + ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; + xxl.job.executor.logretentiondays=30 + + +#### 步骤三:执行器组件配置 + +执行器组件,配置文件地址: + + /xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java + +执行器组件,配置内容说明: + +``` +@Bean +public XxlJobSpringExecutor xxlJobExecutor() { + logger.info(">>>>>>>>>>> xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAppname(appname); + xxlJobSpringExecutor.setIp(ip); + xxlJobSpringExecutor.setPort(port); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setLogPath(logPath); + xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); + + return xxlJobSpringExecutor; +} +``` + +#### 步骤四:部署执行器项目: +如果已经正确进行上述配置,可将执行器项目编译打部署,系统提供多种执行器Sample示例项目,选择其中一个即可,各自的部署方式如下。 + + xxl-job-executor-sample-springboot:项目编译打包成springboot类型的可执行JAR包,命令启动即可; + xxl-job-executor-sample-frameless:项目编译打包成JAR包,命令启动即可; + + +至此“执行器”项目已经部署结束。 + +#### 步骤五:执行器集群(可选): +执行器支持集群部署,提升调度系统可用性,同时提升任务处理能力。 + +执行器集群部署时,几点要求和建议: +- 执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作。 +- 同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表。 + + +### 2.5 开发第一个任务“Hello World” +本示例以新建一个 “GLUE模式(Java)” 运行模式的任务为例。更多有关任务的详细配置,请查看“章节三:任务详解”。 +( “GLUE模式(Java)”的执行代码托管到调度中心在线维护,相比“Bean模式任务”需要在执行器项目开发部署上线,更加简便轻量) + +> 前提:请确认“调度中心”和“执行器”项目已经成功部署并启动; + +#### 步骤一:新建任务: +登录调度中心,点击下图所示“新建任务”按钮,新建示例任务。然后,参考下面截图中任务的参数配置,点击保存。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_o8HQ.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png "在这里输入图片标题") + + +#### 步骤二:“GLUE模式(Java)” 任务开发: +请点击任务右侧 “GLUE” 按钮,进入 “GLUE编辑器开发界面” ,见下图。“GLUE模式(Java)” 运行模式的任务默认已经初始化了示例任务代码,即打印Hello World。 +( “GLUE模式(Java)” 运行模式的任务实际上是一段继承自IJobHandler的Java类代码,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务,详细介绍请查看第三章节) + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Fgql.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_dNUJ.png "在这里输入图片标题") + +#### 步骤三:触发执行: +请点击任务右侧 “执行” 按钮,可手动触发一次任务执行(通常情况下,通过配置Cron表达式进行任务调度触发)。 + +#### 步骤四:查看日志: +请点击任务右侧 “日志” 按钮,可前往任务日志界面查看任务日志。 +在任务日志界面中,可查看该任务的历史调度记录以及每一次调度的任务调度信息、执行参数和执行信息。运行中的任务点击右侧的“执行日志”按钮,可进入日志控制台查看实时执行日志。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_inc8.png "在这里输入图片标题") + +在日志控制台,可以Rolling方式实时查看任务在执行器一侧运行输出的日志信息,实时监控任务进度; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_eYrv.png "在这里输入图片标题") + +## 三、任务详解 + +### 配置属性详细说明: + + 基础配置: + - 执行器:任务的绑定的执行器,任务触发调度时将会自动发现注册成功的执行器, 实现任务自动发现功能; 另一方面也可以方便的进行任务分组。每个任务必须绑定一个执行器, 可在 "执行器管理" 进行设置; + - 任务描述:任务的描述信息,便于任务管理; + - 负责人:任务的负责人; + - 报警邮件:任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔; + + 触发配置: + - 调度类型: + 无:该类型不会主动触发调度; + CRON:该类型将会通过CRON,触发任务调度; + 固定速度:该类型将会以固定速度,触发任务调度;按照固定的间隔时间,周期性触发; + 固定延迟:该类型将会以固定延迟,触发任务调度;按照固定的延迟时间,从上次调度结束后开始计算延迟时间,到达延迟时间后触发下次调度; + - CRON:触发任务执行的Cron表达式; + - 固定速度:固件速度的时间间隔,单位为秒; + - 固定延迟:固件延迟的时间间隔,单位为秒; + + 任务配置: + - 运行模式: + BEAN模式:任务以JobHandler方式维护在执行器端;需要结合 "JobHandler" 属性匹配执行器中任务; + GLUE模式(Java):任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并 "groovy" 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务; + GLUE模式(Shell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "shell" 脚本; + GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "python" 脚本; + GLUE模式(PHP):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "php" 脚本; + GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "nodejs" 脚本; + GLUE模式(PowerShell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "PowerShell" 脚本; + - JobHandler:运行模式为 "BEAN模式" 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值; + - 执行参数:任务执行所需的参数; + + 高级配置: + - 路由策略:当执行器集群部署时,提供丰富的路由策略,包括; + FIRST(第一个):固定选择第一个机器; + LAST(最后一个):固定选择最后一个机器; + ROUND(轮询):; + RANDOM(随机):随机选择在线的机器; + CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。 + LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举; + LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举; + FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度; + BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度; + SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务; + - 子任务:每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。 + - 调度过期策略: + - 忽略:调度过期后,忽略过期的任务,从当前时间开始重新计算下次触发时间; + - 立即执行一次:调度过期后,立即执行一次,并从当前时间开始重新计算下次触发时间; + - 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略; + 单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行; + 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败; + 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务; + - 任务超时时间:支持自定义任务超时时间,任务运行超时将会主动中断任务; + - 失败重试次数;支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试; + + + + + +### 3.1 BEAN模式(类形式) + +Bean模式任务,支持基于类的开发方式,每个任务对应一个Java类。 + +- 优点:不限制项目环境,兼容性好。即使是无框架项目,如main方法直接启动的项目也可以提供支持,可以参考示例项目 "xxl-job-executor-sample-frameless"; +- 缺点: + - 每个任务需要占用一个Java类,造成类的浪费; + - 不支持自动扫描任务并注入到执行器容器,需要手动注入。 + +#### 步骤一:执行器项目中,开发Job类: + + 1、开发一个继承自"com.xxl.job.core.handler.IJobHandler"的JobHandler类,实现其中任务方法。 + 2、手动通过如下方式注入到执行器容器。 + ``` + XxlJobExecutor.registJobHandler("demoJobHandler", new DemoJobHandler()); + ``` + +#### 步骤二:调度中心,新建调度任务 +后续步骤和 "3.2 BEAN模式(方法形式)"一致,可以前往参考。 + + +### 3.2 BEAN模式(方法形式) + +Bean模式任务,支持基于方法的开发方式,每个任务对应一个方法。 + +- 优点: + - 每个任务只需要开发一个方法,并添加"@XxlJob"注解即可,更加方便、快速。 + - 支持自动扫描任务并注入到执行器容器。 +- 缺点:要求Spring容器环境; + +>基于方法开发的任务,底层会生成JobHandler代理,和基于类的方式一样,任务也会以JobHandler的形式存在于执行器任务容器中。 + +#### 步骤一:执行器项目中,开发Job方法: + + 1、任务开发:在Spring Bean实例中,开发Job方法; + 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。 + 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志; + 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果; + +``` +// 可参考Sample示例执行器中的 "com.xxl.job.executor.service.jobhandler.SampleXxlJob" ,如下: +@XxlJob("demoJobHandler") +public void demoJobHandler() throws Exception { + XxlJobHelper.log("XXL-JOB, Hello World."); +} +``` + +#### 步骤二:调度中心,新建调度任务 +参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "BEAN模式",JobHandler属性填写任务注解“@XxlJob”中定义的值; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAsz.png "在这里输入图片标题") + +#### 原生内置Bean模式任务 +为方便用户参考与快速实用,示例执行器内原生提供多个Bean模式任务Handler,可以直接配置实用,如下: + +- demoJobHandler:简单示例任务,任务内部模拟耗时任务逻辑,用户可在线体验Rolling Log等功能; +- shardingJobHandler:分片示例任务,任务内部模拟处理分片参数,可参考熟悉分片任务; +- httpJobHandler:通用HTTP任务Handler;业务方只需要提供HTTP链接等信息即可,不限制语言、平台。示例任务入参如下: + ``` + url: http://www.xxx.com + method: get 或 post + data: post-data + ``` +- commandJobHandler:通用命令行任务Handler;业务方只需要提供命令行即可;如 “pwd”命令; + + +### 3.3 GLUE模式(Java) +任务以源码方式维护在调度中心,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。开发流程如下: + +#### 步骤一:调度中心,新建调度任务: +参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "GLUE模式(Java)"; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_tJOq.png "在这里输入图片标题") + +#### 步骤二:开发任务代码: +选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。 + +版本回溯功能(支持30个版本的版本回溯):在GLUE任务的Web IDE界面,选择右上角下拉框“版本回溯”,会列出该GLUE的更新历史,选择相应版本即可显示该版本代码,保存后GLUE代码即回退到对应的历史版本; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_dNUJ.png "在这里输入图片标题") + +### 3.4 GLUE模式(Shell) + +#### 步骤一:调度中心,新建调度任务 +参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "GLUE模式(Shell)"; + +#### 步骤二:开发任务代码: +选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。 + +该模式的任务实际上是一段 "shell" 脚本; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_iUw0.png "在这里输入图片标题") + +### 3.4 GLUE模式(Python) + +#### 步骤一:调度中心,新建调度任务 +参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "GLUE模式(Python)"; + +#### 步骤二:开发任务代码: +选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。 + +该模式的任务实际上是一段 "python" 脚本; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_BPLG.png "在这里输入图片标题") + +### 3.5 GLUE模式(NodeJS) + +#### 步骤一:调度中心,新建调度任务 +参考上文“配置属性详细说明”对新建的任务进行参数配置,运行模式选中 "GLUE模式(NodeJS)"; + +#### 步骤二:开发任务代码: +选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。 + +该模式的任务实际上是一段 "nodeJS" 脚本; + +### 3.6 GLUE模式(PHP) +同上 + +### 3.7 GLUE模式(PowerShell) +同上 + + + +## 四、操作指南 + +### 4.1 配置执行器 +点击进入"执行器管理"界面, 如下图: +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Hr2T.png "在这里输入图片标题") + + 1、"调度中心OnLine:"右侧显示在线的"调度中心"列表, 任务执行结束后, 将会以failover的模式进行回调调度中心通知执行结果, 避免回调的单点风险; + 2、"执行器列表" 中显示在线的执行器列表, 可通过"OnLine 机器"查看对应执行器的集群机器。 + +点击按钮 "+新增执行器" 弹框如下图, 可新增执行器配置: + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_V3vF.png "在这里输入图片标题") + +执行器属性说明 + + AppName: 是每个执行器集群的唯一标示AppName, 执行器会周期性以AppName为对象进行自动注册。可通过该配置自动发现注册成功的执行器, 供任务调度时使用; + 名称: 执行器的名称, 因为AppName限制字母数字等组成,可读性不强, 名称为了提高执行器的可读性; + 排序: 执行器的排序, 系统中需要执行器的地方,如任务新增, 将会按照该排序读取可用的执行器列表; + 注册方式:调度中心获取执行器地址的方式; + 自动注册:执行器自动进行执行器注册,调度中心通过底层注册表可以动态发现执行器机器地址; + 手动录入:人工手动录入执行器的地址信息,多地址逗号分隔,供调度中心使用; + 机器地址:"注册方式"为"手动录入"时有效,支持人工维护执行器的地址信息; + +### 4.2 新建任务 +进入任务管理界面,点击“新增任务”按钮,在弹出的“新增任务”界面配置任务属性后保存即可。详情页参考章节 "三、任务详解"。 + +### 4.3 编辑任务 +进入任务管理界面,选中指定任务。点击该任务右侧“编辑”按钮,在弹出的“编辑任务”界面更新任务属性后保存即可,可以修改设置的任务属性信息: + +### 4.4 编辑GLUE代码 + +该操作仅针对GLUE任务。 + +选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发。可参考章节 "3.3 GLUE模式(Java)"。 + +### 4.5 启动/停止任务 +可对任务进行“启动”和“停止”操作。 +需要注意的是,此处的启动/停止仅针对任务的后续调度触发行为,不会影响到已经触发的调度任务,如需终止已经触发的调度任务,可查看“4.9 终止运行中的任务” + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAhX.png "在这里输入图片标题") + +### 4.6 手动触发一次调度 +点击“执行”按钮,可手动触发一次任务调度,不影响原有调度规则。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAhX.png "在这里输入图片标题") + +### 4.7 查看调度日志 +点击“日志”按钮,可以查看任务历史调度日志。在历史调入日志界面可查看每次任务调度的调度结果、执行结果等,点击“执行日志”按钮可查看执行器完整日志。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_ZAhX.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_UDSo.png "在这里输入图片标题") + + 调度时间:"调度中心"触发本次调度并向"执行器"发送任务执行信号的时间; + 调度结果:"调度中心"触发本次调度的结果,200表示成功,500或其他表示失败; + 调度备注:"调度中心"触发本次调度的日志信息; + 执行器地址:本次任务执行的机器地址 + 运行模式:触发调度时任务的运行模式,运行模式可参考章节 "三、任务详解"; + 任务参数:本地任务执行的入参 + 执行时间:"执行器"中本次任务执行结束后回调的时间; + 执行结果:"执行器"中本次任务执行的结果,200表示成功,500或其他表示失败; + 执行备注:"执行器"中本次任务执行的日志信息; + 操作: + "执行日志"按钮:点击可查看本地任务执行的详细日志信息;详见“4.8 查看执行日志”; + "终止任务"按钮:点击可终止本地调度对应执行器上本任务的执行线程,包括未执行的阻塞任务一并被终止; + +### 4.8 查看执行日志 +点击执行日志右侧的 “执行日志” 按钮,可跳转至执行日志界面,可以查看业务代码中打印的完整日志,如下图; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_tvGI.png "在这里输入图片标题") + +### 4.9 终止运行中的任务 +仅针对执行中的任务。 +在任务日志界面,点击右侧的“终止任务”按钮,将会向本次任务对应的执行器发送任务终止请求,将会终止掉本次任务,同时会清空掉整个任务执行队列。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_hIci.png "在这里输入图片标题") + +任务终止时通过 "interrupt" 执行线程的方式实现, 将会触发 "InterruptedException" 异常。因此如果JobHandler内部catch到了该异常并消化掉的话, 任务终止功能将不可用。 + +因此, 如果遇到上述任务终止不可用的情况, 需要在JobHandler中应该针对 "InterruptedException" 异常进行特殊处理 (向上抛出) , 正确逻辑如下: +``` +try{ + // do something +} catch (Exception e) { + if (e instanceof InterruptedException) { + throw e; + } + logger.warn("{}", e); +} +``` + +而且,在JobHandler中开启子线程时,子线程也不可catch处理"InterruptedException",应该主动向上抛出。 + +任务终止时会执行对应JobHandler的"destroy()"方法,可以借助该方法处理一些资源回收的逻辑。 + + +### 4.10 删除执行日志 +在任务日志界面,选中执行器和任务之后,点击右侧的"删除"按钮将会出现"日志清理"弹框,弹框中支持选择不同类型的日志清理策略,选中后点击"确定"按钮即可进行日志清理操作; +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Ypik.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_EB65.png "在这里输入图片标题") + +### 4.11 删除任务 +点击删除按钮,可以删除对应任务。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Z9Qr.png "在这里输入图片标题") + +### 4.12 用户管理 +进入 "用户管理" 界面,可查看和管理用户信息; + +目前用户分为两种角色: +- 管理员:拥有全量权限,支持在线管理用户信息,为用户分配权限,权限分配粒度为执行器; +- 普通用户:仅拥有被分配权限的执行器,及相关任务的操作权限; + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_1001.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_1002.png "在这里输入图片标题") + + +## 五、总体设计 +### 5.1 源码目录介绍 + - /doc :文档资料 + - /db :“调度数据库”建表脚本 + - /xxl-job-admin :调度中心,项目源码 + - /xxl-job-core :公共Jar依赖 + - /xxl-job-executor-samples :执行器,Sample示例项目(大家可以在该项目上进行开发,也可以将现有项目改造生成执行器项目) + +### 5.2 “调度数据库”配置 +XXL-JOB调度模块基于自研调度组件并支持集群部署,调度数据库表说明如下: + + - xxl_job_lock:任务调度锁表; + - xxl_job_group:执行器信息表,维护任务执行器信息; + - xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等; + - xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等; + - xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到; + - xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能; + - xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息; + - xxl_job_user:系统用户表; + + +### 5.3 架构设计 +#### 5.3.1 设计思想 +将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。 + +将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。 + +因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性; + +#### 5.3.2 系统组成 +- **调度模块(调度中心)**: + 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块; + 支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。 +- **执行模块(执行器)**: + 负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效; + 接收“调度中心”的执行请求、终止请求和日志请求等。 + +#### 5.3.3 架构图 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Qohm.png "在这里输入图片标题") + +### 5.4 调度模块剖析 +#### 5.4.1 quartz的不足 +Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题: + +- 问题一:调用API的的方式操作任务,不人性化; +- 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。 +- 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务; +- 问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。 + +XXL-JOB弥补了quartz的上述不足之处。 + +#### 5.4.2 自研调度模块 +XXL-JOB最终选择自研调度组件(早期调度组件基于Quartz);一方面是为了精简系统降低冗余依赖,另一方面是为了提供系统的可控度与稳定性; + +XXL-JOB中“调度模块”和“任务模块”完全解耦,调度模块进行任务调度时,将会解析不同的任务参数发起远程调用,调用各自的远程执行器服务。这种调用模型类似RPC调用,调度中心提供调用代理的功能,而执行器提供远程服务的功能。 + +#### 5.4.3 调度中心HA(集群) +基于数据库的集群方案,数据库选用Mysql;集群分布式并发环境中进行定时任务调度时,会在各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。 + +#### 5.4.4 调度线程池 +调度采用线程池方式实现,避免单线程因阻塞而引起任务调度延迟。 + +#### 5.4.5 并行调度 +XXL-JOB调度模块默认采用并行机制,在多线程调度的情况下,调度模块被阻塞的几率很低,大大提高了调度系统的承载量。 + +XXL-JOB的不同任务之间并行调度、并行执行。 +XXL-JOB的单个任务,针对多个执行器是并行运行的,针对单个执行器是串行执行的。同时支持任务终止。 + +#### 5.4.6 过期处理策略 +任务调度错过触发时间时的处理策略: +- 可能原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过; +- 处理策略: + - 过期超5s:本次忽略,当前时间开始计算下次触发时间 + - 过期5s内:立即触发一次,当前时间开始计算下次触发时间 + + +#### 5.4.7 日志回调服务 +调度模块的“调度中心”作为Web服务部署时,一方面承担调度中心功能,另一方面也为执行器提供API服务。 + +调度中心提供的"日志回调服务API服务"代码位置如下: +``` +xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback +``` + +“执行器”在接收到任务执行请求后,执行任务,在执行结束之后会将执行结果回调通知“调度中心”: + +#### 5.4.8 任务HA(Failover) +执行器如若集群部署,调度中心将会感知到在线的所有执行器,如“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”。 + +当任务"路由策略"选择"故障转移(FAILOVER)"时,当调度中心每次发起调度请求时,会按照顺序对执行器发出心跳检测请求,第一个检测为存活状态的执行器将会被选定并发送调度请求。 + +调度成功后,可在日志监控界面查看“调度备注”,如下; +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_jrdI.png "在这里输入图片标题") + +“调度备注”可以看出本地调度运行轨迹,执行器的"注册方式"、"地址列表"和任务的"路由策略"。"故障转移(FAILOVER)"路由策略下,调度中心首先对第一个地址进行心跳检测,心跳失败因此自动跳过,第二个依然心跳检测失败…… +直至心跳检测第三个地址“127.0.0.1:9999”成功,选定为“目标执行器”;然后对“目标执行器”发送调度请求,调度流程结束,等待执行器回调执行结果。 + +#### 5.4.9 调度日志 +调度中心每次进行任务调度,都会记录一条任务日志,任务日志主要包括以下三部分内容: + +- 任务信息:包括“执行器地址”、“JobHandler”和“执行参数”等属性,点击任务ID按钮可查看,根据这些参数,可以精确的定位任务执行的具体机器和任务代码; +- 调度信息:包括“调度时间”、“调度结果”和“调度日志”等,根据这些参数,可以了解“调度中心”发起调度请求时具体情况。 +- 执行信息:包括“执行时间”、“执行结果”和“执行日志”等,根据这些参数,可以了解在“执行器”端任务执行的具体情况; + +调度日志,针对单次调度,属性说明如下: +- 执行器地址:任务执行的机器地址; +- JobHandler:Bean模式表示任务执行的JobHandler名称; +- 任务参数:任务执行的入参; +- 调度时间:调度中心,发起调度的时间; +- 调度结果:调度中心,发起调度的结果,SUCCESS或FAIL; +- 调度备注:调度中心,发起调度的备注信息,如地址心跳检测日志等; +- 执行时间:执行器,任务执行结束后回调的时间; +- 执行结果:执行器,任务执行的结果,SUCCESS或FAIL; +- 执行备注:执行器,任务执行的备注信息,如异常日志等; +- 执行日志:任务执行过程中,业务代码中打印的完整执行日志,见“4.8 查看执行日志”; + +#### 5.4.10 任务依赖 +原理:XXL-JOB中每个任务都对应有一个任务ID,同时,每个任务支持设置属性“子任务ID”,因此,通过“任务ID”可以匹配任务依赖关系。 + +当父任务执行结束并且执行成功时,将会根据“子任务ID”匹配子任务依赖,如果匹配到子任务,将会主动触发一次子任务的执行。 + +在任务日志界面,点击任务的“执行备注”的“查看”按钮,可以看到匹配子任务以及触发子任务执行的日志信息,如无信息则表示未触发子任务执行,可参考下图。 + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_Wb2o.png "在这里输入图片标题") + +![输入图片说明](https://www.xuxueli.com/doc/static/xxl-job/images/img_jOAU.png "在这里输入图片标题") + +#### 5.4.11 全异步化 & 轻量级 + +- 全异步化设计:XXL-JOB系统中业务逻辑在远程执行器执行,触发流程全异步化设计。相比直接在调度中心内部执行业务逻辑,极大的降低了调度线程占用时间; + - 异步调度:调度中心每次任务触发时仅发送一次调度请求,该调度请求首先推送“异步调度队列”,然后异步推送给远程执行器 + - 异步执行:执行器会将请求存入“异步执行队列”并且立即响应调度中心,异步运行。 +- 轻量级设计:XXL-JOB调度中心中每个JOB逻辑非常 “轻”,在全异步化的基础上,单个JOB一次运行平均耗时基本在 "10ms" 之内(基本为一次请求的网络开销);因此,可以保证使用有限的线程支撑大量的JOB并发运行; + +得益于上述两点优化,理论上默认配置下的调度中心,单机能够支撑 5000 任务并发运行稳定运行; + +实际场景中,由于调度中心与执行器网络ping延迟不同、DB读写耗时不同、任务调度密集程度不同,会导致任务量上限会上下波动。 + +如若需要支撑更多的任务量,可以通过 "调大调度线程数" 、"降低调度中心与执行器ping延迟" 和 "提升机器配置" 几种方式优化。 + +#### 5.4.12 均衡调度 +调度中心在集群部署时会自动进行任务平均分配,触发组件每次获取与线程池数量(调度中心支持自定义调度线程池大小)相关数量的任务,避免大量任务集中在单个调度中心集群节点; + +### 5.5 任务 "运行模式" 剖析 +#### 5.5.1 "Bean模式" 任务 +开发步骤:可参考 "章节三" ; +原理:每个Bean模式任务都是一个Spring的Bean类实例,它被维护在“执行器”项目的Spring容器中。任务类需要加“@JobHandler(value="名称")”注解,因为“执行器”会根据该注解识别Spring容器中的任务。任务类需要继承统一接口“IJobHandler”,任务逻辑在execute方法中开发,因为“执行器”在接收到调度中心的调度请求时,将会调用“IJobHandler”的execute方法,执行任务逻辑。 + +#### 5.5.2 "GLUE模式(Java)" 任务 +开发步骤:可参考 "章节三" ; +原理:每个 "GLUE模式(Java)" 任务的代码,实际上是“一个继承自“IJobHandler”的实现类的类代码”,“执行器”接收到“调度中心”的调度请求时,会通过Groovy类加载器加载此代码,实例化成Java对象,同时注入此代码中声明的Spring服务(请确保Glue代码中的服务和类引用在“执行器”项目中存在),然后调用该对象的execute方法,执行任务逻辑。 + +#### 5.5.3 GLUE模式(Shell) + GLUE模式(Python) + GLUE模式(PHP) + GLUE模式(NodeJS) + GLUE模式(Powershell) +开发步骤:可参考 "章节三" ; +原理:脚本任务的源码托管在调度中心,脚本逻辑在执行器运行。当触发脚本任务时,执行器会加载脚本源码在执行器机器上生成一份脚本文件,然后通过Java代码调用该脚本;并且实时将脚本输出日志写到任务日志文件中,从而在调度中心可以实时监控脚本运行情况; + +目前支持的脚本类型如下: + + - shell脚本:任务运行模式选择为 "GLUE模式(Shell)"时支持 "Shell" 脚本任务; + - python脚本:任务运行模式选择为 "GLUE模式(Python)"时支持 "Python" 脚本任务; + - php脚本:任务运行模式选择为 "GLUE模式(PHP)"时支持 "PHP" 脚本任务; + - nodejs脚本:任务运行模式选择为 "GLUE模式(NodeJS)"时支持 "NodeJS" 脚本任务; + - powershell:任务运行模式选择为 "GLUE模式(PowerShell)"时支持 "PowerShell" 脚本任务; + +脚本任务通过 Exit Code 判断任务执行结果,状态码可参考章节 "5.15 任务执行结果说明"; + +#### 5.5.4 执行器 +执行器实际上是一个内嵌的Server,默认端口9999(配置项:xxl.job.executor.port)。 + +在项目启动时,执行器会通过“@JobHandler”识别Spring容器中“Bean模式任务”,以注解的value属性为key管理起来。 + +“执行器”接收到“调度中心”的调度请求时,如果任务类型为“Bean模式”,将会匹配Spring容器中的“Bean模式任务”,然后调用其execute方法,执行任务逻辑。如果任务类型为“GLUE模式”,将会加载GLue代码,实例化Java对象,注入依赖的Spring服务(注意:Glue代码中注入的Spring服务,必须存在与该“执行器”项目的Spring容器中),然后调用execute方法,执行任务逻辑。 + +#### 5.5.5 任务日志 +XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 "XxlJobHelper.log" 打印执行日志,“调度中心”查看执行日志时将会加载对应的日志文件。 + +(历史版本通过重写LOG4J的Appender实现,存在依赖限制,该方式在新版本已经被抛弃) + +日志文件存放的位置可在“执行器”配置文件进行自定义,默认目录格式为:/data/applogs/xxl-job/jobhandler/“格式化日期”/“数据库调度日志记录的主键ID.log”。 + +在JobHandler中开启子线程时,子线程将会将会把日志打印在父线程即JobHandler的执行日志中,方便日志追踪。 + +### 5.6 通讯模块剖析 + +#### 5.6.1 一次完整的任务调度通讯流程 + - 1、“调度中心”向“执行器”发送http调度请求: “执行器”中接收请求的服务,实际上是一台内嵌Server,默认端口9999; + - 2、“执行器”执行任务逻辑; + - 3、“执行器”http回调“调度中心”调度结果: “调度中心”中接收回调的服务,是针对执行器开放一套API服务; + +#### 5.6.2 通讯数据加密 +调度中心向执行器发送的调度请求时使用RequestModel和ResponseModel两个对象封装调度请求参数和响应数据, 在进行通讯之前底层会将上述两个对象对象序列化,并进行数据协议以及时间戳检验,从而达到数据加密的功能; + +### 5.7 任务注册, 任务自动发现 +自v1.5版本之后, 任务取消了"任务执行机器"属性, 改为通过任务注册和自动发现的方式, 动态获取远程执行器地址并执行。 + + AppName: 每个执行器机器集群的唯一标示, 任务注册以 "执行器" 为最小粒度进行注册; 每个任务通过其绑定的执行器可感知对应的执行器机器列表; + 注册表: 见"xxl_job_registry"表, "执行器" 在进行任务注册时将会周期性维护一条注册记录,即机器地址和AppName的绑定关系; "调度中心" 从而可以动态感知每个AppName在线的机器列表; + 执行器注册: 任务注册Beat周期默认30s; 执行器以一倍Beat进行执行器注册, 调度中心以一倍Beat进行动态任务发现; 注册信息的失效时间为三倍Beat; + 执行器注册摘除:执行器销毁时,将会主动上报调度中心并摘除对应的执行器机器信息,提高心跳注册的实时性; + + +为保证系统"轻量级"并且降低学习部署成本,没有采用Zookeeper作为注册中心,采用DB方式进行任务注册发现; + +### 5.8 任务执行结果 +自v1.6.2之后,任务执行结果通过 "IJobHandler" 的返回值 "ReturnT" 进行判断; +当返回值符合 "ReturnT.code == ReturnT.SUCCESS_CODE" 时表示任务执行成功,否则表示任务执行失败,而且可以通过 "ReturnT.msg" 回调错误信息给调度中心; +从而,在任务逻辑中可以方便的控制任务执行结果; + +### 5.9 分片广播 & 动态分片 +执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务; + +"分片广播" 以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。 + +"分片广播" 和普通任务开发流程一致,不同之处在于可以获取分片参数,获取分片参数进行分片业务处理。 + +- Java语言任务获取分片参数方式:BEAN、GLUE模式(Java) +``` +// 可参考Sample示例执行器中的示例任务"ShardingJobHandler"了解试用 +int shardIndex = XxlJobHelper.getShardIndex(); +int shardTotal = XxlJobHelper.getShardTotal(); +``` +- 脚本语言任务获取分片参数方式:GLUE模式(Shell)、GLUE模式(Python)、GLUE模式(Nodejs) +``` +// 脚本任务入参固定为三个,依次为:任务传参、分片序号、分片总数。以Shell模式任务为例,获取分片参数代码如下 +echo "分片序号 index = $2" +echo "分片总数 total = $3" +``` + +分片参数属性说明: + + index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号; + total:总分片数,执行器集群的总机器数量; + +该特性适用场景如: +- 1、分片任务场景:10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍; +- 2、广播任务场景:广播执行器机器运行shell脚本、广播集群节点进行缓存更新等 + +### 5.10 访问令牌(AccessToken) +为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯; + +调度中心和执行器,可通过配置项 "xxl.job.accessToken" 进行AccessToken的设置。 + +调度中心和执行器,如果需要正常通讯,只有两种设置; + +- 设置一:调度中心和执行器,均不设置AccessToken;关闭安全性校验; +- 设置二:调度中心和执行器,设置了相同的AccessToken; + +### 5.11 故障转移 & 失败重试 +一次完整任务流程包括"调度(调度中心) + 执行(执行器)"两个阶段。 + +- "故障转移"发生在调度阶段,在执行器集群部署时,如果某一台执行器发生故障,该策略支持自动进行Failover切换到一台正常的执行器机器并且完成调度请求流程。 +- "失败重试"发生在"调度 + 执行"两个阶段,支持通过自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试; + +### 5.12 执行器灰度上线 +调度中心与业务解耦,只需部署一次后常年不需要维护。但是,执行器中托管运行着业务作业,作业上线和变更需要重启执行器,尤其是Bean模式任务。 +执行器重启可能会中断运行中的任务。但是,XXL-JOB得益于自建执行器与自建注册中心,可以通过灰度上线的方式,避免因重启导致的任务中断的问题。 + +步骤如下: +- 1、执行器改为手动注册,下线一半机器列表(A组),线上运行另一半机器列表(B组); +- 2、等待A组机器任务运行结束并编译上线;执行器注册地址替换为A组; +- 3、等待B组机器任务运行结束并编译上线;执行器注册地址替换为A组+B组; +操作结束; + +### 5.13 任务执行结果说明 +系统根据以下标准判断任务执行结果,可参考之。 + +-- | Bean/Glue(Java) | Glue(Shell) 等脚本任务 +--- | --- | --- +成功 | IJobHandler.SUCCESS | 0 +失败 | IJobHandler.FAIL | -1(非0状态码) + +### 5.14 任务超时控制 +支持设置任务超时时间,任务运行超时的情况下,将会主动中断任务; + +需要注意的是,任务超时中断时与任务终止机制(可查看“4.9 终止运行中的任务”)类似,也是通过 "interrupt" 中断任务,因此业务代码需要将 "InterruptedException" 外抛,否则功能不可用。 + +### 5.15 跨语言 +XXL-JOB是一个跨语言的任务调度平台,主要体现在如下几个方面: +- 1、RESTful API:调度中心与执行器提供语言无关的 RESTful API 服务,第三方任意语言可据此对接调度中心或者实现执行器。(可参考章节 “调度中心/执行器 RESTful API” ) +- 2、多任务模式:提供Java、Python、PHP……等十来种任务模式,可参考章节 “5.5 任务 "运行模式" ”;理论上可扩展任意语言任务模式; +- 2、提供基于HTTP的任务Handler(Bean任务,JobHandler="httpJobHandler");业务方只需要提供HTTP链接等相关信息即可,不限制语言、平台;(可参考章节 “原生内置Bean模式任务” ) + +### 5.16 任务失败告警 +默认提供邮件失败告警,可扩展短信、钉钉等方式。如果需要新增一种告警方式,只需要新增一个实现 "com.xxl.job.admin.core.alarm.JobAlarm" 接口的告警实现即可。可以参考默认提供邮箱告警实现 "EmailJobAlarm"。 + +### 5.17 调度中心Docker镜像构建 +可以通过以下命令快速构建调度中心,并启动运行; +``` +mvn clean package +docker build -t xuxueli/xxl-job-admin ./xxl-job-admin +docker run --name xxl-job-admin -p 8080:8080 -d xuxueli/xxl-job-admin +``` + +### 5.20 避免任务重复执行 +调度密集或者耗时任务可能会导致任务阻塞,集群情况下调度组件小概率情况下会重复触发; +针对上述情况,可以通过结合 "单机路由策略(如:第一台、一致性哈希)" + "阻塞策略(如:单机串行、丢弃后续调度)" 来规避,最终避免任务重复执行。 + +### 5.21 命令行任务 +原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可; +如任务参数 "pwd" 将会执行命令并输出数据; + +### 5.22 日志自动清理 +XXL-JOB日志主要包含如下两部分,均支持日志自动清理,说明如下: +- 调度中心日志表数据:可借助配置项 "xxl.job.logretentiondays" 设置日志表数据保存天数,过期日志自动清理;详情可查看上文配置说明; +- 执行器日志文件数据:可借助配置项 "xxl.job.executor.logretentiondays" 设置日志文件数据保存天数,过期日志自动清理;详情可查看上文配置说明; + +### 5.23 调度结果丢失处理 +执行器因网络抖动回调失败或宕机等异常情况,会导致任务调度结果丢失。由于调度中心依赖执行器回调来感知调度结果,因此会导致调度日志永远处于 "运行中" 状态。 + +针对该问题,调度中心提供内置组件进行处理,逻辑为:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败; + + +## 六、调度中心/执行器 RESTful API +XXL-JOB 目标是一种跨平台、跨语言的任务调度规范和协议。 + +针对Java应用,可以直接通过官方提供的调度中心与执行器,方便快速的接入和使用调度中心,可以参考上文 “快速入门” 章节。 + +针对非Java应用,可借助 XXL-JOB 的标准 RESTful API 方便的实现多语言支持。 + +- 调度中心 RESTful API: + - 说明:调度中心提供给执行器使用的API;不局限于官方执行器使用,第三方可使用该API来实现执行器; + - API列表:执行器注册、任务结果回调等; +- 执行器 RESTful API : + - 说明:执行器提供给调度中心使用的API;官方执行器默认已实现,第三方执行器需要实现并对接提供给调度中心; + - API列表:任务触发、任务终止、任务日志查询……等; + +此处 RESTful API 主要用于非Java语言定制个性化执行器使用,实现跨语言。除此之外,如果有需要通过API操作调度中心,可以个性化扩展 “调度中心 RESTful API” 并使用。 + +### 6.1 调度中心 RESTful API + +API服务位置:com.xxl.job.core.biz.AdminBiz ( com.xxl.job.admin.controller.JobApiController ) +API服务请求参考代码:com.xxl.job.adminbiz.AdminBizTest + +#### a、任务回调 +``` +说明:执行器执行完任务后,回调任务结果时使用 + +------ + +地址格式:{调度中心跟地址}/callback + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + [{ + "logId":1, // 本次调度日志ID + "logDateTim":0, // 本次调度日志时间 + "executeResult":{ + "code": 200, // 200 表示任务执行正常,500表示失败 + "msg": null + } + }] + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### b、执行器注册 +``` +说明:执行器注册时使用,调度中心会实时感知注册成功的执行器并发起任务调度 + +------ + +地址格式:{调度中心跟地址}/registry + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "registryGroup":"EXECUTOR", // 固定值 + "registryKey":"xxl-job-executor-example", // 执行器AppName + "registryValue":"http://127.0.0.1:9999/" // 执行器地址,内置服务跟地址 + } + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### c、执行器注册摘除 +``` +说明:执行器注册摘除时使用,注册摘除后的执行器不参与任务调度与执行 + +------ + +地址格式:{调度中心跟地址}/registryRemove + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "registryGroup":"EXECUTOR", // 固定值 + "registryKey":"xxl-job-executor-example", // 执行器AppName + "registryValue":"http://127.0.0.1:9999/" // 执行器地址,内置服务跟地址 + } + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +### 6.2 执行器 RESTful API + +API服务位置:com.xxl.job.core.biz.ExecutorBiz +API服务请求参考代码:com.xxl.job.executorbiz.ExecutorBizTest + +#### a、心跳检测 +``` +说明:调度中心检测执行器是否在线时使用 + +------ + +地址格式:{执行器内嵌服务跟地址}/beat + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### b、忙碌检测 +``` +说明:调度中心检测指定执行器上指定任务是否忙碌(运行中)时使用 + +------ + +地址格式:{执行器内嵌服务跟地址}/idleBeat + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "jobId":1 // 任务ID + } + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### c、触发任务 +``` +说明:触发任务执行 + +------ + +地址格式:{执行器内嵌服务跟地址}/run + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "jobId":1, // 任务ID + "executorHandler":"demoJobHandler", // 任务标识 + "executorParams":"demoJobHandler", // 任务参数 + "executorBlockStrategy":"COVER_EARLY", // 任务阻塞策略,可选值参考 com.xxl.job.core.enums.ExecutorBlockStrategyEnum + "executorTimeout":0, // 任务超时时间,单位秒,大于零时生效 + "logId":1, // 本次调度日志ID + "logDateTime":1586629003729, // 本次调度日志时间 + "glueType":"BEAN", // 任务模式,可选值参考 com.xxl.job.core.glue.GlueTypeEnum + "glueSource":"xxx", // GLUE脚本代码 + "glueUpdatetime":1586629003727, // GLUE脚本更新时间,用于判定脚本是否变更以及是否需要刷新 + "broadcastIndex":0, // 分片参数:当前分片 + "broadcastTotal":0 // 分片参数:总分片 + } + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### f、终止任务 +``` +说明:终止任务 + +------ + +地址格式:{执行器内嵌服务跟地址}/kill + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "jobId":1 // 任务ID + } + + +响应数据格式: + { + "code": 200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + } +``` + +#### d、查看执行日志 +``` +说明:终止任务,滚动方式加载 + +------ + +地址格式:{执行器内嵌服务跟地址}/log + +Header: + XXL-JOB-ACCESS-TOKEN : {请求令牌} + +请求数据格式如下,放置在 RequestBody 中,JSON格式: + { + "logDateTim":0, // 本次调度日志时间 + "logId":0, // 本次调度日志ID + "fromLineNum":0 // 日志开始行号,滚动加载日志 + } + +响应数据格式: + { + "code":200, // 200 表示正常、其他失败 + "msg": null // 错误提示消息 + "content":{ + "fromLineNum":0, // 本次请求,日志开始行数 + "toLineNum":100, // 本次请求,日志结束行号 + "logContent":"xxx", // 本次请求日志内容 + "isEnd":true // 日志是否全部加载完 + } + } +``` + + + +## 七、版本更新日志 +### 7.1 版本 V1.1.x,新特性[2015-12-05] +**【于V1.1.x版本,XXL-JOB正式应用于我司,内部定制别名为 “Ferrari”,新接入应用推荐使用最新版本】** +- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手; +- 2、动态:支持动态修改任务状态,动态暂停/恢复任务,即时生效; +- 3、服务HA:任务信息持久化到mysql中,Job服务天然支持集群,保证服务HA; +- 4、任务HA:某台Job服务挂掉,任务会平滑分配给其他的某一台存活服务,即使所有服务挂掉,重启时或补偿执行丢失任务; +- 5、一个任务只会在其中一台服务器上执行; +- 6、任务串行执行; +- 7、支持自定义参数; +- 8、支持远程任务执行终止; + +### 7.2 版本 V1.2.x,新特性[2016-01-17] +- 1、支持任务分组; +- 2、支持“本地任务”、“远程任务”; +- 3、底层通讯支持两种方式,Servlet方式 + JETTY方式; +- 4、支持“任务日志”; +- 5、支持“串行执行”,并行执行; + + 说明:V1.2版本将系统架构按功能拆分为: + + - 调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求; + - 执行模块(执行器):负责接收调度请求并执行任务逻辑; + - 通讯模块:负责调度模块和任务模块之间的信息通讯; + 优点: + + - 解耦:任务模块提供任务接口,调度模块维护调度信息,业务相互独立; + - 高扩展性; + - 稳定性; + +### 7.3 版本 V1.3.0,新特性[2016-05-19] +- 1、遗弃“本地任务”模式,推荐使用“远程任务”,易于系统解耦,任务对应的JobHandler统称为“执行器”; +- 2、遗弃“servlet”方式底层系统通讯,推荐使用JETTY方式,调度+回调双向通讯,重构通讯逻辑; +- 3、UI交互优化:左侧菜单展开状态优化,菜单项选中状态优化,任务列表打开表格有压缩优化; +- 4、【重要】“执行器”细分为:BEAN、GLUE两种开发模式,简介见下文: + + “执行器” 模式简介: + - BEAN模式执行器:每个执行器都是Spring的一个Bean实例,XXL-JOB通过注解@JobHandler识别和调度执行器; + -GLUE模式执行器:每个执行器对应一段代码,在线Web编辑和维护,动态编译生效,执行器负责加载GLUE代码和执行; + +### 7.4 版本 V1.3.1,新特性[2016-05-23] +- 1、更新项目目录结构: + - /xxl-job-admin -------------------- 【调度中心】:负责管理调度信息,按照调度配置发出调度请求; + - /xxl-job-core ----------------------- 公共依赖 + - /xxl-job-executor-example ------ 【执行器】:负责接收调度请求并执行任务逻辑; + - /db ---------------------------------- 建表脚本 + - /doc --------------------------------- 用户手册 +- 2、在新的目录结构上,升级了用户手册; +- 3、优化了一些交互和UI; + +### 7.5 版本 V1.3.2,新特性[2016-05-28] +- 1、调度逻辑进行事务包裹; +- 2、执行器异步回调执行日志; +- 3、【重要】在 “调度中心” 支持HA的基础上,扩展执行器的Failover支持,支持配置多执行期地址; + +### 7.6 版本 V1.4.0 新特性[2016-07-24] +- 1、任务依赖: 通过事件触发方式实现, 任务执行成功并回调时会主动触发一次子任务的调度, 多个子任务用逗号分隔; +- 2、执行器底层实现代码进行重度重构, 优化底层建表脚本; +- 3、执行器中任务线程分组逻辑优化: 之前根据执行器JobHandler进行线程分组,当多个任务复用Jobhanlder会导致相互阻塞。现改为根据调度中心任务进行任务线程分组,任务与任务执行相互隔离; +- 4、执行器调度通讯方案优化, 通过Hex + HC实现建议RPC通讯协议, 优化了通讯参数的维护和解析流程; +- 5、调度中心, 新建/编辑任务, 界面属性调整: + - 5.1、任务新增/编辑界面中去除 "任务名JobName"属性 ,该属性改为系统自动生成: 该字段之前主要用于在 "调度中心" 唯一标示一个任务, 现实意义不大, 因此计划淡化掉该字段,改为系统生成UUID,从而简化任务新建的操作; + - 5.2、任务新增/编辑界面中去除 "GLUE模式" 复选框位置调整, 改为贴近"JobHandler"输入框右侧; + - 5.3、任务新增/编辑界面中去除 "报警阈值" 属性; + - 5.4、任务新增/编辑界面中去除 "子任务Key" 属性, 每个任务全局任务Key可以从任务列表获取, 当本任务执行结束且成功后, 将会根据子任务Key匹配子任务并主动触发一次子任务执行; +- 6、问题修复: + - 6.1、执行器jetty关闭优化,解决一处可能导致jetty无法关闭的问题; + - 6.2、执行器任务终止时,执行队列回调优化,解决一处导致任务无法回调的问题; + - 6.3、调度中心中列表分页参数优化,解决一处因服务器限制post长度而引起的问题; + - 6.4、执行器Jobhandler注解优化,解决一处因事务代理导致的容器无法加载JobHandler的问题; + - 6.5、远程调度优化,禁用retry策略,解决一处可能导致重复调用的问题; + +Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段, 地址见分支 [V1.3](https://github.com/xuxueli/xxl-job/tree/v1.3) 。新特性将会在master分支持续更新。 + +### 7.7 版本 V1.4.1 新特性[2016-09-06] +- 1、项目成功推送maven中央仓库, 中央仓库地址以及依赖如下: + ``` + + + com.xuxueli + xxl-job-core + ${最新稳定版} + + ``` +- 2、为适配中央仓库规则, 项目groupId从com.xxl改为com.xuxueli。 +- 3、系统版本不在维护在项目跟pom中,各个子模块单独配置版本配置,解决子模块无法单独编译的问题; +- 4、底层RPC通讯,传输数据的字节长度统计规则优化,可节省50%数据传输量; +- 5、IJobHandler取消任务返回值,原通过返回值判断执行状态,逻辑改为:默认任务执行成功,仅在捕获异常时认定任务执行失败。 +- 6、系统公共弹框功能,插件化; +- 7、底层表结构,表明统一大写; +- 8、调度中心,异常处理器JSON响应的ContentType修改,修复浏览器不识别的问题; + +### 7.8 版本 V1.4.2 新特性[2016-09-29] +- 1、推送新版本 V1.4.2 至中央仓库, 大版本 V1.4 进入维护阶段; +- 2、任务新增时,任务列表偏移问题修复; +- 3、修复一处因bootstrap不支持模态框重叠而导致的样式错乱的问题, 在任务编辑时会出现该问题; +- 4、调度超时和Handler匹配不到时,调度状态优化; +- 5、因catch异常,导致任务不可终止的问题,给出解决方案, 见文档; + +### 7.9 版本 V1.5.0 特性[2016-11-13] +- 1、任务注册: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。 +- 2、"执行器" 新增参数 "AppName" : 是每个执行器集群的唯一标示AppName, 并周期性以AppName为对象进行自动注册。 +- 3、调度中心新增栏目 "执行器管理" : 管理在线的执行器, 通过属性AppName自动发现注册的执行器。只有被管理的执行器才允许被使用; +- 4、"任务组"属性改为"执行器": 每个任务需要绑定指定的执行器, 调度地址通过绑定的执行器获取; +- 5、抛弃"任务机器"属性: 通过任务绑定的执行器, 自动发现注册的远程执行器地址并触发调度请求。 +- 6、"公共依赖"中新增DBGlueLoader,基于原生jdbc实现GLUE源码的加载器,减少第三方依赖(mybatis,spring-orm等);精简和优化执行器测配置(针对GLUE任务),降低上手难度; +- 7、表结构调整,底层重构优化; +- 8、"调度中心"自动注册和发现,failover: 调度中心周期性自动注册, 任务回调时可以感知在线的所有调度中心地址, 通过failover的方式进行任务回调,避免回调单点风险。 + +### 7.10 版本 V1.5.1 特性[2016-11-13] +- 1、底层代码重构和逻辑优化,POM清理以及CleanCode; +- 2、Servlet/JSP Spec设定为3.0/2.2 +- 3、Spring升级至3.2.17.RELEASE版本; +- 4、Jetty升级版本至8.2.0.v20160908; +- 5、已推送V1.5.0和V1.5.1至Maven中央仓库; + +### 7.11 版本 V1.5.2 特性[2017-02-28] +- 1、IP工具类获取IP逻辑优化,IP静态缓存; +- 2、执行器、调度中心,均支持自定义注册IP地址;解决机器多网卡时错误网卡注册的情况; +- 3、任务跨天执行时生成多份日志文件的问题修复; +- 4、底层日志底层日志调整,非敏感日志level调整为debug; +- 5、升级数据库连接池c3p0版本; +- 6、执行器log4j配置优化,去除无效属性; +- 7、底层代码重构和逻辑优化以及CleanCode; +- 8、GLUE依赖注入逻辑优化,支持别名注入; + +### 7.12 版本 V1.6.0 特性[2017-03-13] +- 1、通讯方案升级,原基于HEX的通讯模型调整为基于HTTP的B-RPC的通讯模型; +- 2、执行器支持手动设置执行地址列表,提供开关切换使用注册地址还是手动设置的地址; +- 3、执行器路由规则:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移; +- 4、规范线程模型统一,统一线程销毁方案(通过listener或stop方法,容器销毁时销毁线程;Daemon方式有时不太理想); +- 5、规范系统配置数据,通过配置文件统一管理; +- 6、CleanCode,清理无效的历史参数; +- 7、底层扩展数据结构以及相关表结构调整; +- 8、新建任务默认为非运行状态; +- 9、GLUE模式任务实例更新逻辑优化,原根据超时时间更新改为根据版本号更新,源码变动版本号加一; + +### 7.13 版本 V1.6.1 特性[2017-03-25] +- 1、Rolling日志; +- 2、WebIDE交互重构; +- 3、通讯增强校验,有效过滤非正常请求; +- 4、权限增强校验,采用动态登录TOKEN(推荐接入内部SSO); +- 5、数据库配置优化,解决乱码问题; + +### 7.14 版本 V1.6.2 特性[2017-04-25] +- 1、运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等; +- 2、JobHandler支持设置任务返回值,在任务逻辑中可以方便的控制任务执行结果; +- 3、资源路径包含空格或中文时资源文件无法加载时,无法准确查看异常信息的问题处理。 +- 4、路由策越优化:循环和LFU路由策略计数器自增无上限问题和首次路由压力集中在首台机器的问题修复; + +### 7.15 版本 V1.7.0 特性[2017-05-02] +- 1、脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python和Groovy等类型脚本; +- 2、新增spring-boot类型执行器example项目; +- 3、升级jetty版本至9.2; +- 4、任务运行日志移除log4j组件依赖,改为底层自主实现,从而取消了对日志组件的依赖限制; +- 5、执行器移除GlueLoader依赖,改为推送方式实现,从而GLUE源码加载不再依赖JDBC; +- 6、登录拦截Redirect时获取项目名,解决非根据目录发布时跳转404问题; + +### 7.16 版本 V1.7.1 特性[2017-05-08] +- 1、运行日志读写编码统一为UTF-8,解决windows环境下日志乱码问题; +- 2、通讯超时时间限定为10s,避免异常情况下调度线程占用; +- 3、执行器,server启动、销毁和注册逻辑调整; +- 4、JettyServer关闭逻辑优化,修复执行器无法正常关闭导致端口占用和频繁打印c3p0日志的问题; +- 5、JobHandler中开启子线程时,支持子线程输出执行日志并通过Rolling查看。 +- 6、任务日志清理功能; +- 7、弹框组件统一替换为layer; +- 8、升级quartz版本至2.3.0; + +### 7.17 版本 V1.7.2 特性[2017-05-17] +- 1、阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度; +- 2、失败处理策略;调度失败时的处理策略,策略包括:失败告警(默认)、失败重试; +- 3、通讯时间戳超时时间调整为180s; +- 4、执行器与数据库彻底解耦,但是执行器需要配置调度中心集群地址。调度中心提供API供执行器回调和心跳注册服务,取消调度中心内部jetty,心跳周期调整为30s,心跳失效为三倍心跳; +- 5、执行参数编辑时丢失问题修复; +- 6、新增任务测试Demo,方便在开发时进行任务逻辑测试; + +### 7.18 版本 V1.8.0 特性[2017-07-17] +- 1、任务Cron更新逻辑优化,改为rescheduleJob,同时防止cron重复设置; +- 2、API回调服务失败状态码优化,方便问题排查; +- 3、XxlJobLogger的日志多参数支持; +- 4、路由策略新增 "忙碌转移" 模式:按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度; +- 5、路由策略代码重构; +- 6、执行器重复注册问题修复; +- 7、任务线程轮空30次后自动销毁,降低低频任务的无效线程消耗。 +- 8、执行器任务执行结果批量回调,降低回调频率提升执行器性能; +- 9、springboot版本执行器,取消XML配置,改为类配置方式; +- 10、执行日志,支持根据运行 "状态" 筛选日志; +- 11、调度中心任务注册检测逻辑优化; + +### 7.19 版本 V1.8.1 特性[2017-07-30] +- 1、分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数处理分片任务; +- 2、动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。 +- 3、执行器JobHandler禁止命名冲突; +- 4、执行器集群地址列表进行自然排序; +- 5、调度中心,DAO层代码精简优化并且新增测试用例覆盖; +- 6、调度中心API服务改为自研RPC形式,统一底层通讯模型; +- 7、新增调度中心API服务测试Demo,方便在调度中心API扩展和测试; +- 8、任务列表页交互优化,更换执行器分组时自动刷新任务列表,新建任务时默认定位在当前执行器位置; +- 9、访问令牌(accessToken):为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯; +- 10、springboot版本执行器,升级至1.5.6.RELEASE版本; +- 11、统一maven依赖版本管理; + +### 7.20 版本 V1.8.2 特性[2017-09-04] +- 1、项目主页搭建:提供中英文文档:https://www.xuxueli.com/xxl-job +- 2、JFinal执行器Sample示例项目; +- 3、事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。 +- 4、执行器摘除:执行器销毁时,主动通知调度中心并摘除对应执行器节点,提高执行器状态感知的时效性。 +- 5、执行器手动设置IP时将会绑定Host; +- 6、规范项目目录,方便扩展多执行器; +- 7、解决执行器回调URL不支持配置HTTPS时问题; +- 8、执行器回调线程销毁前, 批量回调队列中数据,防止任务结果丢失; +- 9、调度中心任务监控线程销毁时,批量对失败任务告警,防止告警信息丢失; +- 10、任务日志文件路径时间戳格式化时SimpleDateFormat并发问题解决; + +### 7.21 版本 V1.9.0 特性[2017-12-29] +- 1、新增Nutz执行器Sample示例项目; +- 2、新增任务运行模式 "GLUE模式(NodeJS) ",支持NodeJS脚本任务; +- 3、脚本任务Shell、Python和Nodejs等支持获取分片参数; +- 4、失败重试,完整支持:调度中心调度失败且启用"失败重试"策略时,将会自动重试一次;执行器执行失败且回调失败重试状态(新增失败重试状态返回值)时,也将会自动重试一次; +- 5、失败告警策略扩展:默认提供邮件失败告警,可扩展短信等,扩展代码位置为 "JobFailMonitorHelper.failAlarm"; +- 6、执行器端口支持自动生成(小于等于0时),避免端口定义冲突; +- 7、调度报表优化,支持时间区间筛选; +- 8、Log组件支持输出异常栈信息,底层实现优化; +- 9、告警邮件样式优化,调整为表格形式,邮件组件调整为commons-email简化邮件操作; +- 10、项目依赖全量升级至较新稳定版本,如spring、jackson等等; +- 11、任务日志,记录发起调度的机器信息; +- 12、交互优化,如登录注销; +- 13、任务Cron长度扩展支持至128位,支持负责类型Cron设置; +- 14、执行器地址录入交互优化,地址长度扩展支持至512位,支持大规模执行器集群配置; +- 15、任务参数“IJobHandler.execute”入参改为“String params”,增强入参通用性。 +- 16、IJobHandler提供init/destroy方法,支持在相应任务线程初始化和销毁时进行附加操作; +- 17、任务注解调整为 “@JobHandler”,与任务抽象接口统一; +- 18、修复任务监控线程被耗时任务阻塞的问题; +- 19、修复任务监控线程无法监控任务触发和执行状态均未0的问题; +- 20、执行器动态代理对象,拦截非业务方法的执行; +- 21、修复JobThread捕获Error错误不更新JobLog的问题; +- 22、修复任务列表界面左侧菜单合并时样式错乱问题; +- 23、调度中心项目日志配置改为xml文件格式; +- 24、Log地址格式兼容,支持非"/"结尾路径配置; +- 25、底层系统日志级别规范调整,清理遗留代码; +- 26、建表SQL优化,支持同步创建制定编码的库和表; +- 27、系统安全性优化,登录Token写Cookie时进行MD5加密,同时Cookie启用HttpOnly; +- 28、新增"任务ID"属性,移除"JobKey"属性,前者承担所有功能,方便后续增强任务依赖功能。 +- 29、任务循环依赖问题修复,避免子任务与父任务重复导致的调度死循环; +- 30、任务列表新增筛选条件 "任务描述",快速检索任务; +- 31、执行器Log文件定期清理功能:执行器新增配置项("xxl.job.executor.logretentiondays")日志保存天数,日志文件过期自动删除。 + +### 7.22 版本 V1.9.1 特性[2018-02-22] +- 1、国际化:调度中心实现国际化,支持中文、英文两种语言,默认为中文。 +- 2、调度报表新增"运行中"中状态项; +- 3、调度报表优化,报表SQL调优并且新增LocalCache缓存(缓存时间60s),提高大数据量下报表加载速度; +- 4、修复打包部署时资源文件乱码问题; +- 5、修复新版本chrome滚动到顶部失效问题; +- 6、调度中心配置加载优化,取消对配置文件名的强依赖,支持加载磁盘配置; +- 7、修复脚本任务Log文件未正常close的问题; +- 8、项目依赖全量升级至较新稳定版本,如spring、jackson等等; + +### 7.23 版本 V1.9.2 特性[2018-10-05] +- 1、任务超时控制:新增任务属性 "任务超时时间",并支持自定义,任务运行超时将会主动中断任务; +- 2、任务失败重试次数:新增任务属性 "失败重试次数",并支持自定义,当任务失败时将会按照预设的失败重试次数主动进行重试;同时收敛废弃其他失败重试策略,如调度失败、执行失败、状态码失败等; +- 3、新增任务运行模式 "GLUE模式(PHP) ",支持php脚本任务; +- 4、新增任务运行模式 "GLUE模式(PowerShell) ",支持PowerShell脚本任务; +- 5、调度全异步处理:任务触发之后,推送到调度队列,多线程并发处理调度请求,提高任务调度速率的同时,避免因网络问题导致quartz调度线程阻塞的问题; +- 6、执行器任务结果落盘优化:执行器回调失败时将任务结果写磁盘,待重启或网络恢复时重试回调任务结果,防止任务执行结果丢失; +- 7、任务日志查询速度大幅提升:百万级别数据量搜索速度提升1000倍; +- 8、调度中心提供API服务,支持通过API服务对任务进行查询、新增、更新、启停等操作; +- 9、底层自研Log组件参数占位符改为"{}",并修复打印有参日志时参数不匹配导致报错的问题; +- 10、任务回调结果优化,支持展示在Rolling log中,方便问题排查; +- 11、底层LocalCache组件兼容性优化,支持jdk9、jdk10及以上版本编译部署; +- 12、告警邮件固定使用 UTF-8 编码格式,修复由机器编码导致的邮件乱码问题; +- 13、告警邮件中展示失败告警信息; +- 14、告警邮箱支持SSL配置; +- 15、Window机器下File.separator不兼容问题修复; +- 16、脚本任务异常Log输出优化; +- 17、任务线程停止变量修饰符优化; +- 18、脚本任务Log文件流关闭优化; +- 19、任务报表成功、失败和进行中统计问题修复; +- 20、核心依赖Core内部国际化处理; +- 21、默认Quartz线程数调整为50; +- 22、新增左侧菜单"运行报表"; +- 23、执行器手动设置IP时取消绑定Host的操作,该IP仅供执行器注册使用;修复指定外网IP时无法绑定执行器Host的问题; +- 24、取消父子任务不可重复的限制,支持循环任务触发等特殊场景; +- 25、任务调度备注中标注任务触发类型,如Cron触发、父任务触发、API触发等等,方便排查调度日志; +- 26、底层日志组件SimpleDateFormat线程安全问题修复; +- 27、执行器通讯线程优化,corePoolSize从256降低至32; +- 28、任务日志表状态字段类型优化; +- 29、GLUE脚本文件自动清理功能,及时清理过期脚本文件; +- 30、执行器注册方式切换优化,切换自动注册时主动同步在线机器,避免执行器为空的问题; +- 31、跨平台:除了提供Java、Python、PHP等十来种任务模式之外,新增提供基于HTTP的任务模式; +- 32、底层RPC序列化协议调整为hessian2; +- 33、修复表字段 “t.order”与数据库关键字冲突查询失败的问题, +- 34、任务属性枚举 "任务模式、阻塞策略" 国际化优化; +- 35、分片任务失败重试优化,仅重试当前失败的分片; +- 36、任务触发时支持动态传参,调度中心与API服务均提供提供动态参数功能; +- 37、任务执行日志、调度日志字段类型调整,改为text类型并取消字数限制; +- 38、GLUE任务脚本字段类型调整,改为mediumtext类型,提高GLUE长度上限; +- 39、任务监控线程Log输出优化,运行中任务的监控Log改为debug级别,减少非核心日志量; +- 40、项目依赖全量升级至较新稳定版本,如spring、Jackson、groovy等等; +- 41、docker支持:调度中心提供 Dockerfile 方便快速构建docker镜像; + +### 7.24 版本 V2.0.0 Release Notes[2018-11-04] +- 1、调度中心迁移到 springboot; +- 2、底层通讯组件迁移至 xxl-rpc; +- 3、容器化:提供官方docker镜像,并实时更新推送dockerhub(docker pull xuxueli/xxl-job-admin),进一步实现产品开箱即用; +- 4、新增无框架执行器Sample示例项目 "xxl-job-executor-sample-frameless"。不依赖第三方框架,只需main方法即可启动运行执行器; +- 5、命令行任务:原生提供通用命令行任务Handler(Bean任务,"CommandJobHandler");业务方只需要提供命令行即可; +- 6、任务状态优化,仅运行状态"NORMAL"任务关联至quartz,降低quartz底层数据存储与调度压力; +- 7、任务状态规范:新增任务默认停止状态,任务更新时保持任务状态不变; +- 8、IP获取逻辑优化,优先遍历网卡来获取可用IP; +- 9、任务新增的API服务接口返回任务ID,方便调用方实用; +- 10、组件化优化,移除对 spring 的依赖:非spring应用选用 "XxlJobExecutor" 、spring应用选用 "XxlJobSpringExecutor" 作为执行器组件; +- 11、任务RollingLog展示逻辑优化,修复超时任务无法查看的问题; +- 12、多项UI组件升级到最新版本,如:CodeMirror、Echarts、Jquery 等; +- 13、项目依赖升级 groovy 至较新稳定版本;pom清理; +- 14、子任务失败重试重试逻辑优化,子任务失败时将会按照其预设的失败重试次数主动进行重试 + +### 7.25 版本 v2.0.1 Release Notes[2018-11-09] +- 1、左侧菜单折叠动画问题修复; +- 2、调度报表日期分布图默认值统一; +- 3、freemarker对数字默认加千分位问题修复,解决日志ID被分隔导致查看日志失败问题; +- 4、底层通讯组件升级,修复通讯异常时无效等待的问题; +- 5、执行器启动之后jetty停止的问题修复; + +### 7.26 版本 v2.0.2 Release Notes[2019-04-20] +- 1、底层通讯方案优化:升级较新版本xxl-rpc,由"JETTY"方案调整为"NETTY_HTTP"方案,执行器内嵌netty-http-server提供服务,调度中心复用容器端口提供服务; +- 2、任务告警逻辑调整,改为通过扫描失败日志方式触发。一方面精确扫描失败任务,降低扫描范围;另一方面取消内存队列,降低线程内存消耗; +- 3、Quartz触发线程池废弃并替换为 "XxlJobThreadPool",降低线程切换、内存占用带来的消耗,提高调度性能; +- 4、调度线程池隔离,拆分为"Fast"和"Slow"两个线程池,1分钟窗口期内任务耗时达500ms超过10次,该窗口期内判定为慢任务,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性; +- 5、执行器热部署时JobHandler重新初始化,修复由此导致的 "jobhandler naming conflicts." 问题; +- 6、新增Class的加载缓存,解决频繁加载Class会使jvm的方法区空间不足导致OOM的问题; +- 7、任务支持更换绑定执行器,方便任务分组转移和管理; +- 8、调度中心告警邮件发送组件改为 “spring-boot-starter-mail”; +- 9、记住密码功能优化,选中时永久记住;非选中时关闭浏览器即登出; +- 10、项目依赖升级至较新稳定版本,如quartz、spring、jackson、groovy、xxl-rpc等等; +- 11、精简项目,取消第三方依赖,如 commons-collections4、commons-lang3 ; +- 12、执行器回调日志落盘方案复用RPC序列化方案,并移除Jackson依赖; +- 13、底层Log调优,应用正常终止取消异常栈信息打印; +- 14、交互优化,尽量避免新开页面窗口;仅WebIDE支持新开页,并提供窗口快速关闭按钮;任务启、停、删除、触发等轻操作提示改为toast方式, +- 15、任务暂停、删除优化,避免quartz delete不完整导致任务脏数据; +- 16、任务回调、心跳注册成功日志优化,非核心常规日志调整为debug级别,降低冗余日志输出; +- 17、调整首页报表默认区间为本周,避免日志量太大查询缓慢; +- 18、LRU路由更新不及时问题修复; +- 19、任务失败告警邮件发送逻辑优化; +- 20、调度日志排序逻辑调整为按照调度时间倒序,兼容TIDB等主键不连续日志存储组件; +- 21、执行器优雅停机优化; +- 22、连接池配置优化,增强连接有效性验证; +- 23、JobHandler#msg长度限制,修复异常情况下日志超长导致内存溢出的问题; +- 24、升级xxl-rpc至较新版本,修复springboot 2.x版本兼容性问题; + +### 7.27 版本 v2.1.0 Release Notes[2019-07-07] +- 1、自研调度组件,移除quartz依赖:一方面是为了精简系统降低冗余依赖,另一方面是为了提供系统的可控度与稳定性; + - 触发:单节点周期性触发,运行事件如delayqueue; + - 调度:集群竞争,负载方式协同处理,锁竞争-更新触发信息-推送时间轮-锁释放-锁竞争; +- 2、底层表结构重构:移除11张quartz相关表,并对现有表结构优化梳理; +- 3、任务日志主键调整为long数据类型,防止海量日志情况下数据溢出; +- 4、底层线程模型重构:移除Quartz线程池,降低系统线程与内存开销; +- 5、用户管理:支持在线管理系统用户,存在管理员、普通用户两种角色; +- 6、权限管理:执行器维度进行权限控制,管理员拥有全量权限,普通用户需要分配执行器权限后才允许相关操作; +- 7、调度线程池参数调优; +- 8、注册表索引优化,缓解锁表问题; +- 9、新增Jboot执行器Sample示例项目; +- 10、任务列表优化,支持根据 "任务状态"、"负责人" 属性筛选任务; +- 11、任务日志列表交互优化,操作按钮合并为分割按钮; +- 12、项目依赖升级至较新稳定版本,如spring、springboot、groovy、xxl-rpc等等;并清理冗余POM; +- 13、升级xxl-rpc至较新版本,修复代理服务初始化时远程服务不可用导致长连冗余创建的问题; +- 14、首页调度报表的日期排序在TIDB下乱序问题修复; +- 15、调度中心与执行器双向通讯超时时间调整为3s; +- 16、调度组件销毁流程优化,先停止调度线程,然后等待时间轮内存量任务处理完成,最终销毁时间轮线程; +- 17、执行器回调线程优化,回调地址为空时销毁问题修复; +- 18、HttpJobHandler优化,响应数据指定UTF-8格式,避免中文乱码; +- 19、代码优化,ConcurrentHashMap变量类型改为ConcurrentMap,避免因不同版本实现不同导致的兼容性问题; + +### 7.28 版本 v2.1.1 Release Notes[2019-11-24] +- 1、 调度中心日志自动清理功能(至此,调度中心/执行器均支持日志自动清理,过期天数均默认设置为30天):调度中心新增配置项("xxl.job.logretentiondays")日志保存天数,过期日志自动清理;解决海量日志情况下日志表慢SQL问题;限制大于等于7时生效,否则关闭清理功能,默认为30; +- 2、 调度报表优化:新增日志报表的存储表,三天内的任务日志会以每分钟一次的频率异步同步至报表中;任务报表仅读取报表数据,极大提升加载速度; +- 3、 Cron在线生成工具:任务新增、编辑框通过组件在线生成Cron表达式; +- 4、 Cron下次执行时间查询:支持通过界面在线查看后续连续5次执行时间; +- 5、 调度中心新增应用健康检查功能,借助“spring-boot-starter-actuator”,相对地址 “/actuator/health”; +- 6、 DB脚本默认编码改为utf8mb4,修复字符乱码问题(建议Mysql版本5.7+); +- 7、 调度中心任务平均分配,触发组件每次获取与线程池数量相关数量的任务,避免大量任务集中在单个调度中心集群节点; +- 8、 任务触发组件优化,预加载频率正常1s一次,当预加载轮空时主动休眠一个加载周期,动态降低加载频率从而降低DB压力; +- 9、 调度组件优化:针对永远不会触发的Cron禁止配置和启动;任务Cron最后一次触发后再也不会触发时,比如一次性任务,主动停止相关任务; +- 10、DB重连优化,修复DB宕机重连后任务调度停止的问题,重连后自动加入调度集群触发任务调度; +- 11、注册监控线程优化,降低死锁几率; +- 12、调度中心日志删除优化,改为分页获取ID并根据ID删除的方式,避免批量删除海量日志导致死锁问题; +- 13、任务重试时参数丢失的问题修复; +- 14、调度中心移除SQL中的 "now()" 函数;集群部署时不再依赖DB时钟,仅需要保证调度中心应用节点时钟一致即可; +- 15、任务触发组件加载顺序调整,避免小概率情况下组件随机加载顺序导致的I18N的NPE问题; +- 16、JobThread自销毁优化,避免并发触发导致triggerQueue中任务丢失问题; +- 17、调度中心密码限制18位,修复修改密码超过18位无法登录的问题; +- 18、任务告警组件分页参数无效问题修复; +- 19、升级xxl-rpc版本:服务端线程优化,降低线程内存开销;IpUtil优化:增加连通性校,过滤明确非法的网卡; +- 20、调度中心回调API服务改为restful方式; +- 21、UI优化,任务列表和日志列表数据表格宽度比例调整,避免数据换行提升体验; +- 22、登录界面取消默认填写的登录账号密码; +- 23、执行器表属性调整,"顺序" 属性调整为整型,解决执行器数据较多时无法正确排序的问题; +- 24、任务列表交互优化,支持查看任务所属执行器的注册节点; +- 25、项目依赖升级至较新稳定版本,如spring、spring-boot、mybatis、slf4j、groovy等等; +- 26、日志组件优化:调度中心支持控制每次请求最大加载行数,日志量太大时分批请求,避免单次加载日志量太大阻塞页面; + +### 7.29 版本 v2.1.2 Release Notes[2019-12-12] +- 1、方法任务支持:由原来基于JobHandler类任务开发方式,优化为支持基于方法的任务开发方式;因此,可以支持单个类中开发多个任务方法,进行类复用 +``` +@XxlJob("demoJobHandler") +public ReturnT execute(String param) { + XxlJobLogger.log("hello world"); + return ReturnT.SUCCESS; +} +``` +- 2、移除commons-exec,采用原生方式实现,降低第三方依赖; +- 3、执行器回调乱码问题修复; +- 4、调度中心dispatcher servlet加载顺序优化; +- 5、执行器回调地址https兼容支持; +- 6、多个项目依赖升级至较新稳定版本; +- 注意:最新版本 "XxlJobSpringExecutor" 逻辑有调整,历史项目中该组件的配置方式请参考Sample示例项目进行调整,尤其注意需要移除组件的init和destroy方法; + +### 7.30 版本 v2.2.0 Release Notes[2020-04-14] +- 1、RESTful API:调度中心与执行器提供语言无关的 RESTful API 服务,第三方任意语言可据此对接调度中心或者实现执行器。 +- 2、任务复制功能:点击复制是弹出新建任务弹框,并初始化被复制任务信息; +- 3、任务手动执行一次的时候,支持指定本次执行的机器地址,为空则从执行器获取; +- 4、任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败; +- 5、调度中心升级springboot2.x;因此,系统要求JDK8+; +- 6、XxlJob注解扫描方式优化,支持查找父类以及接口和基于类代理等常见情况;修复任务为空时小概率NPE问题; +- 7、移除旧类注解JobHandler,推荐使用基于方法注解 "@XxlJob" 的方式进行任务开发;(如需保留类注解JobHandler使用方式,可以参考旧版逻辑定制开发); +- 8、任务告警组件模块化:如果需要新增一种告警方式,只需要新增一个实现 "com.xxl.job.admin.core.alarm.JobAlarm" 接口的告警实现即可,更加灵活、方便定制; +- 9、调度中心国际化完善:新增 "中文繁体" 支持。默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文; +- 10、执行器注册逻辑优化:新增配置项 ”注册地址 / xxl.job.executor.address“,优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。 +- 11、默认数据库连接池调整为hikari,移除tomcat-jdbc依赖; +- 12、多个项目依赖升级至较新稳定版本,如mybatis、groovy和mysql驱动等; +- 13、执行器优雅停机优化,修复任务线程中断未join导致回调丢失的问题; +- 14、一致性哈希路由策略优化:默认虚拟节点数量调整为100,提高路由的均衡性; +- 15、通用HTTP任务Handler(httpJobHandler)优化,扩展自定义参数信息,示例参数如下; +``` +url: http://www.xxx.com +method: get 或 post +data: post-data +``` +- 16、SQL脚本编码默认utf8mb4执行,避免小概率下容器环境中乱码问题; +- 17、Web IDE交互问题修复:输入源码备注之后按回车跳转error问题处理; +- 18、执行器初始化逻辑优化:修复懒加载的Bean被提前初始化问题; +- 19、执行器注册默认值优化; +- 20、修复bootstrap.min.css.map 404问题; +- 21、执行器UI交互优化,移除冗余order属性; +- 22、执行备注消息长度限制,修复数据超长无法存储导致导致回调失败的问题; +注意:XxlJobSpringExecutor组件个别字段调整:“appName” 调整为 “appname” ,升级时该组件时需要注意; + +### 7.31 版本 v2.3.0 Release Notes[2021-02-09] +- 1、【新增】调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等; +- 2、【新增】触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 "固定间隔触发、(固定延时触发,实验中)" 新触发方式; +- 3、【新增】新增任务辅助工具 "XxlJobHelper":提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等; + - 3.1、"ShardingUtil" 组件废弃:改用 "XxlJobHelper.getShardIndex()/getShardTotal();" 获取分片参数; + - 3.2、"XxlJobLogger" 组件废弃:改用 "XxlJobHelper.log" 进行日志输出; +- 4、【优化】任务核心类 "IJobHandler" 的 "execute" 方法取消出入参设计。改为通过 "XxlJobHelper.getJobParam" 获取任务参数并替代方法入参,通过 "XxlJobHelper.handleSuccess/handleFail" 设置任务结果并替代方法出参,示例代码如下; +``` +@XxlJob("demoJobHandler") +public void execute() { + String param = XxlJobHelper.getJobParam(); // 获取参数 + XxlJobHelper.handleSuccess(); // 设置任务结果 +} +``` +- 5、【优化】Cron编辑器增强:Cron编辑器修改cron时可实时查看最近运行时间; +- 6、【优化】执行器示例项目规范整理; +- 7、【优化】任务调度生命周期重构:调度(schedule)、触发(trigger)、执行(handle)、回调(callback)、结束(complete); +- 8、【优化】执行器注册组件优化:注册逻辑调整为异步方式,提高注册性能; +- 9、【优化】执行器鉴权校验:执行器启动时主动校验accessToken,为空则主动Warn告警;(已规划安全强化:AccessToken动态生成、动态启停等) +- 10、【优化】邮箱告警配置优化:将"spring.mail.from"与"spring.mail.username"属性拆分开,更加灵活的支持一些无密码邮箱服务; +- 11、【优化】多个项目依赖升级至较新稳定版本,如netty、groovy、spring、springboot、mybatis等; +- 12、【优化】UI组件常规升级,提升组件稳定性; +- 13、【优化】调度中心页面交互优化:用户管理模块密码列取消;多处表达autocomplete取消;执行器管理模块XSS拦截校验等; +- 14、【优化】调度中心任务状态探测慢SQL问题优化; +- 15、【修复】GLUE-Java模式任务,init/destroy无法执行问题修复; +- 16、【修复】Cron编辑器问题修复:修复小概率情况下cron单个字段修改时导致其他字段被重置问题; +- 17、【修复】通用HTTP任务Handler(httpJobHandler)优化:修复 "setDoOutput(true)" 导致任务请求GetMethod失效问题; +- 18、【修复】执行器Commandhandler示例任务优化,修复极端情况下脚本进程挂起问题; +- 19、【修复】调度通讯组件优化,修复RestFul方式调用 DotNet 版本执行器时心跳检测失败问题; +- 20、【修复】调度中心远程执行日志查询乱码问题修复; +- 21、【修复】调度中心组件加载顺序优化,修复极端情况下调度组件初始慢导致的调度失败问题; +- 22、【修复】执行器注册线程优化,修复极端情况下初始化失败时导致NPE问题; +- 23、【修复】调度线程连接池优化,修复连接有效性校验超时问题; +- 24、【修复】执行器注册表字段优化,解决执行器注册节点过多导致注册信息存储和更新失败的问题; +- 25、【修复】轮训路由策略优化,修复小概率下并发问题; +- 26、【修复】页面redirect跳转后https变为http问题修复; +- 27、【修复】执行器日志清理优化,修复小概率下日志文件为空导致清理异常问题; + + +### 7.32 版本 v2.4.0 Release Notes[规划中] +- 1、【优化】[规划中]任务日志重构:一次调度只记录一条主任务,维护起止时间和状态。 + - 普通任务:只记录一条主任务; + - 广播任务:记录一条主任务,每个分片任务记录一条次任务,关联在主任务上; + - 重试任务:失败时,新增主任务。所有调度记录,包括入口调度和重试调度,均挂载主任务上。 +- 2、【优化】[规划中]分片任务:全部完成后才会出发后置节点; +- 3、[规划中]DAG流程任务 + - DAG任务:支持参数传递,共享数据:DAG任务创建、管理,DAG任务日志查看、操作; + - 子任务:废弃 +- 4、[规划中]多数据库支持,DAO层通过JPA实现,不限制数据库类型; +- 5、[规划中]告警增强:邮件告警 + webhook告警; +- 6、[规划中]安全强化:AccessToken动态生成、动态启停;控制调度、回调; + +### TODO LIST +- 1、任务分片路由:分片采用一致性Hash算法计算出尽量稳定的分片顺序,即使注册机器存在波动也不会引起分批分片顺序大的波动;目前采用IP自然排序,可以满足需求,待定; +- 2、调度隔离:调度中心针对不同执行器,各自维护不同的调度和远程触发组件。 +- 3、调度任务优先级; +- 4、多数据库支持,DAO层通过JPA实现,不限制数据库类型; +- 5、执行器Log清理功能:调度中心Log删除时同步删除执行器中的Log文件; +- 6、延时任务:API触发,支持"动态传参、延时消费";该功能与 XXL-MQ 冲突,该场景建议用后者; +- 7、调度线程池改为协程方式实现,大幅降低系统内存消耗; +- 8、任务、执行器数据全量本地缓存;新增消息表广播通知; +- 9、忙碌转移优化,全部机器忙碌时不再直接失败; +- 10、任务触发参数优化:支持选择 "Cron触发"、"固定间隔时间触发"、"指定时间点触发"、"不选择" 等; +- 11、调度日志列表加上执行时长列,并支持排序; +- 12、DAG流程任务: + - 替换子任务,支持参数传递,共享数据: + - 配置并列的"a-b、b-c"路径列表,构成串行、并行、dag任务流程,"dagre-d3"绘图;任务依赖,流程图,子任务+会签任务,各节点日志;支持根据成功、失败选择分支; + - 分片任务:全部完成后才会出发后置节点; +- 13、日期过滤:支持多个时间段排除; +- 14、告警增强: + - 邮件告警:支持自定义标题、模板格式; + - webhook告警:支持自定义告警URL、请求体格式; +- 15、新增任务运行模式 "GLUE模式(GO) ",支持GO任务; +- 16、GLUE 模式 Web Ide 版本对比功能; +- 17、注册中心优化,实时性注册发现:心跳注册间隔10s,refresh失败则首次注册并立即更新注册信息,心跳类似;30s过期销毁; +- 18、提供执行器Docker镜像; +- 19、脚本任务,支持数据参数,新版本仅支持单参数不支持需要兼容; +- 20、批量调度:调度请求入queue,调度线程批量获取调度请求并发起远程调度;提高线程效率; +- 21、执行器端口复用,复用容器端口提供通讯服务; +- 22、分片任务全部成功后触发子任务; +- 23、新增执行器描述属性;任务名称属性; +- 24、自定义失败重试时间间隔; +- 25、任务标签:方便搜索; +- 26、执行器:dag执行器,不需要注册机器; + + +## 八、其他 + +### 8.1 项目贡献 +欢迎参与项目贡献!比如提交PR修复一个bug,或者新建 [Issue](https://github.com/xuxueli/xxl-job/issues/) 讨论新特性或者变更。 + +### 8.2 用户接入登记 +更多接入的公司,欢迎在 [登记地址](https://github.com/xuxueli/xxl-job/issues/1 ) 登记,登记仅仅为了产品推广。 + +### 8.3 开源协议和版权 +产品开源免费,并且将持续提供免费的社区技术支持。个人或企业内部可自由的接入和使用。 + +- Licensed under the GNU General Public License (GPL) v3. +- Copyright (c) 2015-present, xuxueli. + +--- +### 捐赠 +无论捐赠金额多少都足够表达您这份心意,非常感谢 :) [前往捐赠](https://www.xuxueli.com/page/donate.html ) diff --git a/xxl-job-2.3.0/doc/XXL-JOB架构图.pptx b/xxl-job-2.3.0/doc/XXL-JOB架构图.pptx new file mode 100644 index 0000000..5445216 Binary files /dev/null and b/xxl-job-2.3.0/doc/XXL-JOB架构图.pptx differ diff --git a/xxl-job-2.3.0/doc/db/tables_xxl_job.sql b/xxl-job-2.3.0/doc/db/tables_xxl_job.sql new file mode 100644 index 0000000..02e4442 --- /dev/null +++ b/xxl-job-2.3.0/doc/db/tables_xxl_job.sql @@ -0,0 +1,122 @@ +# +# XXL-JOB v2.3.0 +# Copyright (c) 2015-present, xuxueli. + +CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci; +use `xxl_job`; + +SET NAMES utf8mb4; + +CREATE TABLE `xxl_job_info` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_group` int(11) NOT NULL COMMENT '执行器主键ID', + `job_desc` varchar(255) NOT NULL, + `add_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL, + `author` varchar(64) DEFAULT NULL COMMENT '作者', + `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件', + `schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型', + `schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型', + `misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略', + `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略', + `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler', + `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数', + `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略', + `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒', + `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数', + `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型', + `glue_source` mediumtext COMMENT 'GLUE源代码', + `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注', + `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间', + `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔', + `trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行', + `trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间', + `trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `job_group` int(11) NOT NULL COMMENT '执行器主键ID', + `job_id` int(11) NOT NULL COMMENT '任务,主键ID', + `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址', + `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler', + `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数', + `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2', + `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数', + `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间', + `trigger_code` int(11) NOT NULL COMMENT '调度-结果', + `trigger_msg` text COMMENT '调度-日志', + `handle_time` datetime DEFAULT NULL COMMENT '执行-时间', + `handle_code` int(11) NOT NULL COMMENT '执行-状态', + `handle_msg` text COMMENT '执行-日志', + `alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败', + PRIMARY KEY (`id`), + KEY `I_trigger_time` (`trigger_time`), + KEY `I_handle_code` (`handle_code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_log_report` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间', + `running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量', + `suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量', + `fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量', + `update_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_logglue` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_id` int(11) NOT NULL COMMENT '任务,主键ID', + `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型', + `glue_source` mediumtext COMMENT 'GLUE源代码', + `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注', + `add_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_registry` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `registry_group` varchar(50) NOT NULL, + `registry_key` varchar(255) NOT NULL, + `registry_value` varchar(255) NOT NULL, + `update_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_group` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `app_name` varchar(64) NOT NULL COMMENT '执行器AppName', + `title` varchar(12) NOT NULL COMMENT '执行器名称', + `address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入', + `address_list` text COMMENT '执行器地址列表,多地址逗号分隔', + `update_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL COMMENT '账号', + `password` varchar(50) NOT NULL COMMENT '密码', + `role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员', + `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割', + PRIMARY KEY (`id`), + UNIQUE KEY `i_username` (`username`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `xxl_job_lock` ( + `lock_name` varchar(50) NOT NULL COMMENT '锁名称', + PRIMARY KEY (`lock_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' ); +INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', ''); +INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL); +INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock'); + +commit; + diff --git a/xxl-job-2.3.0/doc/images/cnblog-首页-每日一博-第一.png b/xxl-job-2.3.0/doc/images/cnblog-首页-每日一博-第一.png new file mode 100644 index 0000000..f292d3e Binary files /dev/null and b/xxl-job-2.3.0/doc/images/cnblog-首页-每日一博-第一.png differ diff --git a/xxl-job-2.3.0/doc/images/cnblog-首页-热门动弹-第一.png b/xxl-job-2.3.0/doc/images/cnblog-首页-热门动弹-第一.png new file mode 100644 index 0000000..a594c06 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/cnblog-首页-热门动弹-第一.png differ diff --git a/xxl-job-2.3.0/doc/images/donate-alipay.jpg b/xxl-job-2.3.0/doc/images/donate-alipay.jpg new file mode 100644 index 0000000..78472ce Binary files /dev/null and b/xxl-job-2.3.0/doc/images/donate-alipay.jpg differ diff --git a/xxl-job-2.3.0/doc/images/donate-paypal.png b/xxl-job-2.3.0/doc/images/donate-paypal.png new file mode 100644 index 0000000..24e78a4 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/donate-paypal.png differ diff --git a/xxl-job-2.3.0/doc/images/donate-wechat.png b/xxl-job-2.3.0/doc/images/donate-wechat.png new file mode 100644 index 0000000..4d16dab Binary files /dev/null and b/xxl-job-2.3.0/doc/images/donate-wechat.png differ diff --git a/xxl-job-2.3.0/doc/images/gitee-gvp.jpg b/xxl-job-2.3.0/doc/images/gitee-gvp.jpg new file mode 100644 index 0000000..dcc195b Binary files /dev/null and b/xxl-job-2.3.0/doc/images/gitee-gvp.jpg differ diff --git a/xxl-job-2.3.0/doc/images/img_1001.png b/xxl-job-2.3.0/doc/images/img_1001.png new file mode 100644 index 0000000..549880b Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_1001.png differ diff --git a/xxl-job-2.3.0/doc/images/img_1002.png b/xxl-job-2.3.0/doc/images/img_1002.png new file mode 100644 index 0000000..411f8ec Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_1002.png differ diff --git a/xxl-job-2.3.0/doc/images/img_6yC0.png b/xxl-job-2.3.0/doc/images/img_6yC0.png new file mode 100644 index 0000000..01bf573 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_6yC0.png differ diff --git a/xxl-job-2.3.0/doc/images/img_BPLG.png b/xxl-job-2.3.0/doc/images/img_BPLG.png new file mode 100644 index 0000000..c928205 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_BPLG.png differ diff --git a/xxl-job-2.3.0/doc/images/img_EB65.png b/xxl-job-2.3.0/doc/images/img_EB65.png new file mode 100644 index 0000000..ccf222d Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_EB65.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Fgql.png b/xxl-job-2.3.0/doc/images/img_Fgql.png new file mode 100644 index 0000000..f884051 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Fgql.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Hr2T.png b/xxl-job-2.3.0/doc/images/img_Hr2T.png new file mode 100644 index 0000000..4b5a73c Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Hr2T.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Qohm.png b/xxl-job-2.3.0/doc/images/img_Qohm.png new file mode 100644 index 0000000..854b6c8 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Qohm.png differ diff --git a/xxl-job-2.3.0/doc/images/img_UDSo.png b/xxl-job-2.3.0/doc/images/img_UDSo.png new file mode 100644 index 0000000..a0b81a4 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_UDSo.png differ diff --git a/xxl-job-2.3.0/doc/images/img_V3vF.png b/xxl-job-2.3.0/doc/images/img_V3vF.png new file mode 100644 index 0000000..4607c84 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_V3vF.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Wb2o.png b/xxl-job-2.3.0/doc/images/img_Wb2o.png new file mode 100644 index 0000000..fec8dca Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Wb2o.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Ypik.png b/xxl-job-2.3.0/doc/images/img_Ypik.png new file mode 100644 index 0000000..6b4a2dd Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Ypik.png differ diff --git a/xxl-job-2.3.0/doc/images/img_Z9Qr.png b/xxl-job-2.3.0/doc/images/img_Z9Qr.png new file mode 100644 index 0000000..2bfb044 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_Z9Qr.png differ diff --git a/xxl-job-2.3.0/doc/images/img_ZAhX.png b/xxl-job-2.3.0/doc/images/img_ZAhX.png new file mode 100644 index 0000000..4a6039a Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_ZAhX.png differ diff --git a/xxl-job-2.3.0/doc/images/img_ZAsz.png b/xxl-job-2.3.0/doc/images/img_ZAsz.png new file mode 100644 index 0000000..bbb83ec Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_ZAsz.png differ diff --git a/xxl-job-2.3.0/doc/images/img_dNUJ.png b/xxl-job-2.3.0/doc/images/img_dNUJ.png new file mode 100644 index 0000000..a1a57a0 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_dNUJ.png differ diff --git a/xxl-job-2.3.0/doc/images/img_eYrv.png b/xxl-job-2.3.0/doc/images/img_eYrv.png new file mode 100644 index 0000000..3f9c5e9 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_eYrv.png differ diff --git a/xxl-job-2.3.0/doc/images/img_hIci.png b/xxl-job-2.3.0/doc/images/img_hIci.png new file mode 100644 index 0000000..0529209 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_hIci.png differ diff --git a/xxl-job-2.3.0/doc/images/img_iUw0.png b/xxl-job-2.3.0/doc/images/img_iUw0.png new file mode 100644 index 0000000..b746000 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_iUw0.png differ diff --git a/xxl-job-2.3.0/doc/images/img_inc8.png b/xxl-job-2.3.0/doc/images/img_inc8.png new file mode 100644 index 0000000..e1d38d6 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_inc8.png differ diff --git a/xxl-job-2.3.0/doc/images/img_jOAU.png b/xxl-job-2.3.0/doc/images/img_jOAU.png new file mode 100644 index 0000000..beddc97 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_jOAU.png differ diff --git a/xxl-job-2.3.0/doc/images/img_jrdI.png b/xxl-job-2.3.0/doc/images/img_jrdI.png new file mode 100644 index 0000000..69b38c0 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_jrdI.png differ diff --git a/xxl-job-2.3.0/doc/images/img_o8HQ.png b/xxl-job-2.3.0/doc/images/img_o8HQ.png new file mode 100644 index 0000000..46b5bd0 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_o8HQ.png differ diff --git a/xxl-job-2.3.0/doc/images/img_tJOq.png b/xxl-job-2.3.0/doc/images/img_tJOq.png new file mode 100644 index 0000000..f3d0062 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_tJOq.png differ diff --git a/xxl-job-2.3.0/doc/images/img_tvGI.png b/xxl-job-2.3.0/doc/images/img_tvGI.png new file mode 100644 index 0000000..4b2265a Binary files /dev/null and b/xxl-job-2.3.0/doc/images/img_tvGI.png differ diff --git a/xxl-job-2.3.0/doc/images/qq群-一个xxl同学进了58.png b/xxl-job-2.3.0/doc/images/qq群-一个xxl同学进了58.png new file mode 100644 index 0000000..a525e0b Binary files /dev/null and b/xxl-job-2.3.0/doc/images/qq群-一个xxl同学进了58.png differ diff --git a/xxl-job-2.3.0/doc/images/xxl-logo.jpg b/xxl-job-2.3.0/doc/images/xxl-logo.jpg new file mode 100644 index 0000000..0169cce Binary files /dev/null and b/xxl-job-2.3.0/doc/images/xxl-logo.jpg differ diff --git a/xxl-job-2.3.0/doc/images/xxl-logo.png b/xxl-job-2.3.0/doc/images/xxl-logo.png new file mode 100644 index 0000000..045c006 Binary files /dev/null and b/xxl-job-2.3.0/doc/images/xxl-logo.png differ diff --git a/xxl-job-2.3.0/pom.xml b/xxl-job-2.3.0/pom.xml new file mode 100644 index 0000000..9106098 --- /dev/null +++ b/xxl-job-2.3.0/pom.xml @@ -0,0 +1,117 @@ + + 4.0.0 + com.xuxueli + xxl-job + 2.3.0 + pom + + ${project.artifactId} + A distributed task scheduling framework. + https://www.xuxueli.com/ + + + xxl-job-core + xxl-job-admin + + + + UTF-8 + UTF-8 + UTF-8 + 1.8 + 1.8 + true + + 4.1.58.Final + 2.8.6 + + 5.3.3 + 2.7.18 + + 2.1.4 + 8.0.23 + + 1.7.30 + 5.7.1 + 1.3.2 + + 3.0.7 + + 3.2.1 + 3.2.0 + 1.6 + 3.3.1 + + 2021.0.9 + + + + + release + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + package + + jar + + + none + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + false + + + + verify + + sign + + + + + + + + + oss + https://oss.sonatype.org/content/repositories/snapshots/ + + + oss + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/.gitignore b/xxl-job-2.3.0/xxl-job-admin/.gitignore new file mode 100644 index 0000000..b501cc2 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/.gitignore @@ -0,0 +1,18 @@ +*.class + +# Package Files # +*.war +*.ear + +class +.idea +*.iml +.settings +*.classpath +/bin +/images/ +classes +/target/ +/.project/ +/.metadata/ +/logs/ \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/Dockerfile b/xxl-job-2.3.0/xxl-job-admin/Dockerfile new file mode 100644 index 0000000..dc19537 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/Dockerfile @@ -0,0 +1,11 @@ +FROM openjdk:8-jre-slim +MAINTAINER xuxueli + +ENV PARAMS="" + +ENV TZ=PRC +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +ADD target/xxl-job-admin-*.jar /app.jar + +ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"] \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/hs_err_pid41516.log b/xxl-job-2.3.0/xxl-job-admin/hs_err_pid41516.log new file mode 100644 index 0000000..cd52b94 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/hs_err_pid41516.log @@ -0,0 +1,298 @@ +# +# There is insufficient memory for the Java Runtime Environment to continue. +# Native memory allocation (malloc) failed to allocate 32744 bytes for ChunkPool::allocate +# Possible reasons: +# The system is out of physical RAM or swap space +# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap +# Possible solutions: +# Reduce memory load on the system +# Increase physical memory or swap space +# Check if swap backing store is full +# Decrease Java heap size (-Xmx/-Xms) +# Decrease number of Java threads +# Decrease Java thread stack sizes (-Xss) +# Set larger code cache with -XX:ReservedCodeCacheSize= +# JVM is running with Zero Based Compressed Oops mode in which the Java heap is +# placed in the first 32GB address space. The Java Heap base address is the +# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress +# to set the Java Heap base and to place the Java Heap above 32GB virtual address. +# This output file may be truncated or incomplete. +# +# Out of Memory Error (allocation.cpp:272), pid=41516, tid=0x0000000000009820 +# +# JRE version: Java(TM) SE Runtime Environment (8.0_441) (build 1.8.0_441-b07) +# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.441-b07 mixed mode windows-amd64 compressed oops) +# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows +# + +--------------- T H R E A D --------------- + +Current thread (0x0000016c2b038000): JavaThread "C2 CompilerThread4" daemon [_thread_in_native, id=38944, stack(0x000000315df00000,0x000000315e000000)] + +Stack: [0x000000315df00000,0x000000315e000000] +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +V [jvm.dll+0x34ba99] +V [jvm.dll+0x288e12] +V [jvm.dll+0x2899e0] +V [jvm.dll+0x27dc65] +V [jvm.dll+0xda38d] +V [jvm.dll+0xda71c] +V [jvm.dll+0x50160] +V [jvm.dll+0x4fed6] +V [jvm.dll+0x53966] +V [jvm.dll+0x535e8] +V [jvm.dll+0x529be] +V [jvm.dll+0x405b0] +V [jvm.dll+0x449e48] +V [jvm.dll+0x47269c] +V [jvm.dll+0x4743ed] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x44dc24] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x44dc24] +V [jvm.dll+0x47447f] +V [jvm.dll+0x50427c] +V [jvm.dll+0x4fc2d4] +V [jvm.dll+0x4fb92a] +V [jvm.dll+0x4f996a] +V [jvm.dll+0x44cf00] +V [jvm.dll+0x460b00] +V [jvm.dll+0x44abbc] +V [jvm.dll+0xaf385] +V [jvm.dll+0xada9f] +V [jvm.dll+0x24e539] +V [jvm.dll+0x2a595c] +C [ucrtbase.dll+0x37b0] +C [KERNEL32.DLL+0x2e8d7] +C [ntdll.dll+0xbbf2c] + + +Current CompileTask: +C2: 8323 694 4 org.codehaus.plexus.util.InterpolationFilterReader::read (477 bytes) + + +--------------- P R O C E S S --------------- + +Java Threads: ( => current thread ) + 0x0000016c2b0f0800 JavaThread "Service Thread" daemon [_thread_blocked, id=41824, stack(0x000000315e700000,0x000000315e800000)] + 0x0000016c2b03e800 JavaThread "C1 CompilerThread11" daemon [_thread_blocked, id=39324, stack(0x000000315e600000,0x000000315e700000)] + 0x0000016c2b03e000 JavaThread "C1 CompilerThread10" daemon [_thread_blocked, id=6832, stack(0x000000315e500000,0x000000315e600000)] + 0x0000016c2b03a000 JavaThread "C1 CompilerThread9" daemon [_thread_blocked, id=6836, stack(0x000000315e400000,0x000000315e500000)] + 0x0000016c2b03d000 JavaThread "C1 CompilerThread8" daemon [_thread_blocked, id=45736, stack(0x000000315e300000,0x000000315e400000)] + 0x0000016c2b03c800 JavaThread "C2 CompilerThread7" daemon [_thread_blocked, id=43500, stack(0x000000315e200000,0x000000315e300000)] + 0x0000016c2b03b000 JavaThread "C2 CompilerThread6" daemon [_thread_blocked, id=10568, stack(0x000000315e100000,0x000000315e200000)] + 0x0000016c2b039000 JavaThread "C2 CompilerThread5" daemon [_thread_blocked, id=29904, stack(0x000000315e000000,0x000000315e100000)] +=>0x0000016c2b038000 JavaThread "C2 CompilerThread4" daemon [_thread_in_native, id=38944, stack(0x000000315df00000,0x000000315e000000)] + 0x0000016c2b037800 JavaThread "C2 CompilerThread3" daemon [_thread_blocked, id=19692, stack(0x000000315de00000,0x000000315df00000)] + 0x0000016c2b031800 JavaThread "C2 CompilerThread2" daemon [_thread_in_native, id=14816, stack(0x000000315dd00000,0x000000315de00000)] + 0x0000016c2b02e000 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=8816, stack(0x000000315dc00000,0x000000315dd00000)] + 0x0000016c2b02c000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=13332, stack(0x000000315db00000,0x000000315dc00000)] + 0x0000016c2afeb000 JavaThread "Attach Listener" daemon [_thread_blocked, id=14780, stack(0x000000315d900000,0x000000315da00000)] + 0x0000016c2b001000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=7120, stack(0x000000315d800000,0x000000315d900000)] + 0x0000016c28f34800 JavaThread "Finalizer" daemon [_thread_blocked, id=29504, stack(0x000000315d700000,0x000000315d800000)] + 0x0000016c2af82000 JavaThread "Reference Handler" daemon [_thread_blocked, id=21136, stack(0x000000315d600000,0x000000315d700000)] + 0x0000016c04ecf000 JavaThread "main" [_thread_in_native, id=46548, stack(0x000000315c600000,0x000000315c700000)] + +Other Threads: + 0x0000016c28f1f000 VMThread [stack: 0x000000315d500000,0x000000315d600000] [id=28612] + 0x0000016c2b139800 WatcherThread [stack: 0x000000315e800000,0x000000315e900000] [id=18396] + +VM state:not at safepoint (normal execution) + +VM Mutex/Monitor currently owned by a thread: None + +heap address: 0x00000005c8800000, size: 8056 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 +Narrow klass base: 0x0000000000000000, Narrow klass shift: 3 +Compressed class space size: 1073741824 Address: 0x00000007c0000000 + +Heap: + PSYoungGen total 150528K, used 43868K [0x0000000718300000, 0x0000000722b00000, 0x00000007c0000000) + eden space 129024K, 34% used [0x0000000718300000,0x000000071add72c0,0x0000000720100000) + from space 21504K, 0% used [0x0000000721600000,0x0000000721600000,0x0000000722b00000) + to space 21504K, 0% used [0x0000000720100000,0x0000000720100000,0x0000000721600000) + ParOldGen total 344064K, used 0K [0x00000005c8800000, 0x00000005dd800000, 0x0000000718300000) + object space 344064K, 0% used [0x00000005c8800000,0x00000005c8800000,0x00000005dd800000) + Metaspace used 8930K, capacity 9052K, committed 9344K, reserved 1056768K + class space used 1049K, capacity 1080K, committed 1152K, reserved 1048576K + +Card table byte_map: [0x0000016c15f80000,0x0000016c16f40000] byte_map_base: 0x0000016c1313c000 + +Marking Bits: (ParMarkBitMap*) 0x00007fffab8b0200 + Begin Bits: [0x0000016c179c0000, 0x0000016c1f7a0000) + End Bits: [0x0000016c1f7a0000, 0x0000016c27580000) + +Polling page: 0x0000016c05170000 + +CodeCache: size=245760Kb used=4906Kb max_used=4926Kb free=240853Kb + bounds [0x0000016c06bc0000, 0x0000016c070a0000, 0x0000016c15bc0000] + total_blobs=1027 nmethods=697 adapters=240 + compilation: enabled + +Compilation events (10 events): +Event: 1.868 Thread 0x0000016c2b02e000 690 4 java.nio.CharBuffer::arrayOffset (35 bytes) +Event: 1.868 Thread 0x0000016c2b03c800 691 4 org.codehaus.plexus.util.xml.XmlReader::read (11 bytes) +Event: 1.868 Thread 0x0000016c2b02c000 692 4 java.io.Reader::read (21 bytes) +Event: 1.868 Thread 0x0000016c2b02e000 nmethod 690 0x0000016c0706af10 code [0x0000016c0706b040, 0x0000016c0706b0d8] +Event: 1.868 Thread 0x0000016c2b03e000 nmethod 680 0x0000016c0706c6d0 code [0x0000016c0706cbe0, 0x0000016c07070510] +Event: 1.868 Thread 0x0000016c2b038000 694 4 org.codehaus.plexus.util.InterpolationFilterReader::read (477 bytes) +Event: 1.868 Thread 0x0000016c2b031800 693 4 java.io.InputStreamReader::read (11 bytes) +Event: 1.869 Thread 0x0000016c2b03d000 695 3 org.codehaus.plexus.util.xml.pull.MXParser::more (79 bytes) +Event: 1.869 Thread 0x0000016c2b03e000 696 3 org.codehaus.plexus.util.xml.pull.MXParser::isS (30 bytes) +Event: 1.869 Thread 0x0000016c2b03d000 nmethod 695 0x0000016c0706c190 code [0x0000016c0706c300, 0x0000016c0706c5d0] + +GC Heap History (0 events): +No events + +Deoptimization events (3 events): +Event: 0.576 Thread 0x0000016c04ecf000 Uncommon trap: reason=loop_limit_check action=maybe_recompile pc=0x0000016c06f3c5dc method=java.lang.String.equals(Ljava/lang/Object;)Z @ 56 +Event: 0.623 Thread 0x0000016c04ecf000 Uncommon trap: reason=loop_limit_check action=maybe_recompile pc=0x0000016c06f75708 method=java.lang.String.indexOf([CII[CIII)I @ 79 +Event: 1.866 Thread 0x0000016c04ecf000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000016c06f87428 method=org.codehaus.plexus.util.xml.pull.MXParser.more()C @ 8 + +Classes redefined (0 events): +No events + +Internal exceptions (7 events): +Event: 0.044 Thread 0x0000016c04ecf000 Exception (0x0000000718307ce8) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1 +Event: 0.044 Thread 0x0000016c04ecf000 Exception (0x0000000718307fd0) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\sh +Event: 0.125 Thread 0x0000016c04ecf000 Exception (0x00000007183dad78) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\share\vm\prims\jni.cpp, line 710] +Event: 0.125 Thread 0x0000016c04ecf000 Exception (0x00000007183db4b0) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\share\vm\prims\jvm.cpp, line 1513] +Event: 0.125 Thread 0x0000016c04ecf000 Exception (0x00000007183db6c0) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\share\vm\prims\jvm.cpp, line 1513] +Event: 0.235 Thread 0x0000016c04ecf000 Exception (0x0000000718c11e08) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\share\vm\prims\jvm.cpp, line 1513] +Event: 0.235 Thread 0x0000016c04ecf000 Exception (0x0000000718c12200) thrown at [C:\jenkins\workspace\8-2-build-windows-x64-cygwin-sans-NAS\jdk8u441\1521\hotspot\src\share\vm\prims\jvm.cpp, line 1513] + +Events (10 events): +Event: 1.862 loading class org/codehaus/plexus/component/annotations/Component done +Event: 1.862 loading class org/eclipse/sisu/plexus/ComponentImpl +Event: 1.862 loading class org/eclipse/sisu/plexus/ComponentImpl done +Event: 1.865 loading class org/eclipse/sisu/space/Streams +Event: 1.865 loading class org/eclipse/sisu/space/Streams done +Event: 1.866 Thread 0x0000016c04ecf000 Uncommon trap: trap_request=0xffffff65 fr.pc=0x0000016c06f87428 +Event: 1.866 Thread 0x0000016c04ecf000 DEOPT PACKING pc=0x0000016c06f87428 sp=0x000000315c6fe1c0 +Event: 1.866 Thread 0x0000016c04ecf000 DEOPT UNPACKING pc=0x0000016c06c058c3 sp=0x000000315c6fe158 mode 2 +Event: 1.869 loading class org/eclipse/sisu/plexus/RequirementImpl +Event: 1.869 loading class org/eclipse/sisu/plexus/RequirementImpl done + + +Dynamic libraries: +0x00007ff6b2b80000 - 0x00007ff6b2bcf000 C:\Program Files\Java\jdk-1.8\bin\java.exe +0x00007ff870480000 - 0x00007ff8706e3000 C:\Windows\SYSTEM32\ntdll.dll +0x00007ff86f2c0000 - 0x00007ff86f387000 C:\Windows\System32\KERNEL32.DLL +0x00007ff86d9d0000 - 0x00007ff86dd97000 C:\Windows\System32\KERNELBASE.dll +0x00007ff86fa20000 - 0x00007ff86fad4000 C:\Windows\System32\ADVAPI32.dll +0x00007ff870380000 - 0x00007ff870429000 C:\Windows\System32\msvcrt.dll +0x00007ff86ebf0000 - 0x00007ff86ec96000 C:\Windows\System32\sechost.dll +0x00007ff86f1a0000 - 0x00007ff86f2b6000 C:\Windows\System32\RPCRT4.dll +0x00007ff870140000 - 0x00007ff870309000 C:\Windows\System32\USER32.dll +0x00007ff86d820000 - 0x00007ff86d847000 C:\Windows\System32\win32u.dll +0x00007ff870110000 - 0x00007ff87013a000 C:\Windows\System32\GDI32.dll +0x00007ff86de40000 - 0x00007ff86df6b000 C:\Windows\System32\gdi32full.dll +0x00007ff86df70000 - 0x00007ff86e013000 C:\Windows\System32\msvcp_win.dll +0x00007ff86e0b0000 - 0x00007ff86e1fc000 C:\Windows\System32\ucrtbase.dll +0x00007ff84d8a0000 - 0x00007ff84db30000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.3037_none_3e09262ce333c378\COMCTL32.dll +0x00007ff870310000 - 0x00007ff87033f000 C:\Windows\System32\IMM32.DLL +0x00007ff858ed0000 - 0x00007ff858eeb000 C:\Program Files\Java\jdk-1.8\jre\bin\vcruntime140.dll +0x00007ff828b90000 - 0x00007ff828b9c000 C:\Program Files\Java\jdk-1.8\jre\bin\vcruntime140_1.dll +0x00007ff828b00000 - 0x00007ff828b8e000 C:\Program Files\Java\jdk-1.8\jre\bin\msvcp140.dll +0x00007fffab080000 - 0x00007fffab92a000 C:\Program Files\Java\jdk-1.8\jre\bin\server\jvm.dll +0x00007ff870430000 - 0x00007ff870438000 C:\Windows\System32\PSAPI.DLL +0x00007ff83a3b0000 - 0x00007ff83a3ba000 C:\Windows\SYSTEM32\WSOCK32.dll +0x00007ff8641b0000 - 0x00007ff8641bb000 C:\Windows\SYSTEM32\VERSION.dll +0x00007ff8641c0000 - 0x00007ff8641f6000 C:\Windows\SYSTEM32\WINMM.dll +0x00007ff870090000 - 0x00007ff870104000 C:\Windows\System32\WS2_32.dll +0x00007ff86c650000 - 0x00007ff86c66a000 C:\Windows\SYSTEM32\kernel.appcore.dll +0x00007ff828af0000 - 0x00007ff828b00000 C:\Program Files\Java\jdk-1.8\jre\bin\verify.dll +0x00007ff828ac0000 - 0x00007ff828aeb000 C:\Program Files\Java\jdk-1.8\jre\bin\java.dll +0x00007ff8310e0000 - 0x00007ff831117000 C:\Program Files\Java\jdk-1.8\jre\bin\instrument.dll +0x00007ff828aa0000 - 0x00007ff828ab8000 C:\Program Files\Java\jdk-1.8\jre\bin\zip.dll +0x00007ff86e2c0000 - 0x00007ff86e9c4000 C:\Windows\System32\SHELL32.dll +0x00007ff86b4f0000 - 0x00007ff86bd27000 C:\Windows\SYSTEM32\windows.storage.dll +0x00007ff86f680000 - 0x00007ff86f9fe000 C:\Windows\System32\combase.dll +0x00007ff86fea0000 - 0x00007ff86ff89000 C:\Windows\System32\SHCORE.dll +0x00007ff86eb90000 - 0x00007ff86ebed000 C:\Windows\System32\shlwapi.dll +0x00007ff86d730000 - 0x00007ff86d75e000 C:\Windows\SYSTEM32\profapi.dll +0x00007ff831e10000 - 0x00007ff831e2a000 D:\ruanjian\idea\IntelliJ IDEA Ultimate\bin\breakgen64.dll +0x00007ff828a80000 - 0x00007ff828a9c000 C:\Program Files\Java\jdk-1.8\jre\bin\net.dll +0x00007ff86cb60000 - 0x00007ff86cbca000 C:\Windows\system32\mswsock.dll +0x00007ff86ce10000 - 0x00007ff86ce2c000 C:\Windows\SYSTEM32\CRYPTSP.dll +0x00007ff86c5b0000 - 0x00007ff86c5e8000 C:\Windows\system32\rsaenh.dll +0x00007ff86cc00000 - 0x00007ff86cc2b000 C:\Windows\SYSTEM32\USERENV.dll +0x00007ff86d040000 - 0x00007ff86d066000 C:\Windows\SYSTEM32\bcrypt.dll +0x00007ff86dda0000 - 0x00007ff86de39000 C:\Windows\System32\bcryptprimitives.dll +0x00007ff86ce00000 - 0x00007ff86ce0c000 C:\Windows\SYSTEM32\CRYPTBASE.dll +0x00007ff86c090000 - 0x00007ff86c0c2000 C:\Windows\SYSTEM32\IPHLPAPI.DLL +0x00007ff86fa10000 - 0x00007ff86fa1a000 C:\Windows\System32\NSI.dll +0x00007ff863890000 - 0x00007ff8638af000 C:\Windows\SYSTEM32\dhcpcsvc6.DLL +0x00007ff863820000 - 0x00007ff863845000 C:\Windows\SYSTEM32\dhcpcsvc.DLL +0x00007ff86c140000 - 0x00007ff86c265000 C:\Windows\SYSTEM32\DNSAPI.dll +0x00007ff8289e0000 - 0x00007ff8289f3000 C:\Program Files\Java\jdk-1.8\jre\bin\nio.dll +0x00007ff858320000 - 0x00007ff85832a000 C:\Users\15017\AppData\Local\Temp\jansi-1.17.1-4804090815734096758.dll +0x00007ff86ac50000 - 0x00007ff86ae91000 C:\Windows\SYSTEM32\dbghelp.dll +0x00007ff86f5a0000 - 0x00007ff86f676000 C:\Windows\System32\OLEAUT32.dll + +VM Arguments: +jvm_args: -Dmaven.multiModuleProjectDirectory=D:\daima\java\sk\skyeye-other\xxl-job-2.3.0\xxl-job-admin -Djansi.passthrough=true -Dmaven.home=D:\ruanjian\idea\IntelliJ IDEA Ultimate\plugins\maven\lib\maven3 -Dclassworlds.conf=D:\ruanjian\idea\IntelliJ IDEA Ultimate\plugins\maven\lib\maven3\bin\m2.conf -Dmaven.ext.class.path=D:\ruanjian\idea\IntelliJ IDEA Ultimate\plugins\maven\lib\maven-event-listener.jar -javaagent:D:\ruanjian\idea\IntelliJ IDEA Ultimate\lib\idea_rt.jar=51113:D:\ruanjian\idea\IntelliJ IDEA Ultimate\bin -Dfile.encoding=UTF-8 +java_command: org.codehaus.classworlds.Launcher -Didea.version=2023.1.7 -s D:\ruanjian\Maven\Maven\conf\settings-wateriot.xml -Dmaven.repo.local=D:\ruanjian\Maven\Maven\JavaRepository clean -P myProfile +java_class_path (initial): D:\ruanjian\idea\IntelliJ IDEA Ultimate\plugins\maven\lib\maven3\boot\plexus-classworlds-2.6.0.jar;D:\ruanjian\idea\IntelliJ IDEA Ultimate\plugins\maven\lib\maven3\boot\plexus-classworlds.license;D:\ruanjian\idea\IntelliJ IDEA Ultimate\lib\idea_rt.jar +Launcher Type: SUN_STANDARD + +Environment Variables: +PATH=D:\ruanjian\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\java8path;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;D:\ruanjian\Git\cmd;%NVM_HOME%;%NVM_SYMLINK%;C:\Program Files\Go\bin;C:\Users\15017\AppData\Local\Microsoft\WindowsApps;C:\Users\15017\AppData\Local\JetBrains\Toolbox\scripts;C:\Users\15017\AppData\Local\nvm;C:\nvm4w\nodejs;D:\wenjian\Windsurf\bin;C:\Users\15017\go\bin;D:\ruanjian\cpolar\ +USERNAME=15017 +OS=Windows_NT +PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 170 Stepping 4, GenuineIntel + + + +--------------- S Y S T E M --------------- + +OS: Windows 11 , 64 bit Build 26100 (10.0.26100.3037) + +CPU:total 18 (initial active 18) (9 cores per cpu, 2 threads per core) family 6 model 170 stepping 4, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx + +Memory: 4k page, physical 32994680k(4007664k free), swap 58594676k(210768k free) + +vm_info: Java HotSpot(TM) 64-Bit Server VM (25.441-b07) for windows-amd64 JRE (1.8.0_441-b07), built on Dec 4 2024 08:12:36 by "java_re" with MS VC++ 17.6 (VS2022) + +time: Thu Feb 27 15:52:05 2025 +timezone: Intel64 Family 6 Model 170 Stepping 4, GenuineIntel +elapsed time: 8.329706 seconds (0d 0h 0m 8s) + diff --git a/xxl-job-2.3.0/xxl-job-admin/pom.xml b/xxl-job-2.3.0/xxl-job-admin/pom.xml new file mode 100644 index 0000000..3561b77 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/pom.xml @@ -0,0 +1,158 @@ + + 4.0.0 + + com.xuxueli + xxl-job + 2.3.0 + + xxl-job-admin + jar + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2021.0.6.1 + pom + import + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + org.springframework.boot + spring-boot-starter-mail + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot-starter.version} + + + + mysql + mysql-connector-java + ${mysql-connector-java.version} + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + com.xuxueli + xxl-job-core + ${project.parent.version} + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + com.spotify + docker-maven-plugin + 0.4.13 + + + ${project.artifactId}:${project.version} + ${project.basedir} + + + / + ${project.build.directory} + ${project.build.finalName}.jar + + + + + + + + diff --git a/xxl-job-2.3.0/xxl-job-admin/replay_pid41516.log b/xxl-job-2.3.0/xxl-job-admin/replay_pid41516.log new file mode 100644 index 0000000..30cea1c --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/replay_pid41516.log @@ -0,0 +1,1351 @@ +JvmtiExport can_access_local_variables 0 +JvmtiExport can_hotswap_or_post_breakpoint 0 +JvmtiExport can_post_on_exceptions 0 +# 156 ciObject found +instanceKlass org/apache/maven/artifact/repository/ArtifactRepositoryFactory +instanceKlass org/apache/maven/artifact/manager/WagonManager +instanceKlass org/apache/maven/repository/legacy/WagonManager +instanceKlass org/apache/maven/artifact/installer/ArtifactInstaller +instanceKlass org/eclipse/sisu/plexus/PlexusXmlMetadata +instanceKlass org/eclipse/sisu/plexus/Roles +instanceKlass org/apache/maven/artifact/deployer/ArtifactDeployer +instanceKlass org/eclipse/sisu/plexus/Hints +instanceKlass org/eclipse/sisu/space/AbstractDeferredClass +instanceKlass org/eclipse/sisu/plexus/RequirementImpl +instanceKlass org/codehaus/plexus/component/annotations/Requirement +instanceKlass org/eclipse/sisu/space/Streams +instanceKlass org/eclipse/sisu/plexus/ComponentImpl +instanceKlass org/codehaus/plexus/component/annotations/Component +instanceKlass org/eclipse/sisu/plexus/PlexusTypeRegistry +instanceKlass org/eclipse/sisu/plexus/PlexusXmlScanner +instanceKlass javax/enterprise/inject/Typed +instanceKlass org/eclipse/sisu/space/QualifiedTypeBinder +instanceKlass org/eclipse/sisu/plexus/PlexusTypeBinder +instanceKlass com/google/inject/spi/InjectionRequest +instanceKlass org/eclipse/sisu/bean/BeanProperty +instanceKlass com/google/inject/internal/Nullability +instanceKlass com/google/inject/spi/InjectionPoint$OverrideIndex +instanceKlass org/eclipse/sisu/inject/RankedBindings +instanceKlass org/eclipse/sisu/Mediator +instanceKlass java/util/function/BiConsumer +instanceKlass sun/reflect/generics/tree/TypeVariableSignature +instanceKlass com/google/common/collect/ComparisonChain +instanceKlass com/google/inject/Inject +instanceKlass javax/inject/Inject +instanceKlass java/lang/reflect/WildcardType +instanceKlass java/lang/reflect/TypeVariable +instanceKlass sun/reflect/generics/tree/ClassSignature +instanceKlass sun/reflect/generics/tree/Signature +instanceKlass sun/reflect/generics/tree/FormalTypeParameter +instanceKlass com/google/inject/spi/InjectionPoint$InjectableMembers +instanceKlass com/google/inject/spi/InjectionPoint$InjectableMember +instanceKlass com/google/common/collect/Ordering +instanceKlass com/google/inject/spi/InjectionPoint +instanceKlass java/lang/reflect/ParameterizedType +instanceKlass com/google/inject/internal/MoreTypes$GenericArrayTypeImpl +instanceKlass com/google/inject/internal/MoreTypes$CompositeType +instanceKlass com/google/inject/Key$AnnotationTypeStrategy +instanceKlass com/google/common/util/concurrent/AbstractFuture$Failure +instanceKlass com/google/common/util/concurrent/AbstractFuture$Cancellation +instanceKlass com/google/common/util/concurrent/AbstractFuture$SetFuture +instanceKlass com/google/common/util/concurrent/Uninterruptibles +instanceKlass com/google/common/base/CommonPattern +instanceKlass com/google/common/base/Platform$JdkPatternCompiler +instanceKlass com/google/common/base/PatternCompiler +instanceKlass com/google/common/base/Platform +instanceKlass com/google/common/base/Stopwatch +instanceKlass java/util/concurrent/locks/LockSupport +instanceKlass com/google/common/util/concurrent/AbstractFuture$Waiter +instanceKlass com/google/common/util/concurrent/AbstractFuture$Listener +instanceKlass com/google/common/util/concurrent/AbstractFuture$UnsafeAtomicHelper$1 +instanceKlass com/google/common/util/concurrent/AbstractFuture$AtomicHelper +instanceKlass com/google/common/util/concurrent/GwtFluentFutureCatchingSpecialization +instanceKlass com/google/common/util/concurrent/ListenableFuture +instanceKlass com/google/common/cache/LocalCache$LoadingValueReference +instanceKlass java/lang/annotation/Documented +instanceKlass java/lang/annotation/Target +instanceKlass javax/inject/Named +instanceKlass javax/inject/Qualifier +instanceKlass com/google/inject/BindingAnnotation +instanceKlass javax/inject/Scope +instanceKlass com/google/inject/ScopeAnnotation +instanceKlass com/google/inject/internal/Annotations$AnnotationChecker +instanceKlass java/lang/reflect/Proxy$1 +instanceKlass java/lang/reflect/WeakCache$Value +instanceKlass sun/misc/ProxyGenerator$ExceptionTableEntry +instanceKlass sun/misc/ProxyGenerator$PrimitiveTypeInfo +instanceKlass sun/misc/ProxyGenerator$FieldInfo +instanceKlass java/io/DataOutput +instanceKlass sun/misc/ProxyGenerator$ConstantPool$Entry +instanceKlass sun/misc/ProxyGenerator$MethodInfo +instanceKlass sun/misc/ProxyGenerator$ProxyMethod +instanceKlass sun/misc/ProxyGenerator$ConstantPool +instanceKlass sun/misc/ProxyGenerator +instanceKlass java/lang/reflect/WeakCache$Factory +instanceKlass java/util/function/Supplier +instanceKlass java/lang/reflect/Proxy$ProxyClassFactory +instanceKlass java/lang/reflect/Proxy$KeyFactory +instanceKlass java/util/function/BiFunction +instanceKlass java/lang/reflect/WeakCache +instanceKlass java/lang/reflect/Proxy +instanceKlass sun/reflect/annotation/AnnotationInvocationHandler +instanceKlass sun/reflect/annotation/AnnotationParser$1 +instanceKlass sun/reflect/annotation/ExceptionProxy +instanceKlass java/lang/Class$4 +instanceKlass java/lang/annotation/Inherited +instanceKlass java/lang/annotation/Retention +instanceKlass sun/reflect/annotation/AnnotationType$1 +instanceKlass java/lang/reflect/GenericArrayType +instanceKlass sun/reflect/generics/visitor/Reifier +instanceKlass sun/reflect/generics/visitor/TypeTreeVisitor +instanceKlass sun/reflect/generics/factory/CoreReflectionFactory +instanceKlass sun/reflect/generics/factory/GenericsFactory +instanceKlass sun/reflect/generics/scope/AbstractScope +instanceKlass sun/reflect/generics/scope/Scope +instanceKlass sun/reflect/generics/tree/ClassTypeSignature +instanceKlass sun/reflect/generics/tree/SimpleClassTypeSignature +instanceKlass sun/reflect/generics/tree/FieldTypeSignature +instanceKlass sun/reflect/generics/tree/BaseType +instanceKlass sun/reflect/generics/tree/TypeSignature +instanceKlass sun/reflect/generics/tree/ReturnType +instanceKlass sun/reflect/generics/tree/TypeArgument +instanceKlass sun/reflect/generics/tree/TypeTree +instanceKlass sun/reflect/generics/tree/Tree +instanceKlass sun/reflect/generics/parser/SignatureParser +instanceKlass com/google/inject/internal/Annotations$TestAnnotation +instanceKlass com/google/inject/internal/Annotations$3 +instanceKlass com/google/common/base/Joiner$MapJoiner +instanceKlass com/google/common/base/Joiner +instanceKlass java/lang/reflect/InvocationHandler +instanceKlass com/google/inject/internal/Annotations +instanceKlass org/eclipse/sisu/Parameters +instanceKlass org/eclipse/sisu/wire/ParameterKeys +instanceKlass org/eclipse/sisu/wire/TypeConverterCache +instanceKlass org/eclipse/sisu/inject/DefaultRankingFunction +instanceKlass com/google/inject/internal/Scoping +instanceKlass com/google/inject/internal/InternalFactory +instanceKlass com/google/inject/spi/ProviderKeyBinding +instanceKlass com/google/inject/spi/ProviderInstanceBinding +instanceKlass com/google/inject/spi/InstanceBinding +instanceKlass com/google/inject/internal/DelayedInitialize +instanceKlass com/google/inject/spi/ConstructorBinding +instanceKlass com/google/inject/spi/HasDependencies +instanceKlass com/google/inject/spi/LinkedKeyBinding +instanceKlass com/google/inject/spi/UntargettedBinding +instanceKlass com/google/inject/internal/BindingImpl +instanceKlass com/google/inject/Key$AnnotationStrategy +instanceKlass org/eclipse/sisu/wire/ElementAnalyzer$1 +instanceKlass com/google/inject/util/Modules$EmptyModule +instanceKlass com/google/inject/util/Modules$OverriddenModuleBuilder +instanceKlass com/google/inject/util/Modules +instanceKlass sun/reflect/annotation/AnnotationParser +instanceKlass com/google/common/collect/ImmutableMap$Builder +instanceKlass com/google/inject/internal/MoreTypes +instanceKlass com/google/inject/multibindings/ProvidesIntoOptional +instanceKlass com/google/inject/multibindings/ProvidesIntoMap +instanceKlass com/google/inject/multibindings/ProvidesIntoSet +instanceKlass com/google/inject/Provides +instanceKlass javax/inject/Singleton +instanceKlass com/google/inject/spi/ElementSource +instanceKlass com/google/inject/spi/ScopeBinding +instanceKlass com/google/inject/Scopes$2 +instanceKlass com/google/inject/Scopes$1 +instanceKlass com/google/inject/internal/SingletonScope +instanceKlass com/google/inject/Scopes +instanceKlass com/google/inject/Singleton +instanceKlass com/google/inject/spi/Elements$ModuleInfo +instanceKlass com/google/inject/PrivateModule +instanceKlass com/google/inject/internal/util/StackTraceElements$InMemoryStackTraceElement +instanceKlass com/google/inject/internal/util/StackTraceElements +instanceKlass com/google/inject/spi/ModuleSource +instanceKlass com/google/inject/internal/InternalFlags$1 +instanceKlass com/google/inject/internal/InternalFlags +instanceKlass com/google/inject/internal/ProviderMethodsModule +instanceKlass com/google/inject/internal/AbstractBindingBuilder +instanceKlass com/google/inject/binder/ConstantBindingBuilder +instanceKlass com/google/common/collect/Sets +instanceKlass com/google/inject/binder/AnnotatedElementBuilder +instanceKlass com/google/inject/spi/Elements$RecordingBinder +instanceKlass com/google/inject/Binding +instanceKlass com/google/inject/spi/DefaultBindingTargetVisitor +instanceKlass com/google/inject/spi/BindingTargetVisitor +instanceKlass com/google/inject/spi/Elements +instanceKlass com/google/inject/internal/InjectorShell$RootModule +instanceKlass java/util/concurrent/atomic/AtomicReferenceArray +instanceKlass java/util/concurrent/Future +instanceKlass java/util/concurrent/ConcurrentLinkedQueue$Node +instanceKlass com/google/common/cache/Weigher +instanceKlass com/google/common/base/Predicate +instanceKlass com/google/common/base/Equivalence +instanceKlass com/google/common/base/MoreObjects +instanceKlass com/google/common/cache/LocalCache$1 +instanceKlass com/google/common/cache/ReferenceEntry +instanceKlass com/google/common/cache/CacheLoader +instanceKlass com/google/common/cache/LocalCache$LocalManualCache +instanceKlass com/google/inject/internal/WeakKeySet$1 +instanceKlass com/google/common/cache/LocalCache$StrongValueReference +instanceKlass com/google/common/cache/LocalCache$ValueReference +instanceKlass com/google/common/cache/CacheBuilder$2 +instanceKlass com/google/common/cache/CacheStats +instanceKlass com/google/common/base/Suppliers$SupplierOfInstance +instanceKlass com/google/common/base/Suppliers +instanceKlass com/google/common/cache/CacheBuilder$1 +instanceKlass com/google/common/cache/AbstractCache$StatsCounter +instanceKlass com/google/common/cache/LoadingCache +instanceKlass com/google/common/cache/Cache +instanceKlass com/google/common/base/Ticker +instanceKlass com/google/common/base/Supplier +instanceKlass com/google/common/cache/CacheBuilder +instanceKlass com/google/common/cache/RemovalListener +instanceKlass com/google/inject/internal/WeakKeySet +instanceKlass com/google/inject/internal/State$1 +instanceKlass com/google/inject/internal/InheritingState +instanceKlass com/google/inject/internal/ProcessedBindingData +instanceKlass com/google/inject/spi/DefaultElementVisitor +instanceKlass com/google/inject/internal/State +instanceKlass com/google/inject/internal/InjectorShell$Builder +instanceKlass com/google/common/collect/Lists +instanceKlass com/google/common/collect/AbstractMapEntry +instanceKlass com/google/common/collect/LinkedHashMultimap$ValueSetLink +instanceKlass com/google/common/collect/Platform +instanceKlass com/google/common/collect/Multiset +instanceKlass com/google/common/collect/AbstractMultimap +instanceKlass com/google/common/collect/SetMultimap +instanceKlass com/google/common/base/Converter +instanceKlass com/google/common/collect/ImmutableMap +instanceKlass com/google/common/collect/BiMap +instanceKlass com/google/common/collect/Maps$EntryTransformer +instanceKlass com/google/common/base/Function +instanceKlass com/google/common/collect/SortedMapDifference +instanceKlass com/google/common/collect/MapDifference +instanceKlass com/google/common/collect/Maps +instanceKlass com/google/inject/internal/CycleDetectingLock +instanceKlass com/google/common/collect/Multimap +instanceKlass com/google/inject/internal/CycleDetectingLock$CycleDetectingLockFactory +instanceKlass com/google/inject/internal/Initializable +instanceKlass com/google/inject/internal/Initializer +instanceKlass com/google/common/collect/PeekingIterator +instanceKlass com/google/common/collect/UnmodifiableIterator +instanceKlass com/google/common/collect/Iterators +instanceKlass com/google/inject/internal/util/SourceProvider +instanceKlass com/google/common/collect/Hashing +instanceKlass com/google/common/collect/ObjectArrays +instanceKlass com/google/common/primitives/Primitives +instanceKlass com/google/common/base/Preconditions +instanceKlass com/google/common/collect/CollectPreconditions +instanceKlass com/google/common/collect/ImmutableCollection$Builder +instanceKlass com/google/inject/internal/Errors +instanceKlass java/util/logging/LogManager$5 +instanceKlass sun/reflect/UnsafeFieldAccessorFactory +instanceKlass java/util/logging/LoggingProxyImpl +instanceKlass sun/util/logging/LoggingProxy +instanceKlass sun/util/logging/LoggingSupport$1 +instanceKlass sun/util/logging/LoggingSupport +instanceKlass sun/util/logging/PlatformLogger$LoggerProxy +instanceKlass sun/util/logging/PlatformLogger$1 +instanceKlass sun/util/logging/PlatformLogger +instanceKlass java/util/logging/LogManager$LoggerContext$1 +instanceKlass java/util/logging/LogManager$3 +instanceKlass java/util/logging/LogManager$2 +instanceKlass java/util/logging/LogManager$LogNode +instanceKlass java/util/logging/LogManager$LoggerContext +instanceKlass java/util/logging/LogManager$1 +instanceKlass java/util/logging/LogManager +instanceKlass java/util/concurrent/CopyOnWriteArrayList +instanceKlass java/util/logging/Logger$LoggerBundle +instanceKlass java/util/logging/Level$KnownLevel +instanceKlass java/util/logging/Level +instanceKlass java/util/logging/Handler +instanceKlass java/util/logging/Logger +instanceKlass com/google/inject/internal/util/Stopwatch +instanceKlass com/google/inject/Injector +instanceKlass com/google/inject/internal/InternalInjectorCreator +instanceKlass com/google/inject/Guice +instanceKlass org/eclipse/sisu/wire/Wiring +instanceKlass org/eclipse/sisu/wire/WireModule$Strategy$1 +instanceKlass org/eclipse/sisu/wire/WireModule$Strategy +instanceKlass org/eclipse/sisu/wire/AbstractTypeConverter +instanceKlass com/google/inject/spi/ElementVisitor +instanceKlass org/eclipse/sisu/wire/WireModule +instanceKlass org/eclipse/sisu/bean/BeanBinder +instanceKlass org/eclipse/sisu/plexus/PlexusBindingModule +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$BootModule +instanceKlass org/codehaus/plexus/component/annotations/Configuration +instanceKlass org/eclipse/sisu/plexus/PlexusAnnotatedMetadata +instanceKlass org/eclipse/sisu/plexus/PlexusBeanMetadata +instanceKlass org/eclipse/sisu/plexus/PlexusAnnotatedBeanModule$PlexusAnnotatedBeanSource +instanceKlass org/eclipse/sisu/space/SpaceModule$Strategy$1 +instanceKlass org/eclipse/sisu/space/DefaultClassFinder +instanceKlass org/eclipse/sisu/space/asm/ClassVisitor +instanceKlass org/eclipse/sisu/space/SpaceScanner +instanceKlass org/eclipse/sisu/space/IndexedClassFinder +instanceKlass org/eclipse/sisu/space/ClassFinder +instanceKlass org/eclipse/sisu/space/SpaceModule +instanceKlass org/eclipse/sisu/space/SpaceVisitor +instanceKlass org/eclipse/sisu/plexus/PlexusTypeListener +instanceKlass org/eclipse/sisu/space/QualifiedTypeListener +instanceKlass org/eclipse/sisu/plexus/PlexusAnnotatedBeanModule$1 +instanceKlass org/eclipse/sisu/space/SpaceModule$Strategy +instanceKlass org/eclipse/sisu/plexus/PlexusAnnotatedBeanModule +instanceKlass org/eclipse/sisu/plexus/PlexusBeanSource +instanceKlass org/eclipse/sisu/plexus/PlexusXmlBeanModule +instanceKlass org/eclipse/sisu/plexus/PlexusBeanModule +instanceKlass org/eclipse/sisu/space/URLClassSpace +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$SLF4JLoggerFactoryProvider +instanceKlass com/google/inject/util/Providers$ConstantProvider +instanceKlass com/google/inject/util/Providers +instanceKlass org/codehaus/plexus/personality/plexus/lifecycle/phase/Disposable +instanceKlass org/codehaus/plexus/personality/plexus/lifecycle/phase/Startable +instanceKlass org/codehaus/plexus/personality/plexus/lifecycle/phase/Initializable +instanceKlass org/codehaus/plexus/personality/plexus/lifecycle/phase/Contextualizable +instanceKlass org/codehaus/plexus/logging/LogEnabled +instanceKlass org/eclipse/sisu/bean/PropertyBinding +instanceKlass org/eclipse/sisu/bean/LifecycleBuilder +instanceKlass org/eclipse/sisu/bean/BeanScheduler$1 +instanceKlass com/google/inject/spi/DefaultBindingScopingVisitor +instanceKlass com/google/inject/spi/BindingScopingVisitor +instanceKlass org/eclipse/sisu/bean/BeanScheduler$CycleActivator +instanceKlass com/google/inject/spi/Message +instanceKlass com/google/inject/spi/Element +instanceKlass com/google/inject/Scope +instanceKlass com/google/inject/spi/TypeListener +instanceKlass com/google/inject/binder/AnnotatedConstantBindingBuilder +instanceKlass com/google/inject/PrivateBinder +instanceKlass com/google/inject/MembersInjector +instanceKlass com/google/inject/spi/ModuleAnnotatedMethodScanner +instanceKlass com/google/inject/spi/Dependency +instanceKlass com/google/inject/TypeLiteral +instanceKlass com/google/inject/Key +instanceKlass com/google/inject/binder/AnnotatedBindingBuilder +instanceKlass com/google/inject/binder/LinkedBindingBuilder +instanceKlass com/google/inject/binder/ScopedBindingBuilder +instanceKlass com/google/inject/spi/ProvisionListener +instanceKlass com/google/inject/Binder +instanceKlass org/eclipse/sisu/bean/BeanScheduler +instanceKlass org/eclipse/sisu/plexus/DefaultPlexusBeanLocator +instanceKlass org/eclipse/sisu/inject/MildKeys +instanceKlass org/eclipse/sisu/plexus/ClassRealmManager +instanceKlass org/codehaus/plexus/context/ContextMapAdapter +instanceKlass org/codehaus/plexus/context/DefaultContext +instanceKlass org/codehaus/plexus/logging/AbstractLogger +instanceKlass org/codehaus/plexus/logging/AbstractLoggerManager +instanceKlass java/text/DigitList +instanceKlass java/text/FieldPosition +instanceKlass java/util/Currency$CurrencyNameGetter +instanceKlass java/util/Currency$1 +instanceKlass java/util/Currency +instanceKlass java/text/DecimalFormatSymbols +instanceKlass java/util/concurrent/atomic/AtomicMarkableReference$Pair +instanceKlass java/util/concurrent/atomic/AtomicMarkableReference +instanceKlass java/text/DateFormatSymbols +instanceKlass sun/util/locale/LanguageTag +instanceKlass java/util/ResourceBundle$CacheKeyReference +instanceKlass java/util/ResourceBundle$CacheKey +instanceKlass java/util/ResourceBundle$RBClassLoader$1 +instanceKlass java/util/spi/ResourceBundleControlProvider +instanceKlass java/util/ResourceBundle +instanceKlass java/util/ResourceBundle$Control +instanceKlass sun/util/resources/LocaleData$1 +instanceKlass sun/util/resources/LocaleData +instanceKlass sun/util/locale/provider/LocaleResources +instanceKlass sun/util/locale/provider/CalendarDataUtility$CalendarWeekParameterGetter +instanceKlass sun/util/locale/provider/TimeZoneNameUtility$TimeZoneNameGetter +instanceKlass sun/util/locale/provider/LocaleServiceProviderPool$LocalizedObjectGetter +instanceKlass sun/util/locale/provider/CalendarDataUtility +instanceKlass java/util/ServiceLoader$1 +instanceKlass java/util/ServiceLoader$LazyIterator +instanceKlass java/util/ServiceLoader +instanceKlass java/util/Calendar$Builder +instanceKlass sun/util/locale/provider/SPILocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/JRELocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/LocaleDataMetaInfo +instanceKlass sun/util/locale/provider/AvailableLanguageTags +instanceKlass sun/util/locale/provider/LocaleProviderAdapter$1 +instanceKlass sun/util/locale/provider/ResourceBundleBasedAdapter +instanceKlass sun/util/locale/provider/LocaleProviderAdapter +instanceKlass java/util/Calendar +instanceKlass java/text/AttributedCharacterIterator$Attribute +instanceKlass sun/util/locale/provider/LocaleServiceProviderPool +instanceKlass java/util/spi/LocaleServiceProvider +instanceKlass sun/util/locale/provider/TimeZoneNameUtility +instanceKlass com/google/inject/matcher/AbstractMatcher +instanceKlass com/google/inject/matcher/Matcher +instanceKlass sun/util/calendar/CalendarUtils +instanceKlass sun/util/calendar/CalendarDate +instanceKlass com/google/inject/spi/TypeConverter +instanceKlass java/util/TimeZone$1 +instanceKlass sun/util/calendar/ZoneInfoFile$ZoneOffsetTransitionRule +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$LoggerProvider +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$DefaultsModule +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$ContainerModule +instanceKlass java/io/DataInput +instanceKlass org/eclipse/sisu/inject/ImplicitBindings +instanceKlass sun/util/calendar/ZoneInfoFile$1 +instanceKlass sun/util/calendar/ZoneInfoFile +instanceKlass org/eclipse/sisu/inject/MildValues$InverseMapping +instanceKlass java/util/TimeZone +instanceKlass org/eclipse/sisu/inject/MildValues +instanceKlass sun/util/calendar/CalendarSystem +instanceKlass java/util/Date +instanceKlass org/eclipse/sisu/inject/Weak +instanceKlass sun/nio/cs/Surrogate +instanceKlass sun/nio/cs/Surrogate$Parser +instanceKlass java/util/concurrent/atomic/AtomicReference +instanceKlass sun/misc/VMSupport +instanceKlass org/eclipse/sisu/inject/BindingPublisher +instanceKlass org/eclipse/sisu/inject/RankingFunction +instanceKlass org/eclipse/sisu/inject/BindingSubscriber +instanceKlass org/eclipse/sisu/inject/DefaultBeanLocator +instanceKlass org/eclipse/sisu/inject/DeferredClass +instanceKlass org/codehaus/plexus/DefaultPlexusContainer$LoggerManagerProvider +instanceKlass org/eclipse/sisu/inject/DeferredProvider +instanceKlass com/google/inject/Provider +instanceKlass com/google/inject/AbstractModule +instanceKlass org/codehaus/plexus/context/Context +instanceKlass org/eclipse/sisu/space/ClassSpace +instanceKlass javax/inject/Provider +instanceKlass org/eclipse/sisu/bean/BeanManager +instanceKlass org/eclipse/sisu/plexus/PlexusBeanLocator +instanceKlass org/codehaus/plexus/classworlds/ClassWorldListener +instanceKlass com/google/inject/Module +instanceKlass org/eclipse/sisu/inject/MutableBeanLocator +instanceKlass org/eclipse/sisu/inject/BeanLocator +instanceKlass org/codehaus/plexus/DefaultPlexusContainer +instanceKlass org/codehaus/plexus/MutablePlexusContainer +instanceKlass org/apache/maven/extension/internal/CoreExports +instanceKlass org/codehaus/plexus/DefaultContainerConfiguration +instanceKlass org/codehaus/plexus/ContainerConfiguration +instanceKlass org/codehaus/plexus/util/xml/XMLWriter +instanceKlass org/codehaus/plexus/util/xml/Xpp3Dom +instanceKlass org/codehaus/plexus/util/xml/pull/MXParser +instanceKlass org/codehaus/plexus/util/xml/pull/XmlPullParser +instanceKlass org/codehaus/plexus/util/xml/Xpp3DomBuilder +instanceKlass java/util/regex/ASCII +instanceKlass java/util/regex/Matcher +instanceKlass java/util/regex/MatchResult +instanceKlass java/util/Locale$1 +instanceKlass org/codehaus/plexus/util/ReaderFactory +instanceKlass org/apache/maven/project/ExtensionDescriptor +instanceKlass org/apache/maven/project/ExtensionDescriptorBuilder +instanceKlass org/apache/maven/extension/internal/CoreExtensionEntry +instanceKlass org/apache/maven/cli/ResolveFile +instanceKlass org/codehaus/plexus/util/StringUtils +instanceKlass org/codehaus/plexus/logging/Logger +instanceKlass org/apache/maven/cli/logging/Slf4jLoggerManager +instanceKlass org/slf4j/impl/MavenSlf4jSimpleFriend +instanceKlass org/slf4j/MavenSlf4jFriend +instanceKlass org/apache/maven/cli/logging/BaseSlf4jConfiguration +instanceKlass org/codehaus/plexus/util/IOUtil +instanceKlass org/codehaus/plexus/util/PropertyUtils +instanceKlass org/apache/maven/cli/logging/Slf4jConfiguration +instanceKlass org/apache/maven/cli/logging/Slf4jConfigurationFactory +instanceKlass org/slf4j/impl/OutputChoice +instanceKlass sun/net/DefaultProgressMeteringPolicy +instanceKlass sun/net/ProgressMeteringPolicy +instanceKlass sun/net/ProgressMonitor +instanceKlass org/slf4j/impl/SimpleLoggerConfiguration$1 +instanceKlass java/text/Format +instanceKlass org/slf4j/impl/SimpleLoggerConfiguration +instanceKlass org/slf4j/helpers/NamedLoggerBase +instanceKlass org/slf4j/impl/SimpleLoggerFactory +instanceKlass org/slf4j/impl/StaticLoggerBinder +instanceKlass org/slf4j/spi/LoggerFactoryBinder +instanceKlass java/util/Collections$3 +instanceKlass java/net/URLClassLoader$3$1 +instanceKlass sun/misc/CompoundEnumeration +instanceKlass java/net/URLClassLoader$3 +instanceKlass sun/misc/URLClassPath$1 +instanceKlass java/lang/ClassLoader$2 +instanceKlass sun/misc/URLClassPath$2 +instanceKlass org/slf4j/helpers/Util +instanceKlass org/slf4j/helpers/NOPLoggerFactory +instanceKlass java/util/concurrent/LinkedBlockingQueue$Node +instanceKlass java/util/concurrent/locks/AbstractQueuedSynchronizer$ConditionObject +instanceKlass java/util/concurrent/locks/Condition +instanceKlass java/util/concurrent/locks/AbstractQueuedSynchronizer$Node +instanceKlass java/util/concurrent/locks/AbstractOwnableSynchronizer +instanceKlass java/util/concurrent/BlockingQueue +instanceKlass org/slf4j/helpers/SubstituteLoggerFactory +instanceKlass org/slf4j/ILoggerFactory +instanceKlass org/slf4j/event/LoggingEvent +instanceKlass org/slf4j/LoggerFactory +instanceKlass org/apache/commons/lang3/StringUtils +instanceKlass org/apache/maven/cli/CLIReportingUtils +instanceKlass org/apache/maven/properties/internal/SystemProperties +instanceKlass java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry +instanceKlass java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$1 +instanceKlass org/codehaus/plexus/util/Os +instanceKlass org/apache/maven/properties/internal/EnvironmentUtils +instanceKlass java/util/LinkedList$Node +instanceKlass java/util/ListIterator +instanceKlass org/apache/commons/cli/Util +instanceKlass org/apache/commons/cli/CommandLine +instanceKlass org/apache/commons/cli/Parser +instanceKlass org/apache/maven/cli/CleanArgument +instanceKlass org/apache/commons/cli/OptionValidator +instanceKlass org/apache/commons/cli/Option$Builder +instanceKlass org/apache/commons/cli/Option +instanceKlass org/apache/commons/cli/Options +instanceKlass org/apache/commons/cli/CommandLineParser +instanceKlass org/apache/maven/cli/CLIManager +instanceKlass org/apache/maven/cli/logging/Slf4jStdoutLogger +instanceKlass org/eclipse/aether/DefaultRepositoryCache +instanceKlass org/apache/maven/project/ProjectBuildingRequest +instanceKlass org/eclipse/aether/RepositoryCache +instanceKlass org/apache/maven/execution/DefaultMavenExecutionRequest +instanceKlass org/apache/maven/execution/MavenExecutionRequest +instanceKlass java/lang/ApplicationShutdownHooks$1 +instanceKlass java/lang/ApplicationShutdownHooks +instanceKlass java/lang/Shutdown$Lock +instanceKlass java/lang/Shutdown +instanceKlass java/io/DeleteOnExitHook$1 +instanceKlass java/io/DeleteOnExitHook +instanceKlass sun/net/www/protocol/jar/JarFileFactory +instanceKlass sun/net/www/protocol/jar/URLJarFile$URLJarFileCloseController +instanceKlass sun/nio/fs/BasicFileAttributesHolder +instanceKlass sun/nio/fs/WindowsDirectoryStream$WindowsDirectoryIterator +instanceKlass sun/nio/fs/WindowsFileAttributes +instanceKlass java/nio/file/attribute/DosFileAttributes +instanceKlass java/nio/file/attribute/BasicFileAttributes +instanceKlass sun/nio/fs/NativeBuffer$Deallocator +instanceKlass sun/nio/fs/NativeBuffer +instanceKlass sun/nio/fs/NativeBuffers +instanceKlass sun/nio/fs/WindowsNativeDispatcher$BackupResult +instanceKlass sun/nio/fs/WindowsNativeDispatcher$CompletionStatus +instanceKlass sun/nio/fs/WindowsNativeDispatcher$AclInformation +instanceKlass sun/nio/fs/WindowsNativeDispatcher$Account +instanceKlass sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace +instanceKlass sun/nio/fs/WindowsNativeDispatcher$VolumeInformation +instanceKlass sun/nio/fs/WindowsNativeDispatcher$FirstStream +instanceKlass sun/nio/fs/WindowsNativeDispatcher$FirstFile +instanceKlass sun/nio/fs/WindowsNativeDispatcher$1 +instanceKlass sun/nio/fs/WindowsNativeDispatcher +instanceKlass sun/nio/fs/WindowsDirectoryStream +instanceKlass java/nio/file/DirectoryStream +instanceKlass java/nio/file/Files$AcceptAllFilter +instanceKlass java/nio/file/DirectoryStream$Filter +instanceKlass java/nio/file/Files +instanceKlass sun/nio/fs/AbstractPath +instanceKlass sun/nio/fs/Util +instanceKlass sun/nio/fs/WindowsPathParser$Result +instanceKlass sun/nio/fs/WindowsPathParser +instanceKlass java/nio/file/FileSystem +instanceKlass java/nio/file/spi/FileSystemProvider +instanceKlass sun/nio/fs/DefaultFileSystemProvider +instanceKlass java/nio/file/FileSystems$DefaultFileSystemHolder$1 +instanceKlass java/nio/file/FileSystems$DefaultFileSystemHolder +instanceKlass java/nio/file/FileSystems +instanceKlass java/net/NetworkInterface$2 +instanceKlass java/net/DefaultInterface +instanceKlass java/net/InterfaceAddress +instanceKlass java/net/NetworkInterface$1 +instanceKlass sun/security/provider/ByteArrayAccess +instanceKlass sun/security/provider/SeedGenerator$1 +instanceKlass sun/security/provider/SeedGenerator +instanceKlass sun/security/provider/SecureRandom$SeederHolder +instanceKlass sun/security/util/MessageDigestSpi2 +instanceKlass sun/security/jca/GetInstance$Instance +instanceKlass sun/security/jca/GetInstance +instanceKlass java/security/SecureRandomSpi +instanceKlass java/util/Collections$EmptyIterator +instanceKlass java/util/LinkedHashMap$LinkedHashIterator +instanceKlass sun/security/util/SecurityProviderConstants +instanceKlass java/security/Provider$UString +instanceKlass java/security/Provider$Service +instanceKlass sun/security/provider/NativePRNG$NonBlocking +instanceKlass sun/security/provider/NativePRNG$Blocking +instanceKlass sun/security/provider/NativePRNG +instanceKlass sun/security/provider/SunEntries$1 +instanceKlass sun/security/provider/SunEntries +instanceKlass sun/security/jca/ProviderConfig$2 +instanceKlass java/security/Security$2 +instanceKlass sun/misc/JavaSecurityPropertiesAccess +instanceKlass java/security/Security$1 +instanceKlass java/security/Security +instanceKlass sun/security/jca/ProviderList$2 +instanceKlass sun/misc/FDBigInteger +instanceKlass java/security/Provider$EngineDescription +instanceKlass java/security/Provider$ServiceKey +instanceKlass sun/security/jca/ProviderConfig +instanceKlass sun/security/jca/ProviderList +instanceKlass sun/security/jca/Providers +instanceKlass java/util/Random +instanceKlass java/io/File$TempDirectory +instanceKlass java/util/AbstractList$Itr +instanceKlass java/net/URLClassLoader$2 +instanceKlass sun/misc/Launcher$BootClassPathHolder$1 +instanceKlass sun/misc/Launcher$BootClassPathHolder +instanceKlass org/fusesource/hawtjni/runtime/Library +instanceKlass org/fusesource/jansi/internal/CLibrary +instanceKlass java/lang/ProcessEnvironment$CheckedEntry +instanceKlass java/lang/ProcessEnvironment$CheckedEntrySet$1 +instanceKlass java/util/Collections$UnmodifiableMap +instanceKlass java/lang/ProcessEnvironment$EntryComparator +instanceKlass java/lang/ProcessEnvironment$NameComparator +instanceKlass org/fusesource/jansi/AnsiConsole +instanceKlass org/fusesource/jansi/Ansi$1 +instanceKlass java/util/concurrent/Callable +instanceKlass org/fusesource/jansi/Ansi +instanceKlass org/apache/maven/shared/utils/logging/LoggerLevelRenderer +instanceKlass org/apache/maven/shared/utils/logging/MessageUtils +instanceKlass java/util/regex/Pattern$TreeInfo +instanceKlass java/util/regex/Pattern$Node +instanceKlass java/util/regex/Pattern +instanceKlass org/apache/maven/cli/CliRequest +instanceKlass org/apache/maven/eventspy/EventSpy$Context +instanceKlass org/codehaus/plexus/PlexusContainer +instanceKlass org/codehaus/plexus/logging/LoggerManager +instanceKlass org/apache/maven/toolchain/building/ToolchainsBuildingRequest +instanceKlass org/apache/maven/building/Source +instanceKlass org/apache/maven/execution/ExecutionListener +instanceKlass org/slf4j/Logger +instanceKlass org/eclipse/aether/transfer/TransferListener +instanceKlass org/apache/maven/exception/ExceptionHandler +instanceKlass org/apache/maven/cli/MavenCli +instanceKlass java/util/TreeMap$PrivateEntryIterator +instanceKlass java/util/TimSort +instanceKlass java/util/Arrays$LegacyMergeSort +instanceKlass org/codehaus/plexus/classworlds/launcher/Configurator$1 +instanceKlass org/codehaus/plexus/classworlds/launcher/ConfigurationParser$1 +instanceKlass org/codehaus/plexus/classworlds/strategy/AbstractStrategy +instanceKlass org/codehaus/plexus/classworlds/strategy/Strategy +instanceKlass org/codehaus/plexus/classworlds/strategy/StrategyFactory +instanceKlass java/util/NavigableSet +instanceKlass java/util/SortedSet +instanceKlass java/net/Socket$2 +instanceKlass java/io/FilenameFilter +instanceKlass sun/net/NetHooks +instanceKlass java/util/ArrayList$Itr +instanceKlass org/codehaus/plexus/classworlds/launcher/ConfigurationParser +instanceKlass java/net/Proxy +instanceKlass sun/net/spi/DefaultProxySelector$3 +instanceKlass sun/net/spi/DefaultProxySelector$NonProxyInfo +instanceKlass java/net/URI$Parser +instanceKlass java/net/URI +instanceKlass org/codehaus/plexus/classworlds/ClassWorld +instanceKlass org/codehaus/plexus/classworlds/launcher/Configurator +instanceKlass org/codehaus/plexus/classworlds/launcher/ConfigurationHandler +instanceKlass java/util/Properties$LineReader +instanceKlass java/lang/Void +instanceKlass sun/net/NetProperties$1 +instanceKlass sun/net/NetProperties +instanceKlass sun/net/spi/DefaultProxySelector$1 +instanceKlass java/lang/Class$MethodArray +instanceKlass java/net/ProxySelector +instanceKlass java/net/SocksSocketImpl$3 +instanceKlass sun/launcher/LauncherHelper$FXHelper +instanceKlass org/codehaus/plexus/classworlds/launcher/Launcher +instanceKlass java/net/Inet6Address$Inet6AddressHolder +instanceKlass sun/misc/FloatingDecimal$ASCIIToBinaryBuffer +instanceKlass sun/misc/FloatingDecimal$PreparedASCIIToBinaryBuffer +instanceKlass sun/misc/FloatingDecimal$ASCIIToBinaryConverter +instanceKlass sun/misc/FloatingDecimal$BinaryToASCIIBuffer +instanceKlass java/io/FileOutputStream$1 +instanceKlass sun/misc/FloatingDecimal$ExceptionalBinaryToASCIIBuffer +instanceKlass sun/misc/FloatingDecimal$BinaryToASCIIConverter +instanceKlass sun/misc/FloatingDecimal +instanceKlass java/net/PlainSocketImpl$1 +instanceKlass java/net/NetworkInterface +instanceKlass java/net/StandardSocketOptions$StdSocketOption +instanceKlass java/net/StandardSocketOptions +instanceKlass java/util/HashMap$HashIterator +instanceKlass sun/usagetracker/UsageTrackerClient$3 +instanceKlass sun/usagetracker/UsageTrackerClient$2 +instanceKlass java/util/Collections$UnmodifiableCollection$1 +instanceKlass sun/usagetracker/UsageTrackerClient$4 +instanceKlass sun/usagetracker/UsageTrackerClient$1 +instanceKlass java/util/concurrent/atomic/AtomicBoolean +instanceKlass sun/usagetracker/UsageTrackerClient +instanceKlass jdk/net/ExtendedSocketOptions$PlatformSocketOptions$1 +instanceKlass jdk/net/ExtendedSocketOptions$PlatformSocketOptions +instanceKlass jdk/net/SocketFlow +instanceKlass sun/misc/PostVMInitHook$1 +instanceKlass jdk/net/ExtendedSocketOptions$ExtSocketOption +instanceKlass java/net/SocketOption +instanceKlass jdk/internal/util/EnvUtils +instanceKlass jdk/net/ExtendedSocketOptions +instanceKlass sun/misc/PostVMInitHook$2 +instanceKlass sun/net/ExtendedSocketOptions +instanceKlass java/security/MessageDigestSpi +instanceKlass java/net/AbstractPlainSocketImpl$1 +instanceKlass java/net/SocketImpl +instanceKlass java/net/SocketOptions +instanceKlass sun/security/validator/Validator +instanceKlass java/net/SocksConsts +instanceKlass java/security/cert/X509Extension +instanceKlass java/net/InetAddress$2 +instanceKlass sun/net/spi/nameservice/NameService +instanceKlass java/security/cert/CertificateFactory +instanceKlass javax/crypto/JarVerifier +instanceKlass java/net/Inet6AddressImpl +instanceKlass java/net/InetAddressImpl +instanceKlass java/net/InetAddressImplFactory +instanceKlass java/net/InetAddress$Cache +instanceKlass java/net/InetAddress$InetAddressHolder +instanceKlass sun/misc/PostVMInitHook +instanceKlass java/lang/invoke/MethodHandleStatics$1 +instanceKlass java/lang/invoke/MethodHandleStatics +instanceKlass java/lang/invoke/MemberName$Factory +instanceKlass java/lang/ClassValue$Version +instanceKlass java/lang/ClassValue$Identity +instanceKlass java/lang/ClassValue +instanceKlass java/lang/invoke/MethodHandleImpl$3 +instanceKlass java/net/InetAddress$1 +instanceKlass java/lang/invoke/MethodHandleImpl$2 +instanceKlass java/util/function/Function +instanceKlass sun/security/action/GetBooleanAction +instanceKlass java/lang/invoke/MethodHandleImpl$1 +instanceKlass java/net/InetSocketAddress$InetSocketAddressHolder +instanceKlass java/net/InetAddress +instanceKlass java/lang/invoke/MethodHandleImpl +instanceKlass java/net/SocketAddress +instanceKlass java/net/Socket +instanceKlass com/intellij/rt/execution/application/AppMainV2 +instanceKlass sun/instrument/InstrumentationImpl$1 +instanceKlass com/intellij/rt/execution/application/AppMainV2$Agent +instanceKlass java/io/FilePermission$1 +instanceKlass sun/net/www/MessageHeader +instanceKlass java/net/URLConnection +instanceKlass java/security/PermissionCollection +instanceKlass java/util/zip/CRC32 +instanceKlass java/util/zip/Checksum +instanceKlass sun/nio/ByteBuffered +instanceKlass java/lang/Package +instanceKlass java/util/jar/Attributes$Name +instanceKlass java/util/jar/Attributes +instanceKlass sun/misc/Resource +instanceKlass sun/misc/IOUtils +instanceKlass sun/security/action/GetIntegerAction +instanceKlass sun/security/util/SignatureFileVerifier +instanceKlass java/util/zip/ZStreamRef +instanceKlass java/util/zip/Inflater +instanceKlass java/util/zip/ZipEntry +instanceKlass sun/misc/ExtensionDependency +instanceKlass sun/misc/JarIndex +instanceKlass sun/nio/ch/DirectBuffer +instanceKlass sun/misc/PerfCounter$CoreCounters +instanceKlass sun/misc/Perf +instanceKlass sun/misc/Perf$GetPerfAction +instanceKlass sun/misc/PerfCounter +instanceKlass java/util/zip/ZipCoder +instanceKlass java/util/Deque +instanceKlass java/util/Queue +instanceKlass java/nio/charset/StandardCharsets +instanceKlass java/util/jar/JavaUtilJarAccessImpl +instanceKlass sun/misc/JavaUtilJarAccess +instanceKlass sun/misc/FileURLMapper +instanceKlass sun/misc/URLClassPath$JarLoader$1 +instanceKlass sun/nio/cs/ThreadLocalCoders$Cache +instanceKlass sun/nio/cs/ThreadLocalCoders +instanceKlass java/util/zip/ZipFile$1 +instanceKlass sun/misc/JavaUtilZipFileAccess +instanceKlass java/util/zip/ZipFile +instanceKlass java/util/zip/ZipConstants +instanceKlass sun/misc/URLClassPath$Loader +instanceKlass sun/misc/URLClassPath$3 +instanceKlass sun/net/util/URLUtil +instanceKlass java/net/URLClassLoader$1 +instanceKlass sun/instrument/TransformerManager$TransformerInfo +instanceKlass sun/instrument/TransformerManager +instanceKlass sun/instrument/InstrumentationImpl +instanceKlass java/lang/instrument/Instrumentation +instanceKlass java/lang/SystemClassLoaderAction +instanceKlass sun/misc/Launcher$AppClassLoader$1 +instanceKlass sun/misc/URLClassPath +instanceKlass java/security/Principal +instanceKlass java/security/ProtectionDomain$Key +instanceKlass java/security/ProtectionDomain$2 +instanceKlass sun/misc/JavaSecurityProtectionDomainAccess +instanceKlass java/security/ProtectionDomain$JavaSecurityAccessImpl +instanceKlass sun/misc/JavaSecurityAccess +instanceKlass sun/net/util/IPAddressUtil +instanceKlass java/net/URLStreamHandler +instanceKlass java/net/Parts +instanceKlass java/util/BitSet +instanceKlass sun/net/www/ParseUtil +instanceKlass java/io/FileInputStream$1 +instanceKlass java/lang/CharacterData +instanceKlass sun/util/locale/LocaleUtils +instanceKlass java/util/Locale$LocaleKey +instanceKlass sun/util/locale/BaseLocale$Key +instanceKlass sun/util/locale/BaseLocale +instanceKlass java/util/concurrent/ConcurrentHashMap$CollectionView +instanceKlass java/util/concurrent/ConcurrentHashMap$CounterCell +instanceKlass java/util/concurrent/ConcurrentHashMap$Node +instanceKlass java/util/concurrent/locks/ReentrantLock +instanceKlass java/util/concurrent/locks/Lock +instanceKlass java/util/concurrent/ConcurrentMap +instanceKlass sun/util/locale/LocaleObjectCache +instanceKlass java/util/Locale +instanceKlass java/lang/reflect/Array +instanceKlass java/io/Reader +instanceKlass sun/misc/MetaIndex +instanceKlass java/util/StringTokenizer +instanceKlass sun/misc/Launcher$ExtClassLoader$1 +instanceKlass java/net/URLClassLoader$7 +instanceKlass sun/misc/JavaNetAccess +instanceKlass java/lang/ClassLoader$ParallelLoaders +instanceKlass sun/security/util/Debug +instanceKlass sun/misc/Launcher$Factory +instanceKlass java/net/URLStreamHandlerFactory +instanceKlass java/lang/Compiler$1 +instanceKlass java/lang/Compiler +instanceKlass java/lang/System$2 +instanceKlass sun/misc/JavaLangAccess +instanceKlass sun/io/Win32ErrorMode +instanceKlass sun/misc/OSEnvironment +instanceKlass java/lang/Integer$IntegerCache +instanceKlass sun/misc/NativeSignalHandler +instanceKlass sun/misc/Signal +instanceKlass java/lang/Terminator$1 +instanceKlass sun/misc/SignalHandler +instanceKlass java/lang/Terminator +instanceKlass java/io/ExpiringCache$Entry +instanceKlass java/lang/ClassLoaderHelper +instanceKlass java/lang/ClassLoader$NativeLibrary +instanceKlass java/lang/ClassLoader$3 +instanceKlass java/nio/charset/CoderResult$Cache +instanceKlass java/nio/charset/CoderResult +instanceKlass java/lang/Readable +instanceKlass java/lang/StringCoding$StringEncoder +instanceKlass java/nio/file/Path +instanceKlass java/nio/file/Watchable +instanceKlass java/lang/Enum +instanceKlass java/io/ExpiringCache +instanceKlass java/io/FileSystem +instanceKlass java/io/DefaultFileSystem +instanceKlass java/nio/Bits$1 +instanceKlass sun/misc/JavaNioAccess +instanceKlass java/nio/ByteOrder +instanceKlass java/nio/Bits +instanceKlass java/nio/charset/CharsetEncoder +instanceKlass sun/nio/cs/ArrayEncoder +instanceKlass sun/security/action/GetPropertyAction +instanceKlass java/io/Writer +instanceKlass sun/reflect/misc/ReflectUtil +instanceKlass java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl$1 +instanceKlass java/security/PrivilegedExceptionAction +instanceKlass java/util/concurrent/atomic/AtomicReferenceFieldUpdater +instanceKlass java/io/OutputStream +instanceKlass java/io/Flushable +instanceKlass java/io/FileDescriptor$1 +instanceKlass sun/misc/JavaIOFileDescriptorAccess +instanceKlass java/io/FileDescriptor +instanceKlass sun/misc/Version +instanceKlass java/lang/Runtime +instanceKlass java/util/Hashtable$Enumerator +instanceKlass java/util/Iterator +instanceKlass java/util/Enumeration +instanceKlass java/util/Objects +instanceKlass java/util/Collections$SynchronizedCollection +instanceKlass java/nio/charset/CodingErrorAction +instanceKlass java/nio/charset/CharsetDecoder +instanceKlass sun/nio/cs/ArrayDecoder +instanceKlass sun/nio/cs/ext/DelegatableDecoder +instanceKlass sun/nio/cs/ext/DoubleByte +instanceKlass java/lang/StringCoding$StringDecoder +instanceKlass java/lang/ThreadLocal$ThreadLocalMap +instanceKlass java/lang/StringCoding +instanceKlass sun/nio/cs/HistoricallyNamedCharset +instanceKlass java/util/TreeMap$Entry +instanceKlass sun/misc/ASCIICaseInsensitiveComparator +instanceKlass java/util/NavigableMap +instanceKlass java/util/SortedMap +instanceKlass sun/reflect/ReflectionFactory$1 +instanceKlass java/lang/Class$1 +instanceKlass java/nio/charset/Charset$ExtendedProviderHolder$1 +instanceKlass java/nio/charset/Charset$ExtendedProviderHolder +instanceKlass java/util/Arrays +instanceKlass java/lang/reflect/ReflectAccess +instanceKlass sun/reflect/LangReflectAccess +instanceKlass java/lang/reflect/Modifier +instanceKlass sun/reflect/annotation/AnnotationType +instanceKlass java/lang/Class$AnnotationData +instanceKlass sun/reflect/generics/repository/AbstractRepository +instanceKlass java/lang/Class$Atomic +instanceKlass java/lang/Class$ReflectionData +instanceKlass java/lang/Class$3 +instanceKlass java/lang/ThreadLocal +instanceKlass java/nio/charset/spi/CharsetProvider +instanceKlass java/nio/charset/Charset +instanceKlass java/lang/Math +instanceKlass java/util/Hashtable$Entry +instanceKlass sun/misc/VM +instanceKlass java/util/HashMap$Node +instanceKlass java/util/Map$Entry +instanceKlass sun/reflect/Reflection +instanceKlass sun/misc/SharedSecrets +instanceKlass java/lang/ref/Reference$1 +instanceKlass sun/misc/JavaLangRefAccess +instanceKlass java/lang/ref/ReferenceQueue$Lock +instanceKlass java/util/Collections$UnmodifiableCollection +instanceKlass java/util/AbstractMap +instanceKlass java/util/Set +instanceKlass java/util/Collections +instanceKlass java/lang/ref/Reference$Lock +instanceKlass sun/reflect/ReflectionFactory +instanceKlass java/util/AbstractCollection +instanceKlass java/util/RandomAccess +instanceKlass java/util/List +instanceKlass java/util/Collection +instanceKlass java/lang/Iterable +instanceKlass java/security/cert/Certificate +instanceKlass sun/reflect/ReflectionFactory$GetReflectionFactoryAction +instanceKlass java/security/PrivilegedAction +instanceKlass java/security/AccessController +instanceKlass java/security/Permission +instanceKlass java/security/Guard +instanceKlass java/lang/String$CaseInsensitiveComparator +instanceKlass java/util/Comparator +instanceKlass java/io/ObjectStreamField +instanceKlass java/lang/Number +instanceKlass java/lang/Character +instanceKlass java/lang/Boolean +instanceKlass java/nio/Buffer +instanceKlass java/lang/StackTraceElement +instanceKlass java/security/CodeSource +instanceKlass sun/misc/Launcher +instanceKlass java/util/jar/Manifest +instanceKlass java/net/URL +instanceKlass java/io/File +instanceKlass java/io/InputStream +instanceKlass java/io/Closeable +instanceKlass java/lang/AutoCloseable +instanceKlass sun/misc/Unsafe +instanceKlass java/lang/AbstractStringBuilder +instanceKlass java/lang/Appendable +instanceKlass java/lang/invoke/CallSite +instanceKlass java/lang/invoke/MethodType +instanceKlass java/lang/invoke/LambdaForm +instanceKlass java/lang/invoke/MethodHandleNatives +instanceKlass java/lang/invoke/MemberName +instanceKlass java/lang/invoke/MethodHandle +instanceKlass sun/reflect/CallerSensitive +instanceKlass java/lang/annotation/Annotation +instanceKlass sun/reflect/FieldAccessor +instanceKlass sun/reflect/ConstantPool +instanceKlass sun/reflect/ConstructorAccessor +instanceKlass sun/reflect/MethodAccessor +instanceKlass sun/reflect/MagicAccessorImpl +instanceKlass java/lang/reflect/Parameter +instanceKlass java/lang/reflect/Member +instanceKlass java/lang/reflect/AccessibleObject +instanceKlass java/util/Dictionary +instanceKlass java/util/Map +instanceKlass java/lang/ThreadGroup +instanceKlass java/lang/Thread$UncaughtExceptionHandler +instanceKlass java/lang/Thread +instanceKlass java/lang/Runnable +instanceKlass java/lang/ref/ReferenceQueue +instanceKlass java/lang/ref/Reference +instanceKlass java/security/AccessControlContext +instanceKlass java/security/ProtectionDomain +instanceKlass java/lang/SecurityManager +instanceKlass java/lang/Throwable +instanceKlass java/lang/System +instanceKlass java/lang/ClassLoader +instanceKlass java/lang/Cloneable +instanceKlass java/lang/Class +instanceKlass java/lang/reflect/Type +instanceKlass java/lang/reflect/GenericDeclaration +instanceKlass java/lang/reflect/AnnotatedElement +instanceKlass java/lang/String +instanceKlass java/lang/CharSequence +instanceKlass java/lang/Comparable +instanceKlass java/io/Serializable +ciInstanceKlass java/lang/Object 1 1 78 3 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 7 100 100 1 1 1 12 12 12 12 12 12 12 12 12 12 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/io/Serializable 1 0 7 1 1 1 100 100 1 +ciInstanceKlass java/lang/String 1 1 542 3 3 3 3 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 7 100 100 100 7 7 100 100 7 100 100 100 100 100 100 7 100 7 7 100 7 100 100 7 100 7 100 100 100 7 7 100 100 100 7 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 1 1 +staticfield java/lang/String serialPersistentFields [Ljava/io/ObjectStreamField; 0 [Ljava/io/ObjectStreamField; +staticfield java/lang/String CASE_INSENSITIVE_ORDER Ljava/util/Comparator; java/lang/String$CaseInsensitiveComparator +ciInstanceKlass java/lang/Class 1 1 1190 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 8 8 8 8 8 7 7 100 100 100 100 100 7 100 7 100 7 7 7 7 100 7 7 100 7 100 100 100 7 100 100 100 100 100 100 100 100 7 7 100 100 100 7 100 7 100 100 7 7 100 100 7 7 100 100 100 7 7 100 100 100 7 100 100 100 100 7 100 100 100 100 7 100 7 100 100 100 7 7 7 7 100 100 100 7 7 100 100 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 1 1 1 1 1 1 1 1 +staticfield java/lang/Class serialPersistentFields [Ljava/io/ObjectStreamField; 0 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/lang/Cloneable 1 0 7 1 1 1 100 100 1 +instanceKlass java/util/ResourceBundle$RBClassLoader +instanceKlass sun/reflect/DelegatingClassLoader +instanceKlass java/security/SecureClassLoader +ciInstanceKlass java/lang/ClassLoader 1 1 832 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 7 7 100 100 100 100 7 100 100 7 7 7 7 7 7 100 100 100 100 7 7 100 100 7 7 7 7 100 7 100 100 7 100 100 7 7 100 7 7 100 100 7 7 7 100 7 7 7 7 7 7 100 7 7 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 1 1 +staticfield java/lang/ClassLoader nocerts [Ljava/security/cert/Certificate; 0 [Ljava/security/cert/Certificate; +ciInstanceKlass java/lang/System 1 1 369 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 7 100 7 100 100 100 100 100 100 7 7 100 100 7 100 100 7 7 7 7 100 100 100 7 100 100 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield java/lang/System in Ljava/io/InputStream; java/io/BufferedInputStream +staticfield java/lang/System out Ljava/io/PrintStream; java/io/PrintStream +staticfield java/lang/System err Ljava/io/PrintStream; java/io/PrintStream +instanceKlass java/lang/Exception +instanceKlass java/lang/Error +ciInstanceKlass java/lang/Throwable 1 1 353 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 100 100 100 100 100 100 7 100 100 100 100 100 100 7 100 7 100 100 100 100 100 100 100 100 100 7 7 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 1 1 1 1 1 +staticfield java/lang/Throwable UNASSIGNED_STACK [Ljava/lang/StackTraceElement; 0 [Ljava/lang/StackTraceElement; +staticfield java/lang/Throwable SUPPRESSED_SENTINEL Ljava/util/List; java/util/Collections$UnmodifiableRandomAccessList +staticfield java/lang/Throwable EMPTY_THROWABLE_ARRAY [Ljava/lang/Throwable; 0 [Ljava/lang/Throwable; +staticfield java/lang/Throwable $assertionsDisabled Z 1 +instanceKlass java/util/ServiceConfigurationError +instanceKlass com/google/common/util/concurrent/ExecutionError +instanceKlass java/lang/AssertionError +instanceKlass org/apache/maven/BuildAbort +instanceKlass java/lang/VirtualMachineError +instanceKlass java/lang/LinkageError +instanceKlass java/lang/ThreadDeath +ciInstanceKlass java/lang/Error 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 1 1 12 12 12 12 12 10 10 10 10 10 1 +ciInstanceKlass java/lang/ThreadDeath 0 0 18 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 10 1 +instanceKlass java/util/concurrent/TimeoutException +instanceKlass java/util/concurrent/ExecutionException +instanceKlass com/google/inject/internal/ErrorsException +instanceKlass com/google/inject/internal/InternalProvisionException +instanceKlass org/codehaus/plexus/context/ContextException +instanceKlass java/text/ParseException +instanceKlass org/codehaus/plexus/PlexusContainerException +instanceKlass org/codehaus/plexus/component/repository/exception/ComponentLookupException +instanceKlass org/codehaus/plexus/util/xml/pull/XmlPullParserException +instanceKlass java/lang/CloneNotSupportedException +instanceKlass org/apache/commons/cli/ParseException +instanceKlass org/apache/maven/cli/MavenCli$ExitException +instanceKlass org/codehaus/plexus/classworlds/launcher/ConfigurationException +instanceKlass org/codehaus/plexus/classworlds/ClassWorldException +instanceKlass java/security/GeneralSecurityException +instanceKlass java/security/PrivilegedActionException +instanceKlass java/io/IOException +instanceKlass java/lang/InterruptedException +instanceKlass java/lang/ReflectiveOperationException +instanceKlass java/lang/RuntimeException +ciInstanceKlass java/lang/Exception 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 1 1 12 12 12 12 12 10 10 10 10 10 1 +instanceKlass java/lang/annotation/IncompleteAnnotationException +instanceKlass java/lang/reflect/UndeclaredThrowableException +instanceKlass com/google/common/util/concurrent/UncheckedExecutionException +instanceKlass com/google/common/cache/CacheLoader$InvalidCacheLoadException +instanceKlass java/util/NoSuchElementException +instanceKlass com/google/inject/CreationException +instanceKlass com/google/inject/ConfigurationException +instanceKlass com/google/inject/ProvisionException +instanceKlass java/lang/TypeNotPresentException +instanceKlass java/lang/IndexOutOfBoundsException +instanceKlass java/lang/SecurityException +instanceKlass java/lang/UnsupportedOperationException +instanceKlass java/lang/IllegalStateException +instanceKlass java/lang/IllegalArgumentException +instanceKlass java/lang/ArithmeticException +instanceKlass java/lang/NullPointerException +instanceKlass java/lang/IllegalMonitorStateException +instanceKlass java/lang/ArrayStoreException +instanceKlass java/lang/ClassCastException +ciInstanceKlass java/lang/RuntimeException 1 1 30 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 1 12 12 12 12 12 10 10 10 10 10 1 +ciInstanceKlass java/lang/SecurityManager 0 0 375 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/security/ProtectionDomain 1 1 272 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 100 100 100 100 100 100 100 100 100 7 7 100 7 7 100 7 7 7 100 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 1 1 +staticfield java/security/ProtectionDomain debug Lsun/security/util/Debug; null +ciInstanceKlass java/security/AccessControlContext 1 1 305 8 8 8 8 8 8 8 8 8 8 8 8 8 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 100 7 100 100 7 100 100 7 100 100 100 100 7 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 1 +instanceKlass java/net/URLClassLoader +ciInstanceKlass java/security/SecureClassLoader 1 1 130 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 100 100 100 7 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/security/SecureClassLoader debug Lsun/security/util/Debug; null +instanceKlass java/lang/NoSuchFieldException +instanceKlass java/lang/InstantiationException +instanceKlass java/lang/IllegalAccessException +instanceKlass java/lang/reflect/InvocationTargetException +instanceKlass java/lang/NoSuchMethodException +instanceKlass java/lang/ClassNotFoundException +ciInstanceKlass java/lang/ReflectiveOperationException 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 12 12 12 12 10 10 10 10 1 +ciInstanceKlass java/lang/ClassNotFoundException 1 1 32 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 1 1 1 12 12 12 9 10 10 1 +instanceKlass java/lang/UnsatisfiedLinkError +instanceKlass java/lang/IncompatibleClassChangeError +instanceKlass java/lang/BootstrapMethodError +instanceKlass java/lang/NoClassDefFoundError +ciInstanceKlass java/lang/LinkageError 1 1 24 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 12 12 12 10 10 10 1 +ciInstanceKlass java/lang/NoClassDefFoundError 0 0 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/ClassCastException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/ArrayStoreException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass java/lang/InternalError +instanceKlass java/lang/StackOverflowError +instanceKlass java/lang/OutOfMemoryError +ciInstanceKlass java/lang/VirtualMachineError 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 1 12 12 12 12 10 10 10 10 1 +ciInstanceKlass java/lang/OutOfMemoryError 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/StackOverflowError 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/IllegalMonitorStateException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass java/lang/ref/PhantomReference +instanceKlass java/lang/ref/FinalReference +instanceKlass java/lang/ref/WeakReference +instanceKlass java/lang/ref/SoftReference +ciInstanceKlass java/lang/ref/Reference 1 1 139 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 7 7 100 7 7 7 7 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 +instanceKlass com/google/common/cache/LocalCache$SoftValueReference +instanceKlass sun/util/locale/provider/LocaleResources$ResourceReference +instanceKlass java/util/ResourceBundle$BundleReference +instanceKlass org/eclipse/sisu/inject/MildKeys$Soft +instanceKlass sun/util/locale/LocaleObjectCache$CacheEntry +ciInstanceKlass java/lang/ref/SoftReference 1 1 35 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 7 1 1 1 1 12 12 12 12 12 9 9 10 10 10 1 +instanceKlass com/google/common/cache/LocalCache$WeakEntry +instanceKlass java/lang/reflect/WeakCache$CacheValue +instanceKlass java/lang/reflect/Proxy$Key1 +instanceKlass java/lang/reflect/WeakCache$CacheKey +instanceKlass com/google/common/cache/LocalCache$WeakValueReference +instanceKlass java/util/logging/LogManager$LoggerWeakRef +instanceKlass java/util/ResourceBundle$LoaderReference +instanceKlass org/eclipse/sisu/inject/MildKeys$Weak +instanceKlass java/lang/ClassValue$Entry +instanceKlass java/util/WeakHashMap$Entry +instanceKlass java/lang/ThreadLocal$ThreadLocalMap$Entry +ciInstanceKlass java/lang/ref/WeakReference 1 1 20 1 1 1 1 1 1 1 1 7 100 1 1 1 1 12 12 10 10 1 +instanceKlass java/lang/ref/Finalizer +ciInstanceKlass java/lang/ref/FinalReference 1 1 25 8 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 1 1 1 12 12 10 10 1 +instanceKlass sun/misc/Cleaner +ciInstanceKlass java/lang/ref/PhantomReference 1 1 19 1 1 1 1 1 1 1 1 1 1 100 7 1 1 1 12 10 1 +ciInstanceKlass java/lang/ref/Finalizer 1 1 140 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 7 7 100 7 7 100 100 7 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +staticfield java/lang/ref/Finalizer lock Ljava/lang/Object; java/lang/Object +instanceKlass java/lang/ref/ReferenceQueue$Null +ciInstanceKlass java/lang/ref/ReferenceQueue 1 1 130 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 100 7 100 100 100 100 100 7 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +staticfield java/lang/ref/ReferenceQueue $assertionsDisabled Z 1 +instanceKlass java/util/logging/LogManager$Cleaner +instanceKlass org/apache/maven/shared/utils/logging/MessageUtils$1 +instanceKlass com/intellij/rt/execution/application/AppMainV2$1 +instanceKlass java/lang/ref/Finalizer$FinalizerThread +instanceKlass java/lang/ref/Reference$ReferenceHandler +ciInstanceKlass java/lang/Thread 1 1 550 3 3 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 100 100 100 100 100 100 100 100 100 100 100 100 7 100 7 100 7 100 7 7 100 100 100 100 100 100 7 7 100 100 100 100 100 100 7 100 100 100 7 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 1 1 1 1 1 +staticfield java/lang/Thread EMPTY_STACK_TRACE [Ljava/lang/StackTraceElement; 0 [Ljava/lang/StackTraceElement; +staticfield java/lang/Thread SUBCLASS_IMPLEMENTATION_PERMISSION Ljava/lang/RuntimePermission; java/lang/RuntimePermission +ciInstanceKlass java/lang/ThreadGroup 1 1 268 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 7 100 100 7 7 100 100 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +instanceKlass java/util/Hashtable +ciInstanceKlass java/util/Dictionary 1 1 31 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 1 1 1 1 1 1 12 10 1 +instanceKlass java/util/Properties +ciInstanceKlass java/util/Hashtable 1 1 437 3 3 4 4 4 4 8 8 8 8 8 8 8 8 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 100 100 100 100 100 100 100 100 100 100 100 7 100 100 7 100 7 100 100 100 7 100 7 7 100 7 7 7 7 100 100 7 7 7 100 7 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 1 1 1 1 1 1 1 +instanceKlass java/security/Provider +ciInstanceKlass java/util/Properties 1 1 263 3 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 100 100 7 100 100 100 100 100 7 7 7 100 7 7 7 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 1 +staticfield java/util/Properties hexDigit [C 16 +instanceKlass java/lang/reflect/Executable +instanceKlass java/lang/reflect/Field +ciInstanceKlass java/lang/reflect/AccessibleObject 1 1 144 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 7 100 100 7 7 100 7 100 7 7 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 +staticfield java/lang/reflect/AccessibleObject ACCESS_PERMISSION Ljava/security/Permission; java/lang/reflect/ReflectPermission +staticfield java/lang/reflect/AccessibleObject reflectionFactory Lsun/reflect/ReflectionFactory; sun/reflect/ReflectionFactory +ciInstanceKlass java/lang/reflect/Field 1 1 362 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 100 100 100 100 7 7 100 100 100 7 7 7 7 7 100 7 7 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 1 1 +ciInstanceKlass java/lang/reflect/Parameter 0 0 210 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 +instanceKlass java/lang/reflect/Constructor +instanceKlass java/lang/reflect/Method +ciInstanceKlass java/lang/reflect/Executable 1 1 378 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 7 100 100 100 100 100 7 7 7 100 100 100 7 100 100 100 7 7 7 7 7 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 1 1 +ciInstanceKlass java/lang/reflect/Method 1 1 346 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 100 100 100 100 100 100 100 7 100 7 100 100 7 100 100 100 7 7 7 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 1 +ciInstanceKlass java/lang/reflect/Constructor 1 1 330 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 7 100 100 100 100 100 100 7 7 100 100 100 100 100 7 7 7 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 +instanceKlass sun/reflect/FieldAccessorImpl +instanceKlass sun/reflect/ConstructorAccessorImpl +instanceKlass sun/reflect/MethodAccessorImpl +ciInstanceKlass sun/reflect/MagicAccessorImpl 1 1 13 1 1 1 1 1 1 1 7 100 12 10 1 +instanceKlass sun/reflect/DelegatingMethodAccessorImpl +instanceKlass sun/reflect/NativeMethodAccessorImpl +ciInstanceKlass sun/reflect/MethodAccessorImpl 1 1 22 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 12 10 1 +instanceKlass sun/reflect/DelegatingConstructorAccessorImpl +instanceKlass sun/reflect/NativeConstructorAccessorImpl +ciInstanceKlass sun/reflect/ConstructorAccessorImpl 1 1 24 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 7 12 10 1 +ciInstanceKlass sun/reflect/DelegatingClassLoader 0 0 13 1 1 1 1 1 1 1 100 100 1 12 10 +ciInstanceKlass sun/reflect/ConstantPool 1 1 106 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass sun/reflect/UnsafeFieldAccessorImpl +ciInstanceKlass sun/reflect/FieldAccessorImpl 1 1 56 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 12 10 1 +instanceKlass sun/reflect/UnsafeStaticFieldAccessorImpl +ciInstanceKlass sun/reflect/UnsafeFieldAccessorImpl 1 1 230 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield sun/reflect/UnsafeFieldAccessorImpl unsafe Lsun/misc/Unsafe; sun/misc/Unsafe +instanceKlass sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl +ciInstanceKlass sun/reflect/UnsafeStaticFieldAccessorImpl 1 1 38 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 1 1 1 1 12 12 12 12 12 9 9 10 10 10 1 +ciInstanceKlass sun/reflect/CallerSensitive 0 0 17 1 1 1 1 1 1 1 1 100 100 100 1 1 1 1 1 +instanceKlass java/lang/invoke/DirectMethodHandle +ciInstanceKlass java/lang/invoke/MethodHandle 1 1 438 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 100 7 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 1 +staticfield java/lang/invoke/MethodHandle FORM_OFFSET J 20 +staticfield java/lang/invoke/MethodHandle $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/DirectMethodHandle 0 0 701 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 1 1 1 1 1 1 +ciInstanceKlass java/lang/invoke/MemberName 1 1 642 3 3 3 3 3 3 3 3 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 100 100 100 100 100 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 +staticfield java/lang/invoke/MemberName $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/MethodHandleNatives 1 1 427 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 +staticfield java/lang/invoke/MethodHandleNatives COUNT_GWT Z 1 +staticfield java/lang/invoke/MethodHandleNatives $assertionsDisabled Z 1 +ciInstanceKlass java/lang/invoke/LambdaForm 0 0 967 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 8 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 1 1 1 1 1 1 +ciInstanceKlass java/lang/invoke/MethodType 0 0 588 8 8 8 8 8 8 8 8 8 8 8 8 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 5 0 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 1 +ciInstanceKlass java/lang/BootstrapMethodError 0 0 38 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 1 1 12 12 12 12 12 10 10 10 10 10 1 +instanceKlass java/lang/invoke/VolatileCallSite +instanceKlass java/lang/invoke/MutableCallSite +instanceKlass java/lang/invoke/ConstantCallSite +ciInstanceKlass java/lang/invoke/CallSite 0 0 311 8 8 8 8 8 8 8 8 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +ciInstanceKlass java/lang/invoke/ConstantCallSite 0 0 42 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 1 1 12 12 12 12 12 12 9 9 10 10 10 10 10 1 +ciInstanceKlass java/lang/invoke/MutableCallSite 0 0 57 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/lang/invoke/VolatileCallSite 0 0 33 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 1 1 1 12 12 12 12 12 12 10 10 10 10 10 10 1 +instanceKlass java/lang/StringBuilder +instanceKlass java/lang/StringBuffer +ciInstanceKlass java/lang/AbstractStringBuilder 1 1 318 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 100 7 100 100 100 7 7 7 100 7 100 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 +ciInstanceKlass java/lang/StringBuffer 1 1 377 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 7 100 100 7 7 100 100 7 7 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 1 1 +staticfield java/lang/StringBuffer serialPersistentFields [Ljava/io/ObjectStreamField; 3 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/lang/StringBuilder 1 1 333 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 100 7 100 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +ciInstanceKlass sun/misc/Unsafe 1 1 389 8 8 7 7 7 7 7 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 100 7 100 100 7 7 7 100 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield sun/misc/Unsafe theUnsafe Lsun/misc/Unsafe; sun/misc/Unsafe +staticfield sun/misc/Unsafe ARRAY_BOOLEAN_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_BYTE_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_SHORT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_CHAR_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_INT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_LONG_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_FLOAT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_DOUBLE_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_OBJECT_BASE_OFFSET I 16 +staticfield sun/misc/Unsafe ARRAY_BOOLEAN_INDEX_SCALE I 1 +staticfield sun/misc/Unsafe ARRAY_BYTE_INDEX_SCALE I 1 +staticfield sun/misc/Unsafe ARRAY_SHORT_INDEX_SCALE I 2 +staticfield sun/misc/Unsafe ARRAY_CHAR_INDEX_SCALE I 2 +staticfield sun/misc/Unsafe ARRAY_INT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ARRAY_LONG_INDEX_SCALE I 8 +staticfield sun/misc/Unsafe ARRAY_FLOAT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ARRAY_DOUBLE_INDEX_SCALE I 8 +staticfield sun/misc/Unsafe ARRAY_OBJECT_INDEX_SCALE I 4 +staticfield sun/misc/Unsafe ADDRESS_SIZE I 8 +instanceKlass java/util/zip/ZipFile$ZipFileInputStream +instanceKlass java/io/FilterInputStream +instanceKlass java/io/FileInputStream +instanceKlass java/io/ByteArrayInputStream +ciInstanceKlass java/io/InputStream 1 1 61 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 5 0 100 100 100 100 100 100 100 7 12 12 12 12 12 10 10 10 10 10 10 10 1 +ciInstanceKlass java/io/ByteArrayInputStream 1 1 62 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 7 100 100 100 7 1 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 1 +ciInstanceKlass java/io/File 1 1 582 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 7 100 7 7 7 7 100 7 7 100 100 100 100 100 100 7 100 100 100 100 100 7 100 100 100 100 7 7 7 100 100 7 100 100 7 7 100 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 1 1 1 1 +staticfield java/io/File fs Ljava/io/FileSystem; java/io/WinNTFileSystem +staticfield java/io/File separatorChar C 92 +staticfield java/io/File separator Ljava/lang/String; "\" +staticfield java/io/File pathSeparatorChar C 59 +staticfield java/io/File pathSeparator Ljava/lang/String; ";" +staticfield java/io/File PATH_OFFSET J 16 +staticfield java/io/File PREFIX_LENGTH_OFFSET J 12 +staticfield java/io/File UNSAFE Lsun/misc/Unsafe; sun/misc/Unsafe +staticfield java/io/File $assertionsDisabled Z 1 +instanceKlass org/codehaus/plexus/classworlds/realm/ClassRealm +instanceKlass sun/misc/Launcher$ExtClassLoader +instanceKlass sun/misc/Launcher$AppClassLoader +ciInstanceKlass java/net/URLClassLoader 1 1 524 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 7 100 100 100 7 7 7 100 100 7 100 100 100 7 100 7 100 7 100 7 7 7 7 7 100 100 100 7 7 100 100 100 7 7 7 7 100 7 100 100 100 7 7 7 100 7 7 7 7 7 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 +ciInstanceKlass java/net/URL 1 1 584 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 100 7 100 7 7 100 100 100 100 100 7 7 100 100 7 7 100 100 100 100 7 100 100 100 100 7 7 7 100 100 100 7 7 7 100 7 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield java/net/URL serialPersistentFields [Ljava/io/ObjectStreamField; 7 [Ljava/io/ObjectStreamField; +ciInstanceKlass java/util/jar/Manifest 1 1 256 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 7 7 100 7 100 100 100 7 100 7 100 100 7 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 1 1 +ciInstanceKlass sun/misc/Launcher 1 1 222 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 100 100 100 100 100 100 7 100 7 100 7 7 100 7 7 100 7 7 7 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 1 +ciInstanceKlass sun/misc/Launcher$AppClassLoader 1 1 201 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 7 7 100 7 100 7 7 100 100 7 100 7 100 7 100 7 7 7 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 1 +staticfield sun/misc/Launcher$AppClassLoader $assertionsDisabled Z 1 +ciInstanceKlass sun/misc/Launcher$ExtClassLoader 1 1 243 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 100 7 100 7 7 100 100 100 7 7 100 100 100 7 100 100 100 7 7 7 7 7 100 7 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 +ciInstanceKlass java/security/CodeSource 1 1 324 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 100 100 100 100 7 100 100 100 7 100 7 100 100 100 100 100 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 1 +ciInstanceKlass java/lang/StackTraceElement 1 1 98 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 7 100 100 100 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass java/nio/LongBuffer +instanceKlass java/nio/CharBuffer +instanceKlass java/nio/ByteBuffer +ciInstanceKlass java/nio/Buffer 1 1 132 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 100 7 100 100 7 100 100 100 100 100 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/nio/Buffer $assertionsDisabled Z 1 +ciInstanceKlass java/lang/Boolean 1 1 110 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 7 100 100 100 7 100 7 7 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Boolean TRUE Ljava/lang/Boolean; java/lang/Boolean +staticfield java/lang/Boolean FALSE Ljava/lang/Boolean; java/lang/Boolean +staticfield java/lang/Boolean TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Character 1 1 459 3 3 3 3 3 3 3 3 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 0 5 0 100 100 7 100 100 100 100 7 100 7 100 100 100 100 100 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 1 1 1 1 1 +staticfield java/lang/Character TYPE Ljava/lang/Class; java/lang/Class +staticfield java/lang/Character $assertionsDisabled Z 1 +instanceKlass java/util/concurrent/atomic/AtomicLong +instanceKlass java/util/concurrent/atomic/AtomicInteger +instanceKlass java/lang/Long +instanceKlass java/lang/Integer +instanceKlass java/lang/Short +instanceKlass java/lang/Byte +instanceKlass java/lang/Double +instanceKlass java/lang/Float +ciInstanceKlass java/lang/Number 1 1 34 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 7 12 12 10 10 1 +ciInstanceKlass java/lang/Float 1 1 169 3 3 3 4 4 4 4 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 4 4 5 0 7 100 100 7 100 100 100 100 7 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Float TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Double 1 1 223 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 5 0 5 0 5 0 6 0 6 0 6 0 6 0 6 0 6 0 6 0 7 100 7 100 100 100 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/lang/Double TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Byte 1 1 153 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 7 100 7 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Byte TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Short 1 1 159 3 3 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 5 0 5 0 7 100 100 7 100 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Short TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/Integer 1 1 313 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 5 0 5 0 5 0 100 7 7 100 100 7 7 100 100 100 7 100 100 100 7 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Integer TYPE Ljava/lang/Class; java/lang/Class +staticfield java/lang/Integer digits [C 36 +staticfield java/lang/Integer DigitTens [C 100 +staticfield java/lang/Integer DigitOnes [C 100 +staticfield java/lang/Integer sizeTable [I 10 +ciInstanceKlass java/lang/Long 1 1 360 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 100 100 7 100 100 7 7 100 7 100 100 100 100 100 7 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/lang/Long TYPE Ljava/lang/Class; java/lang/Class +ciInstanceKlass java/lang/NullPointerException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +ciInstanceKlass java/lang/ArithmeticException 1 1 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass sun/nio/cs/US_ASCII$Decoder +instanceKlass sun/nio/cs/UTF_8$Decoder +instanceKlass sun/nio/cs/ext/DoubleByte$Decoder +ciInstanceKlass java/nio/charset/CharsetDecoder 1 1 275 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 100 7 100 100 7 7 100 100 100 100 7 100 100 7 100 7 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +staticfield java/nio/charset/CharsetDecoder $assertionsDisabled Z 1 +instanceKlass java/nio/MappedByteBuffer +instanceKlass java/nio/HeapByteBuffer +ciInstanceKlass java/nio/ByteBuffer 1 1 254 8 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 7 7 100 100 7 7 100 7 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass java/nio/HeapCharBuffer +ciInstanceKlass java/nio/CharBuffer 1 1 256 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 7 100 100 7 100 7 100 100 100 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 15 15 16 16 18 1 1 1 +ciInstanceKlass java/nio/HeapCharBuffer 1 1 138 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 100 100 100 100 100 7 7 100 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass java/nio/charset/CoderResult 1 1 139 8 8 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 100 7 7 7 100 100 100 100 100 7 7 100 100 100 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield java/nio/charset/CoderResult names [Ljava/lang/String; 4 [Ljava/lang/String; +staticfield java/nio/charset/CoderResult UNDERFLOW Ljava/nio/charset/CoderResult; java/nio/charset/CoderResult +staticfield java/nio/charset/CoderResult OVERFLOW Ljava/nio/charset/CoderResult; java/nio/charset/CoderResult +staticfield java/nio/charset/CoderResult $assertionsDisabled Z 1 +ciInstanceKlass java/lang/IllegalArgumentException 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 1 12 12 12 12 10 10 10 10 1 +instanceKlass java/io/FilterReader +instanceKlass org/codehaus/plexus/util/xml/XmlReader +instanceKlass java/io/StringReader +instanceKlass sun/nio/cs/StreamDecoder +instanceKlass java/io/InputStreamReader +instanceKlass java/io/BufferedReader +ciInstanceKlass java/io/Reader 1 1 85 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 5 0 100 100 100 7 100 100 100 7 100 100 100 1 1 1 12 12 12 12 12 12 12 12 9 9 10 10 10 10 10 10 10 10 1 +instanceKlass java/io/FileReader +ciInstanceKlass java/io/InputStreamReader 1 1 82 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 7 7 100 100 100 100 100 100 7 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 9 10 10 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass sun/nio/cs/StreamDecoder 1 1 308 8 8 8 8 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 100 100 100 7 7 100 100 7 100 100 100 100 100 100 7 7 100 100 7 7 7 7 100 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 1 +staticfield sun/nio/cs/StreamDecoder $assertionsDisabled Z 1 +ciInstanceKlass sun/nio/cs/UTF_8$Decoder 1 1 217 3 3 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 7 7 100 100 7 7 7 7 100 100 100 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 +staticfield sun/nio/cs/UTF_8$Decoder $assertionsDisabled Z 1 +instanceKlass java/net/SocketException +instanceKlass java/io/ObjectStreamException +instanceKlass java/io/EOFException +instanceKlass java/io/UnsupportedEncodingException +instanceKlass org/codehaus/plexus/util/xml/XmlReaderException +instanceKlass java/io/FileNotFoundException +instanceKlass java/net/MalformedURLException +instanceKlass java/util/zip/ZipException +ciInstanceKlass java/io/IOException 1 1 27 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 7 1 12 12 12 12 10 10 10 10 1 +instanceKlass org/codehaus/plexus/util/xml/XmlStreamReader +ciInstanceKlass org/codehaus/plexus/util/xml/XmlReader 1 1 416 9 100 10 10 10 10 9 10 100 10 10 10 100 10 10 10 10 10 8 10 10 10 7 10 8 10 10 10 10 10 7 8 10 9 9 10 10 7 10 10 10 10 10 10 10 10 7 10 8 10 8 8 9 100 10 10 100 10 9 10 10 8 9 10 9 9 8 10 10 10 9 10 10 10 9 10 10 10 10 8 10 7 10 10 8 8 10 8 7 7 10 10 10 9 8 8 8 8 8 10 8 8 8 10 8 7 10 7 8 10 8 8 8 8 7 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 1 1 1 1 1 1 100 1 1 1 1 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 1 1 1 1 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 1 1 1 1 1 1 1 12 1 12 12 12 12 12 12 1 12 100 12 12 1 100 12 12 12 12 12 1 12 12 12 1 1 12 12 12 12 1 1 12 12 12 12 12 1 12 12 12 12 12 12 12 12 1 12 1 12 1 1 12 1 12 12 1 12 12 12 12 1 12 12 12 12 1 12 12 12 12 12 7 12 12 7 12 12 12 12 12 1 12 1 12 12 1 1 12 1 1 1 12 12 12 1 1 1 1 1 12 1 1 1 12 1 1 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +staticfield org/codehaus/plexus/util/xml/XmlReader CHARSET_PATTERN Ljava/util/regex/Pattern; java/util/regex/Pattern +staticfield org/codehaus/plexus/util/xml/XmlReader ENCODING_PATTERN Ljava/util/regex/Pattern; java/util/regex/Pattern +staticfield org/codehaus/plexus/util/xml/XmlReader RAW_EX_1 Ljava/text/MessageFormat; java/text/MessageFormat +staticfield org/codehaus/plexus/util/xml/XmlReader RAW_EX_2 Ljava/text/MessageFormat; java/text/MessageFormat +staticfield org/codehaus/plexus/util/xml/XmlReader HTTP_EX_1 Ljava/text/MessageFormat; java/text/MessageFormat +staticfield org/codehaus/plexus/util/xml/XmlReader HTTP_EX_2 Ljava/text/MessageFormat; java/text/MessageFormat +staticfield org/codehaus/plexus/util/xml/XmlReader HTTP_EX_3 Ljava/text/MessageFormat; java/text/MessageFormat +ciInstanceKlass org/codehaus/plexus/util/xml/XmlStreamReader 1 1 55 10 10 10 10 10 10 10 10 100 7 1 1 1 1 1 1 1 1 1 1 100 1 1 1 1 1 1 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 1 1 1 1 +ciInstanceKlass java/lang/AssertionError 0 0 65 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 100 100 100 1 1 1 1 1 1 1 1 12 12 12 12 12 12 12 12 12 12 12 10 10 10 10 10 10 10 10 10 10 10 10 1 +instanceKlass java/lang/ArrayIndexOutOfBoundsException +instanceKlass java/lang/StringIndexOutOfBoundsException +ciInstanceKlass java/lang/IndexOutOfBoundsException 0 0 21 1 1 1 1 1 1 1 1 1 1 1 5 0 100 100 12 12 10 10 1 +instanceKlass org/codehaus/plexus/util/InterpolationFilterReader +ciInstanceKlass java/io/FilterReader 1 1 50 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 100 7 1 1 1 12 12 12 12 12 12 12 12 12 12 9 10 10 10 10 10 10 10 10 10 1 +ciInstanceKlass org/codehaus/plexus/util/InterpolationFilterReader 1 1 144 10 9 9 9 7 10 9 9 9 10 9 9 7 8 8 10 100 8 10 10 10 9 10 100 10 10 10 10 10 11 10 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 100 100 100 1 1 12 12 12 12 1 12 12 12 12 7 12 12 12 1 1 1 12 1 1 12 12 12 12 7 1 12 12 12 100 12 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +ciMethod java/lang/Object ()V 4097 1 48932 0 -1 +ciMethod java/lang/String length ()I 4097 1 49564 0 -1 +ciMethod java/lang/String charAt (I)C 4097 1 178997 0 -1 +ciMethod java/nio/Buffer (IIII)V 1457 1 4489 0 0 +ciMethod java/nio/Buffer position ()I 1089 1 136 0 -1 +ciMethod java/nio/Buffer position (I)Ljava/nio/Buffer; 2121 1 8522 0 -1 +ciMethod java/nio/Buffer limit (I)Ljava/nio/Buffer; 2073 1 4499 0 -1 +ciMethod java/nio/Buffer hasRemaining ()Z 2065 1 344 0 -1 +ciMethod java/nio/charset/CharsetDecoder decode (Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;Z)Ljava/nio/charset/CoderResult; 1697 1 4434 0 -1 +ciMethod java/nio/charset/CharsetDecoder reset ()Ljava/nio/charset/CharsetDecoder; 2049 1 1128 0 -1 +ciMethod java/nio/CharBuffer (IIII[CI)V 681 1 4283 0 0 +ciMethod java/nio/CharBuffer wrap ([CII)Ljava/nio/CharBuffer; 41 1 4107 0 0 +ciMethod java/nio/CharBuffer slice ()Ljava/nio/CharBuffer; 0 0 1 0 -1 +ciMethod java/nio/HeapCharBuffer ([CII)V 41 1 4107 0 0 +ciMethod java/nio/charset/CoderResult isUnderflow ()Z 2089 1 4770 0 -1 +ciMethod java/nio/charset/CoderResult isOverflow ()Z 2073 1 8531 0 -1 +ciMethod java/nio/charset/CoderResult throwException ()V 0 0 1 0 -1 +ciMethod java/io/Reader read ()I 4097 1 7119 0 0 +ciMethod java/io/Reader read ([CII)I 0 0 1 0 -1 +ciMethod java/io/InputStreamReader read ([CII)I 4017 1 8096 0 0 +ciMethod sun/nio/cs/StreamDecoder ensureOpen ()V 3377 1 12297 0 0 +ciMethod sun/nio/cs/StreamDecoder read0 ()I 2049 1 4096 0 0 +ciMethod sun/nio/cs/StreamDecoder read ([CII)I 3257 1 12188 0 0 +ciMethod sun/nio/cs/StreamDecoder readBytes ()I 81 1 10 0 -1 +ciMethod sun/nio/cs/StreamDecoder implRead ([CII)I 2345 49 4105 0 0 +ciMethod sun/nio/cs/StreamDecoder inReady ()Z 33 1 4 0 -1 +ciMethod sun/nio/cs/StreamDecoder implReady ()Z 0 0 1 0 0 +ciMethodData java/nio/CharBuffer wrap ([CII)Ljava/nio/CharBuffer; 2 4107 orig 264 120 103 101 171 255 127 0 0 168 210 108 40 108 1 0 0 80 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 49 128 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 5 0 2 0 0 0 32 0 0 0 254 255 255 255 2 0 7 0 0 0 0 0 data 4 0x70002 0x1006 0x100002 0x0 oops 0 +ciMethodData java/nio/HeapCharBuffer ([CII)V 2 4107 orig 264 120 103 101 171 255 127 0 0 0 255 108 40 108 1 0 0 72 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 49 128 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 3 0 2 0 0 0 16 0 0 0 254 255 255 255 2 0 10 0 0 0 0 0 data 2 0xa0002 0x1006 oops 0 +ciMethodData java/nio/CharBuffer (IIII[CI)V 2 4283 orig 264 120 103 101 171 255 127 0 0 176 208 108 40 108 1 0 0 96 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 0 0 0 49 131 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 3 0 2 0 0 0 16 0 0 0 254 255 255 255 2 0 6 0 0 0 0 0 data 2 0x60002 0x1066 oops 0 +ciMethod org/codehaus/plexus/util/xml/XmlReader read ([CII)I 3833 1 7851 0 0 +ciMethod org/codehaus/plexus/util/InterpolationFilterReader read ()I 4097 1 6743 0 -1 +ciMethodData sun/nio/cs/StreamDecoder read ([CII)I 2 12297 orig 264 120 103 101 171 255 127 0 0 32 224 110 40 108 1 0 0 136 3 0 0 224 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 136 1 0 0 145 115 1 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 53 0 2 0 0 0 40 2 0 0 254 255 255 255 2 0 15 0 0 0 0 0 data 69 0xf0002 0x2e72 0x140007 0x0 0xa0 0x2e72 0x1b0007 0x0 0x80 0x2e72 0x200007 0x0 0x60 0x2e72 0x2a0007 0x0 0x40 0x2e72 0x320007 0x2e72 0x30 0x0 0x390002 0x0 0x3f0007 0x2e72 0x20 0x0 0x4e0007 0x1ef6 0x90 0xf7c 0x690007 0xf7c 0x70 0x0 0x6d0005 0x0 0x0 0x0 0x0 0x0 0x700007 0x0 0x20 0x0 0x7c0007 0xf7b 0x88 0xf7b 0x800002 0xf7b 0x880007 0xf7b 0x58 0x0 0x8d0007 0x0 0x38 0x0 0x910003 0x0 0x18 0xb40005 0x0 0x16c2c6d80a0 0xf7b 0x0 0x0 oops 1 65 sun/nio/cs/StreamDecoder +ciMethodData sun/nio/cs/StreamDecoder ensureOpen ()V 2 12297 orig 264 120 103 101 171 255 127 0 0 112 217 110 40 108 1 0 0 80 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 163 1 0 0 25 115 1 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 5 0 2 0 0 0 48 0 0 0 254 255 255 255 7 0 4 0 0 0 0 0 data 6 0x40007 0x2e63 0x30 0x0 0xd0002 0x0 oops 0 +ciMethodData java/io/InputStreamReader read ([CII)I 2 8200 orig 264 120 103 101 171 255 127 0 0 8 200 110 40 108 1 0 0 144 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 244 1 0 0 145 240 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 3 0 2 0 0 0 48 0 0 0 254 255 255 255 5 0 7 0 0 0 0 0 data 6 0x70005 0x0 0x16c2c6d80a0 0x1e12 0x0 0x0 oops 1 2 sun/nio/cs/StreamDecoder +ciMethodData java/io/Reader read ()I 2 7739 orig 264 120 103 101 171 255 127 0 0 0 177 110 40 108 1 0 0 152 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 193 225 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 5 0 2 0 0 0 80 0 0 0 254 255 255 255 5 0 8 0 0 0 0 0 data 10 0x80005 0x0 0x16c2c6f0860 0x1c39 0x0 0x0 0xc0007 0x1c38 0x20 0x0 oops 1 2 org/codehaus/plexus/util/xml/XmlStreamReader +ciMethodData sun/nio/cs/StreamDecoder read0 ()I 2 4096 orig 264 120 103 101 171 255 127 0 0 128 222 110 40 108 1 0 0 40 2 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 120 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 19 0 2 0 0 0 224 0 0 0 254 255 255 255 7 0 11 0 0 0 0 0 data 28 0xb0007 0xf00 0x20 0x0 0x220005 0x0 0x16c2c6d80a0 0xf00 0x0 0x0 0x270008 0xa 0x0 0x60 0x0 0x60 0x0 0x60 0x0 0x60 0x57c 0x60 0x5d0007 0x0 0x30 0x0 0x650002 0x0 oops 1 6 sun/nio/cs/StreamDecoder +ciMethodData sun/nio/cs/StreamDecoder implRead ([CII)I 2 4105 orig 264 120 103 101 171 255 127 0 0 64 233 110 40 108 1 0 0 96 7 0 0 192 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 1 0 0 33 119 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1 0 56 0 2 0 0 0 0 6 0 0 254 255 255 255 7 0 3 0 0 0 0 0 data 192 0x30007 0xee4 0x50 0x0 0xa0007 0x0 0x30 0x0 0x110002 0x0 0x1a0002 0xee4 0x210005 0x36b 0x16c2b0deb20 0xb79 0x0 0x0 0x240007 0xee4 0x50 0x0 0x290005 0x0 0x0 0x0 0x0 0x0 0x3d0005 0x36b 0x16c2b0debd0 0xb79 0x0 0x0 0x440005 0x0 0x16c2c853890 0xee4 0x0 0x0 0x470007 0xee3 0x288 0x1 0x4c0007 0x1 0x38 0x0 0x4f0003 0x0 0x360 0x540005 0x0 0x16c2b0deb20 0x1 0x0 0x0 0x570007 0x0 0x38 0x1 0x5a0003 0x1 0x2f8 0x5f0005 0x0 0x0 0x0 0x0 0x0 0x620007 0x0 0x68 0x0 0x660002 0x0 0x690007 0x0 0x38 0x0 0x6c0003 0x0 0x260 0x700002 0x0 0x770007 0x0 0xfffffffffffffe38 0x0 0x7f0005 0x0 0x0 0x0 0x0 0x0 0x820007 0x0 0x88 0x0 0x890005 0x0 0x0 0x0 0x0 0x0 0x8c0007 0x0 0x38 0x0 0x8f0003 0x0 0x178 0x960005 0x0 0x0 0x0 0x0 0x0 0x9a0003 0x0 0xfffffffffffffd30 0x9f0005 0x0 0x16c2c853890 0xee3 0x0 0x0 0xa20007 0x0 0xa0 0xee3 0xa80007 0xee3 0xc8 0x0 0xad0005 0x0 0x0 0x0 0x0 0x0 0xb00007 0x0 0x78 0x0 0xb70002 0x0 0xbd0005 0x0 0x0 0x0 0x0 0x0 0xc00003 0x0 0xfffffffffffffc18 0xc50007 0xee4 0x50 0x0 0xcc0005 0x0 0x0 0x0 0x0 0x0 0xd20005 0x36b 0x16c2b0deb20 0xb79 0x0 0x0 0xd50007 0xee4 0x70 0x0 0xda0007 0x0 0x20 0x0 0xe20007 0x0 0x30 0x0 0xe90002 0x0 0xef0005 0x36b 0x16c2b0deb20 0xb79 0x0 0x0 oops 7 14 java/nio/HeapCharBuffer 30 sun/nio/cs/UTF_8$Decoder 36 java/nio/charset/CoderResult 53 java/nio/HeapCharBuffer 123 java/nio/charset/CoderResult 168 java/nio/HeapCharBuffer 188 java/nio/HeapCharBuffer +ciMethodData org/codehaus/plexus/util/xml/XmlReader read ([CII)I 2 7988 orig 264 120 103 101 171 255 127 0 0 112 22 160 40 108 1 0 0 144 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 221 1 0 0 145 234 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 3 0 2 0 0 0 48 0 0 0 254 255 255 255 5 0 7 0 0 0 0 0 data 6 0x70005 0x0 0x16c2c885bb0 0x1d52 0x0 0x0 oops 1 2 java/io/InputStreamReader +ciMethodData org/codehaus/plexus/util/InterpolationFilterReader read ()I 2 6856 orig 264 120 103 101 171 255 127 0 0 16 188 178 40 108 1 0 0 112 9 0 0 72 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 68 79 32 101 120 116 114 97 32 100 97 116 97 32 108 111 99 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 185 197 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 2 0 135 0 2 0 0 0 40 8 0 0 254 255 255 255 7 0 5 0 0 0 0 0 data 261 0x50007 0x18b7 0xf0 0x0 0x100005 0x0 0x0 0x0 0x0 0x0 0x130007 0x0 0xa0 0x0 0x250005 0x0 0x0 0x0 0x0 0x0 0x310005 0x0 0x0 0x0 0x0 0x0 0x340007 0x0 0x20 0x0 0x430007 0x18b7 0x88 0x0 0x4e0007 0x0 0x68 0x0 0x600005 0x0 0x0 0x0 0x0 0x0 0x640003 0x0 0x48 0x6b0005 0x0 0x16c2c6f0860 0x18b7 0x0 0x0 0x750005 0x17ed 0x16c2b04acb0 0xca 0x0 0x0 0x780007 0x18b7 0x650 0x0 0x7f0002 0x0 0x8a0007 0x0 0x88 0x0 0x950007 0x0 0x68 0x0 0xa70005 0x0 0x0 0x0 0x0 0x0 0xab0003 0x0 0x48 0xb20005 0x0 0x0 0x0 0x0 0x0 0xb80007 0x0 0x128 0x0 0xbe0005 0x0 0x0 0x0 0x0 0x0 0xc70007 0x0 0x88 0x0 0xd30005 0x0 0x0 0x0 0x0 0x0 0xd60007 0x0 0x38 0x0 0xdb0003 0x0 0x68 0xe40005 0x0 0x0 0x0 0x0 0x0 0xe70007 0x0 0xfffffffffffffe40 0x0 0xec0007 0x0 0x1d0 0x0 0xf40007 0x0 0x1b0 0x0 0xff0007 0x0 0x88 0x0 0x10a0007 0x0 0x68 0x0 0x11c0005 0x0 0x0 0x0 0x0 0x0 0x1200003 0x0 0x48 0x1270005 0x0 0x0 0x0 0x0 0x0 0x12d0007 0x0 0xd8 0x0 0x1330005 0x0 0x0 0x0 0x0 0x0 0x1410005 0x0 0x0 0x0 0x0 0x0 0x1440007 0x0 0x38 0x0 0x1490003 0x0 0x38 0x1520007 0x0 0xfffffffffffffe90 0x0 0x1570007 0x0 0x80 0x0 0x15c0005 0x0 0x0 0x0 0x0 0x0 0x16c0005 0x0 0x0 0x0 0x0 0x0 0x1780005 0x0 0x0 0x0 0x0 0x0 0x1800005 0x0 0x0 0x0 0x0 0x0 0x18b0005 0x0 0x0 0x0 0x0 0x0 0x1940007 0x0 0xd0 0x0 0x1990005 0x0 0x0 0x0 0x0 0x0 0x1a00005 0x0 0x0 0x0 0x0 0x0 0x1a30007 0x0 0x20 0x0 0x1b20005 0x0 0x0 0x0 0x0 0x0 0x1bf0005 0x0 0x0 0x0 0x0 0x0 0x1c70005 0x0 0x0 0x0 0x0 0x0 0x1d70005 0x0 0x0 0x0 0x0 0x0 oops 2 49 org/codehaus/plexus/util/xml/XmlStreamReader 55 java/lang/String +compile org/codehaus/plexus/util/InterpolationFilterReader read ()I -1 4 inline 14 0 -1 org/codehaus/plexus/util/InterpolationFilterReader read ()I 1 107 java/io/Reader read ()I 2 8 org/codehaus/plexus/util/xml/XmlReader read ([CII)I 3 7 java/io/InputStreamReader read ([CII)I 4 7 sun/nio/cs/StreamDecoder read ([CII)I 5 15 sun/nio/cs/StreamDecoder ensureOpen ()V 5 128 sun/nio/cs/StreamDecoder read0 ()I 6 34 sun/nio/cs/StreamDecoder read ([CII)I 7 15 sun/nio/cs/StreamDecoder ensureOpen ()V 7 128 sun/nio/cs/StreamDecoder read0 ()I 7 180 sun/nio/cs/StreamDecoder implRead ([CII)I 8 26 java/nio/CharBuffer wrap ([CII)Ljava/nio/CharBuffer; 9 7 java/nio/HeapCharBuffer ([CII)V 10 10 java/nio/CharBuffer (IIII[CI)V diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java new file mode 100644 index 0000000..3f1c825 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java @@ -0,0 +1,20 @@ +package com.xxl.job.admin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @author xuxueli 2018-10-28 00:38:13 + */ +@SpringBootApplication +@EnableDiscoveryClient // 开启服务发现 +@EnableFeignClients +public class XxlJobAdminApplication { + + public static void main(String[] args) { + SpringApplication.run(XxlJobAdminApplication.class, args); + } + +} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java new file mode 100644 index 0000000..eb63f0b --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java @@ -0,0 +1,96 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.service.LoginService; +import com.xxl.job.admin.service.XxlJobService; +import com.xxl.job.core.biz.model.ReturnT; +import org.springframework.beans.propertyeditors.CustomDateEditor; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.RedirectView; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +/** + * index controller + * @author xuxueli 2015-12-19 16:13:16 + */ +@Controller +public class IndexController { + + @Resource + private XxlJobService xxlJobService; + @Resource + private LoginService loginService; + + + @RequestMapping("/") + public String index(Model model) { + + Map dashboardMap = xxlJobService.dashboardInfo(); + model.addAllAttributes(dashboardMap); + + return "index"; + } + + @RequestMapping("/chartInfo") + @ResponseBody + public ReturnT> chartInfo(Date startDate, Date endDate) { + ReturnT> chartInfo = xxlJobService.chartInfo(startDate, endDate); + return chartInfo; + } + + @RequestMapping("/toLogin") + @PermissionLimit(limit=false) + public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response,ModelAndView modelAndView) { + if (loginService.ifLogin(request, response) != null) { + modelAndView.setView(new RedirectView("/",true,false)); + return modelAndView; + } + return new ModelAndView("login"); + } + + @RequestMapping(value="login", method=RequestMethod.POST) + @ResponseBody + @PermissionLimit(limit=false) + public ReturnT loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){ + boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false; + return loginService.login(request, response, userName, password, ifRem); + } + + @RequestMapping(value="logout", method=RequestMethod.POST) + @ResponseBody + @PermissionLimit(limit=false) + public ReturnT logout(HttpServletRequest request, HttpServletResponse response){ + return loginService.logout(request, response); + } + + @RequestMapping("/help") + public String help() { + + /*if (!PermissionInterceptor.ifLogin(request)) { + return "redirect:/toLogin"; + }*/ + + return "help"; + } + + @InitBinder + public void initBinder(WebDataBinder binder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setLenient(false); + binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java new file mode 100644 index 0000000..aa51e73 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java @@ -0,0 +1,72 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.core.biz.AdminBiz; +import com.xxl.job.core.biz.model.HandleCallbackParam; +import com.xxl.job.core.biz.model.RegistryParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.util.GsonTool; +import com.xxl.job.core.util.XxlJobRemotingUtil; +import org.springframework.stereotype.Controller; +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.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * Created by xuxueli on 17/5/10. + */ +@Controller +@RequestMapping("/api") +public class JobApiController { + + @Resource + private AdminBiz adminBiz; + + /** + * api + * + * @param uri + * @param data + * @return + */ + @RequestMapping("/{uri}") + @ResponseBody + @PermissionLimit(limit=false) + public ReturnT api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) { + + // valid + if (!"POST".equalsIgnoreCase(request.getMethod())) { + return new ReturnT(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support."); + } + if (uri==null || uri.trim().length()==0) { + return new ReturnT(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty."); + } + if (XxlJobAdminConfig.getAdminConfig().getAccessToken()!=null + && XxlJobAdminConfig.getAdminConfig().getAccessToken().trim().length()>0 + && !XxlJobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(XxlJobRemotingUtil.XXL_JOB_ACCESS_TOKEN))) { + return new ReturnT(ReturnT.FAIL_CODE, "The access token is wrong."); + } + + // services mapping + if ("callback".equals(uri)) { + List callbackParamList = GsonTool.fromJson(data, List.class, HandleCallbackParam.class); + return adminBiz.callback(callbackParamList); + } else if ("registry".equals(uri)) { + RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class); + return adminBiz.registry(registryParam); + } else if ("registryRemove".equals(uri)) { + RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class); + return adminBiz.registryRemove(registryParam); + } else { + return new ReturnT(ReturnT.FAIL_CODE, "invalid request, uri-mapping("+ uri +") not found."); + } + + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java new file mode 100644 index 0000000..fe4a0e8 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java @@ -0,0 +1,96 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLogGlue; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobInfoDao; +import com.xxl.job.admin.dao.XxlJobLogGlueDao; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.glue.GlueTypeEnum; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.List; + +/** + * job code controller + * @author xuxueli 2015-12-19 16:13:16 + */ +@Controller +@RequestMapping("/jobcode") +public class JobCodeController { + + @Resource + private XxlJobInfoDao xxlJobInfoDao; + @Resource + private XxlJobLogGlueDao xxlJobLogGlueDao; + + @RequestMapping + public String index(HttpServletRequest request, Model model, int jobId) { + XxlJobInfo jobInfo = xxlJobInfoDao.loadById(jobId); + List jobLogGlues = xxlJobLogGlueDao.findByJobId(jobId); + + if (jobInfo == null) { + throw new RuntimeException(I18nUtil.getString("jobinfo_glue_jobid_unvalid")); + } + if (GlueTypeEnum.BEAN == GlueTypeEnum.match(jobInfo.getGlueType())) { + throw new RuntimeException(I18nUtil.getString("jobinfo_glue_gluetype_unvalid")); + } + + // valid permission + JobInfoController.validPermission(request, jobInfo.getJobGroup()); + + // Glue类型-字典 + model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); + + model.addAttribute("jobInfo", jobInfo); + model.addAttribute("jobLogGlues", jobLogGlues); + return "jobcode/jobcode.index"; + } + + @RequestMapping("/save") + @ResponseBody + public ReturnT save(Model model, int id, String glueSource, String glueRemark) { + // valid + if (glueRemark==null) { + return new ReturnT(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_glue_remark")) ); + } + if (glueRemark.length()<4 || glueRemark.length()>100) { + return new ReturnT(500, I18nUtil.getString("jobinfo_glue_remark_limit")); + } + XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id); + if (exists_jobInfo == null) { + return new ReturnT(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid")); + } + + // update new code + exists_jobInfo.setGlueSource(glueSource); + exists_jobInfo.setGlueRemark(glueRemark); + exists_jobInfo.setGlueUpdatetime(new Date()); + + exists_jobInfo.setUpdateTime(new Date()); + xxlJobInfoDao.update(exists_jobInfo); + + // log old code + XxlJobLogGlue xxlJobLogGlue = new XxlJobLogGlue(); + xxlJobLogGlue.setJobId(exists_jobInfo.getId()); + xxlJobLogGlue.setGlueType(exists_jobInfo.getGlueType()); + xxlJobLogGlue.setGlueSource(glueSource); + xxlJobLogGlue.setGlueRemark(glueRemark); + + xxlJobLogGlue.setAddTime(new Date()); + xxlJobLogGlue.setUpdateTime(new Date()); + xxlJobLogGlueDao.save(xxlJobLogGlue); + + // remove code backup more than 30 + xxlJobLogGlueDao.removeOld(exists_jobInfo.getId(), 30); + + return ReturnT.SUCCESS; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java new file mode 100644 index 0000000..d07df2b --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java @@ -0,0 +1,208 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobRegistry; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.dao.XxlJobInfoDao; +import com.xxl.job.admin.dao.XxlJobRegistryDao; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.RegistryConfig; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * job group controller + * + * @author xuxueli 2016-10-02 20:52:56 + */ +@Controller +@RequestMapping("/jobgroup") +public class JobGroupController { + + @Resource + public XxlJobInfoDao xxlJobInfoDao; + @Resource + public XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobRegistryDao xxlJobRegistryDao; + + @RequestMapping + public String index(Model model) { + return "jobgroup/jobgroup.index"; + } + + @RequestMapping("/pageList") + @ResponseBody + public Map pageList(HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + String appname, String title) { + + // page query + List list = xxlJobGroupDao.pageList(start, length, appname, title); + int list_count = xxlJobGroupDao.pageListCount(start, length, appname, title); + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + + @RequestMapping("/save") + @ResponseBody + public ReturnT save(XxlJobGroup xxlJobGroup) { + + // valid + if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) { + return new ReturnT(500, (I18nUtil.getString("system_please_input") + "AppName")); + } + if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_appname_length")); + } + if (xxlJobGroup.getAppname().contains(">") || xxlJobGroup.getAppname().contains("<")) { + return new ReturnT(500, "AppName" + I18nUtil.getString("system_unvalid")); + } + if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) { + return new ReturnT(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title"))); + } + if (xxlJobGroup.getTitle().contains(">") || xxlJobGroup.getTitle().contains("<")) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_title") + I18nUtil.getString("system_unvalid")); + } + if (xxlJobGroup.getAddressType() != 0) { + if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_addressType_limit")); + } + if (xxlJobGroup.getAddressList().contains(">") || xxlJobGroup.getAddressList().contains("<")) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_registryList") + I18nUtil.getString("system_unvalid")); + } + + String[] addresss = xxlJobGroup.getAddressList().split(","); + for (String item : addresss) { + if (item == null || item.trim().length() == 0) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_registryList_unvalid")); + } + } + } + + // process + xxlJobGroup.setUpdateTime(new Date()); + + int ret = xxlJobGroupDao.save(xxlJobGroup); + return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL; + } + + @RequestMapping("/update") + @ResponseBody + public ReturnT update(XxlJobGroup xxlJobGroup) { + // valid + if (xxlJobGroup.getAppname() == null || xxlJobGroup.getAppname().trim().length() == 0) { + return new ReturnT(500, (I18nUtil.getString("system_please_input") + "AppName")); + } + if (xxlJobGroup.getAppname().length() < 4 || xxlJobGroup.getAppname().length() > 64) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_appname_length")); + } + if (xxlJobGroup.getTitle() == null || xxlJobGroup.getTitle().trim().length() == 0) { + return new ReturnT(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title"))); + } + if (xxlJobGroup.getAddressType() == 0) { + // 0=自动注册 + List registryList = findRegistryByAppName(xxlJobGroup.getAppname()); + String addressListStr = null; + if (registryList != null && !registryList.isEmpty()) { + Collections.sort(registryList); + addressListStr = ""; + for (String item : registryList) { + addressListStr += item + ","; + } + addressListStr = addressListStr.substring(0, addressListStr.length() - 1); + } + xxlJobGroup.setAddressList(addressListStr); + } else { + // 1=手动录入 + if (xxlJobGroup.getAddressList() == null || xxlJobGroup.getAddressList().trim().length() == 0) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_addressType_limit")); + } + String[] addresss = xxlJobGroup.getAddressList().split(","); + for (String item : addresss) { + if (item == null || item.trim().length() == 0) { + return new ReturnT(500, I18nUtil.getString("jobgroup_field_registryList_unvalid")); + } + } + } + + // process + xxlJobGroup.setUpdateTime(new Date()); + + int ret = xxlJobGroupDao.update(xxlJobGroup); + return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL; + } + + private List findRegistryByAppName(String appnameParam) { + HashMap> appAddressMap = new HashMap>(); + List list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); + if (list != null) { + for (XxlJobRegistry item : list) { + if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { + String appname = item.getRegistryKey(); + List registryList = appAddressMap.get(appname); + if (registryList == null) { + registryList = new ArrayList(); + } + + if (!registryList.contains(item.getRegistryValue())) { + registryList.add(item.getRegistryValue()); + } + appAddressMap.put(appname, registryList); + } + } + } + return appAddressMap.get(appnameParam); + } + + @RequestMapping("/remove") + @ResponseBody + public ReturnT remove(int id) { + + // valid + int count = xxlJobInfoDao.pageListCount(0, 10, id, -1, null, null, null); + if (count > 0) { + return new ReturnT(500, I18nUtil.getString("jobgroup_del_limit_0")); + } + + List allList = xxlJobGroupDao.findAll(); + if (allList.size() == 1) { + return new ReturnT(500, I18nUtil.getString("jobgroup_del_limit_1")); + } + + int ret = xxlJobGroupDao.remove(id); + return (ret > 0) ? ReturnT.SUCCESS : ReturnT.FAIL; + } + + @RequestMapping("/loadById") + @ResponseBody + public ReturnT loadById(int id) { + XxlJobGroup jobGroup = xxlJobGroupDao.load(id); + return jobGroup != null ? new ReturnT(jobGroup) : new ReturnT(ReturnT.FAIL_CODE, null); + } + + @RequestMapping("/getGroupId") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT getGroupId(@RequestParam("appname") String appname) { + XxlJobGroup group = xxlJobGroupDao.findByName(appname); + return new ReturnT<>("0", group); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java new file mode 100644 index 0000000..93ac19e --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java @@ -0,0 +1,221 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.core.exception.XxlJobException; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobUser; +import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; +import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; +import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum; +import com.xxl.job.admin.core.thread.JobScheduleHelper; +import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.service.LoginService; +import com.xxl.job.admin.service.XxlJobService; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.glue.GlueTypeEnum; +import com.xxl.job.core.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +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.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * index controller + * + * @author xuxueli 2015-12-19 16:13:16 + */ +@Controller +@RequestMapping("/jobinfo") +public class JobInfoController { + private static Logger logger = LoggerFactory.getLogger(JobInfoController.class); + + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobService xxlJobService; + + @RequestMapping + public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { + + // 枚举-字典 + model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 + model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 + model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 + model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型 + model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略 + + // 执行器列表 + List jobGroupList_all = xxlJobGroupDao.findAll(); + + // filter group + List jobGroupList = filterJobGroupByRole(request, jobGroupList_all); + if (jobGroupList == null || jobGroupList.size() == 0) { + throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); + } + + model.addAttribute("JobGroupList", jobGroupList); + model.addAttribute("jobGroup", jobGroup); + + return "jobinfo/jobinfo.index"; + } + + public static List filterJobGroupByRole(HttpServletRequest request, List jobGroupList_all) { + List jobGroupList = new ArrayList<>(); + if (jobGroupList_all != null && jobGroupList_all.size() > 0) { + XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); + if (loginUser.getRole() == 1) { + jobGroupList = jobGroupList_all; + } else { + List groupIdStrs = new ArrayList<>(); + if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) { + groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(",")); + } + for (XxlJobGroup groupItem : jobGroupList_all) { + if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) { + jobGroupList.add(groupItem); + } + } + } + } + return jobGroupList; + } + + public static void validPermission(HttpServletRequest request, int jobGroup) { + XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); + if (!loginUser.validPermission(jobGroup)) { + throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username=" + loginUser.getUsername() + "]"); + } + } + + @RequestMapping("/pageList") + @ResponseBody + public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { + + return xxlJobService.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + } + + @RequestMapping("/add") + @ResponseBody + public ReturnT add(XxlJobInfo jobInfo) { + return xxlJobService.add(jobInfo); + } + + @RequestMapping("/update") + @ResponseBody + public ReturnT update(XxlJobInfo jobInfo) { + return xxlJobService.update(jobInfo); + } + + @RequestMapping("/remove") + @ResponseBody + public ReturnT remove(int id) { + return xxlJobService.remove(id); + } + + @RequestMapping("/stop") + @ResponseBody + public ReturnT pause(int id) { + return xxlJobService.stop(id); + } + + @RequestMapping("/start") + @ResponseBody + public ReturnT start(int id) { + return xxlJobService.start(id); + } + + @RequestMapping("/trigger") + @ResponseBody + //@PermissionLimit(limit = false) + public ReturnT triggerJob(int id, String executorParam, String addressList) { + // force cover job param + if (executorParam == null) { + executorParam = ""; + } + + JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList); + return ReturnT.SUCCESS; + } + + @RequestMapping("/nextTriggerTime") + @ResponseBody + public ReturnT> nextTriggerTime(String scheduleType, String scheduleConf) { + + XxlJobInfo paramXxlJobInfo = new XxlJobInfo(); + paramXxlJobInfo.setScheduleType(scheduleType); + paramXxlJobInfo.setScheduleConf(scheduleConf); + + List result = new ArrayList<>(); + try { + Date lastTime = new Date(); + for (int i = 0; i < 5; i++) { + lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime); + if (lastTime != null) { + result.add(DateUtil.formatDateTime(lastTime)); + } else { + break; + } + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + return new ReturnT>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")) + e.getMessage()); + } + return new ReturnT>(result); + + } + + /*------------------自定义方法---------------------- */ + @RequestMapping("/addJob") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT addJobInfo(@RequestBody XxlJobInfo jobInfo) { + return xxlJobService.add(jobInfo); + } + + @RequestMapping("/removeJob") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT removeJob(@RequestParam("objectId") String objectId) { + return xxlJobService.deleteByObjectId(objectId); + } + + @RequestMapping("/pauseJob") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT pauseJob(@RequestBody XxlJobInfo jobInfo) { + return xxlJobService.stop(jobInfo.getId()); + } + + @RequestMapping("/startJob") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT startJob(@RequestBody XxlJobInfo jobInfo) { + return xxlJobService.start(jobInfo.getId()); + } + + @RequestMapping("/addAndStart") + @ResponseBody + @PermissionLimit(limit = false) + public ReturnT addAndStart(@RequestBody XxlJobInfo jobInfo) { + ReturnT result = xxlJobService.add(jobInfo); + int id = Integer.valueOf(result.getContent()); + xxlJobService.start(id); + return result; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java new file mode 100644 index 0000000..c64049d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java @@ -0,0 +1,233 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.core.exception.XxlJobException; +import com.xxl.job.admin.core.complete.XxlJobCompleter; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.scheduler.XxlJobScheduler; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.dao.XxlJobInfoDao; +import com.xxl.job.admin.dao.XxlJobLogDao; +import com.xxl.job.core.biz.ExecutorBiz; +import com.xxl.job.core.biz.model.KillParam; +import com.xxl.job.core.biz.model.LogParam; +import com.xxl.job.core.biz.model.LogResult; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * index controller + * @author xuxueli 2015-12-19 16:13:16 + */ +@Controller +@RequestMapping("/joblog") +public class JobLogController { + private static Logger logger = LoggerFactory.getLogger(JobLogController.class); + + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + public XxlJobInfoDao xxlJobInfoDao; + @Resource + public XxlJobLogDao xxlJobLogDao; + + @RequestMapping + public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "0") Integer jobId) { + + // 执行器列表 + List jobGroupList_all = xxlJobGroupDao.findAll(); + + // filter group + List jobGroupList = JobInfoController.filterJobGroupByRole(request, jobGroupList_all); + if (jobGroupList==null || jobGroupList.size()==0) { + throw new XxlJobException(I18nUtil.getString("jobgroup_empty")); + } + + model.addAttribute("JobGroupList", jobGroupList); + + // 任务 + if (jobId > 0) { + XxlJobInfo jobInfo = xxlJobInfoDao.loadById(jobId); + if (jobInfo == null) { + throw new RuntimeException(I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_unvalid")); + } + + model.addAttribute("jobInfo", jobInfo); + + // valid permission + JobInfoController.validPermission(request, jobInfo.getJobGroup()); + } + + return "joblog/joblog.index"; + } + + @RequestMapping("/getJobsByGroup") + @ResponseBody + public ReturnT> getJobsByGroup(int jobGroup){ + List list = xxlJobInfoDao.getJobsByGroup(jobGroup); + return new ReturnT>(list); + } + + @RequestMapping("/pageList") + @ResponseBody + public Map pageList(HttpServletRequest request, + @RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + int jobGroup, int jobId, int logStatus, String filterTime) { + + // valid permission + JobInfoController.validPermission(request, jobGroup); // 仅管理员支持查询全部;普通用户仅支持查询有权限的 jobGroup + + // parse param + Date triggerTimeStart = null; + Date triggerTimeEnd = null; + if (filterTime!=null && filterTime.trim().length()>0) { + String[] temp = filterTime.split(" - "); + if (temp.length == 2) { + triggerTimeStart = DateUtil.parseDateTime(temp[0]); + triggerTimeEnd = DateUtil.parseDateTime(temp[1]); + } + } + + // page query + List list = xxlJobLogDao.pageList(start, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd, logStatus); + int list_count = xxlJobLogDao.pageListCount(start, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd, logStatus); + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + + @RequestMapping("/logDetailPage") + public String logDetailPage(int id, Model model){ + + // base check + ReturnT logStatue = ReturnT.SUCCESS; + XxlJobLog jobLog = xxlJobLogDao.load(id); + if (jobLog == null) { + throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid")); + } + + model.addAttribute("triggerCode", jobLog.getTriggerCode()); + model.addAttribute("handleCode", jobLog.getHandleCode()); + model.addAttribute("executorAddress", jobLog.getExecutorAddress()); + model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime()); + model.addAttribute("logId", jobLog.getId()); + return "joblog/joblog.detail"; + } + + @RequestMapping("/logDetailCat") + @ResponseBody + public ReturnT logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum){ + try { + ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress); + ReturnT logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum)); + + // is end + if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) { + XxlJobLog jobLog = xxlJobLogDao.load(logId); + if (jobLog.getHandleCode() > 0) { + logResult.getContent().setEnd(true); + } + } + + return logResult; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return new ReturnT(ReturnT.FAIL_CODE, e.getMessage()); + } + } + + @RequestMapping("/logKill") + @ResponseBody + public ReturnT logKill(int id){ + // base check + XxlJobLog log = xxlJobLogDao.load(id); + XxlJobInfo jobInfo = xxlJobInfoDao.loadById(log.getJobId()); + if (jobInfo==null) { + return new ReturnT(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid")); + } + if (ReturnT.SUCCESS_CODE != log.getTriggerCode()) { + return new ReturnT(500, I18nUtil.getString("joblog_kill_log_limit")); + } + + // request of kill + ReturnT runResult = null; + try { + ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(log.getExecutorAddress()); + runResult = executorBiz.kill(new KillParam(jobInfo.getId())); + } catch (Exception e) { + logger.error(e.getMessage(), e); + runResult = new ReturnT(500, e.getMessage()); + } + + if (ReturnT.SUCCESS_CODE == runResult.getCode()) { + log.setHandleCode(ReturnT.FAIL_CODE); + log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():"")); + log.setHandleTime(new Date()); + XxlJobCompleter.updateHandleInfoAndFinish(log); + return new ReturnT(runResult.getMsg()); + } else { + return new ReturnT(500, runResult.getMsg()); + } + } + + @RequestMapping("/clearLog") + @ResponseBody + public ReturnT clearLog(int jobGroup, int jobId, int type){ + + Date clearBeforeTime = null; + int clearBeforeNum = 0; + if (type == 1) { + clearBeforeTime = DateUtil.addMonths(new Date(), -1); // 清理一个月之前日志数据 + } else if (type == 2) { + clearBeforeTime = DateUtil.addMonths(new Date(), -3); // 清理三个月之前日志数据 + } else if (type == 3) { + clearBeforeTime = DateUtil.addMonths(new Date(), -6); // 清理六个月之前日志数据 + } else if (type == 4) { + clearBeforeTime = DateUtil.addYears(new Date(), -1); // 清理一年之前日志数据 + } else if (type == 5) { + clearBeforeNum = 1000; // 清理一千条以前日志数据 + } else if (type == 6) { + clearBeforeNum = 10000; // 清理一万条以前日志数据 + } else if (type == 7) { + clearBeforeNum = 30000; // 清理三万条以前日志数据 + } else if (type == 8) { + clearBeforeNum = 100000; // 清理十万条以前日志数据 + } else if (type == 9) { + clearBeforeNum = 0; // 清理所有日志数据 + } else { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_clean_type_unvalid")); + } + + List logIds = null; + do { + logIds = xxlJobLogDao.findClearLogIds(jobGroup, jobId, clearBeforeTime, clearBeforeNum, 1000); + if (logIds!=null && logIds.size()>0) { + xxlJobLogDao.clearLog(logIds); + } + } while (logIds!=null && logIds.size()>0); + + return ReturnT.SUCCESS; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java new file mode 100644 index 0000000..3f4c755 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java @@ -0,0 +1,179 @@ +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobUser; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.dao.XxlJobUserDao; +import com.xxl.job.admin.service.LoginService; +import com.xxl.job.core.biz.model.ReturnT; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author xuxueli 2019-05-04 16:39:50 + */ +@Controller +@RequestMapping("/user") +public class UserController { + + @Resource + private XxlJobUserDao xxlJobUserDao; + @Resource + private XxlJobGroupDao xxlJobGroupDao; + + @RequestMapping + @PermissionLimit(adminuser = true) + public String index(Model model) { + + // 执行器列表 + List groupList = xxlJobGroupDao.findAll(); + model.addAttribute("groupList", groupList); + + return "user/user.index"; + } + + @RequestMapping("/pageList") + @ResponseBody + @PermissionLimit(adminuser = true) + public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + String username, int role) { + + // page list + List list = xxlJobUserDao.pageList(start, length, username, role); + int list_count = xxlJobUserDao.pageListCount(start, length, username, role); + + // filter + if (list!=null && list.size()>0) { + for (XxlJobUser item: list) { + item.setPassword(null); + } + } + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + + @RequestMapping("/add") + @ResponseBody + @PermissionLimit(adminuser = true) + public ReturnT add(XxlJobUser xxlJobUser) { + + // valid username + if (!StringUtils.hasText(xxlJobUser.getUsername())) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input")+I18nUtil.getString("user_username") ); + } + xxlJobUser.setUsername(xxlJobUser.getUsername().trim()); + if (!(xxlJobUser.getUsername().length()>=4 && xxlJobUser.getUsername().length()<=20)) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); + } + // valid password + if (!StringUtils.hasText(xxlJobUser.getPassword())) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_please_input")+I18nUtil.getString("user_password") ); + } + xxlJobUser.setPassword(xxlJobUser.getPassword().trim()); + if (!(xxlJobUser.getPassword().length()>=4 && xxlJobUser.getPassword().length()<=20)) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); + } + // md5 password + xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes())); + + // check repeat + XxlJobUser existUser = xxlJobUserDao.loadByUserName(xxlJobUser.getUsername()); + if (existUser != null) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("user_username_repeat") ); + } + + // write + xxlJobUserDao.save(xxlJobUser); + return ReturnT.SUCCESS; + } + + @RequestMapping("/update") + @ResponseBody + @PermissionLimit(adminuser = true) + public ReturnT update(HttpServletRequest request, XxlJobUser xxlJobUser) { + + // avoid opt login seft + XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); + if (loginUser.getUsername().equals(xxlJobUser.getUsername())) { + return new ReturnT(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit")); + } + + // valid password + if (StringUtils.hasText(xxlJobUser.getPassword())) { + xxlJobUser.setPassword(xxlJobUser.getPassword().trim()); + if (!(xxlJobUser.getPassword().length()>=4 && xxlJobUser.getPassword().length()<=20)) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); + } + // md5 password + xxlJobUser.setPassword(DigestUtils.md5DigestAsHex(xxlJobUser.getPassword().getBytes())); + } else { + xxlJobUser.setPassword(null); + } + + // write + xxlJobUserDao.update(xxlJobUser); + return ReturnT.SUCCESS; + } + + @RequestMapping("/remove") + @ResponseBody + @PermissionLimit(adminuser = true) + public ReturnT remove(HttpServletRequest request, int id) { + + // avoid opt login seft + XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); + if (loginUser.getId() == id) { + return new ReturnT(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit")); + } + + xxlJobUserDao.delete(id); + return ReturnT.SUCCESS; + } + + @RequestMapping("/updatePwd") + @ResponseBody + public ReturnT updatePwd(HttpServletRequest request, String password){ + + // valid password + if (password==null || password.trim().length()==0){ + return new ReturnT(ReturnT.FAIL.getCode(), "密码不可为空"); + } + password = password.trim(); + if (!(password.length()>=4 && password.length()<=20)) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" ); + } + + // md5 password + String md5Password = DigestUtils.md5DigestAsHex(password.getBytes()); + + // update pwd + XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); + + // do write + XxlJobUser existUser = xxlJobUserDao.loadByUserName(loginUser.getUsername()); + existUser.setPassword(md5Password); + xxlJobUserDao.update(existUser); + + return ReturnT.SUCCESS; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/annotation/PermissionLimit.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/annotation/PermissionLimit.java new file mode 100644 index 0000000..379efd4 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/annotation/PermissionLimit.java @@ -0,0 +1,29 @@ +package com.xxl.job.admin.controller.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 权限限制 + * @author xuxueli 2015-12-12 18:29:02 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface PermissionLimit { + + /** + * 登录拦截 (默认拦截) + */ + boolean limit() default true; + + /** + * 要求管理员权限 + * + * @return + */ + boolean adminuser() default false; + +} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java new file mode 100644 index 0000000..57c1c08 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java @@ -0,0 +1,43 @@ +package com.xxl.job.admin.controller.interceptor; + +import com.xxl.job.admin.core.util.FtlUtil; +import com.xxl.job.admin.core.util.I18nUtil; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; + +/** + * push cookies to model as cookieMap + * + * @author xuxueli 2015-12-12 18:09:04 + */ +@Component +public class CookieInterceptor extends HandlerInterceptorAdapter { + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + + // cookie + if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) { + HashMap cookieMap = new HashMap(); + for (Cookie ck : request.getCookies()) { + cookieMap.put(ck.getName(), ck); + } + modelAndView.addObject("cookieMap", cookieMap); + } + + // static method + if (modelAndView != null) { + modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); + } + + super.postHandle(request, response, handler, modelAndView); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java new file mode 100644 index 0000000..5202c29 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java @@ -0,0 +1,59 @@ +package com.xxl.job.admin.controller.interceptor; + +import com.xxl.job.admin.controller.annotation.PermissionLimit; +import com.xxl.job.admin.core.model.XxlJobUser; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.service.LoginService; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 权限拦截 + * + * @author xuxueli 2015-12-12 18:09:04 + */ +@Component +public class PermissionInterceptor extends HandlerInterceptorAdapter { + + @Resource + private LoginService loginService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + if (!(handler instanceof HandlerMethod)) { + return super.preHandle(request, response, handler); + } + + // if need login + boolean needLogin = true; + boolean needAdminuser = false; + HandlerMethod method = (HandlerMethod)handler; + PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class); + if (permission!=null) { + needLogin = permission.limit(); + needAdminuser = permission.adminuser(); + } + + if (needLogin) { + XxlJobUser loginUser = loginService.ifLogin(request, response); + if (loginUser == null) { + response.setStatus(302); + response.setHeader("location", request.getContextPath()+"/toLogin"); + return false; + } + if (needAdminuser && loginUser.getRole()!=1) { + throw new RuntimeException(I18nUtil.getString("system_permission_limit")); + } + request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); + } + + return super.preHandle(request, response, handler); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/WebMvcConfig.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/WebMvcConfig.java new file mode 100644 index 0000000..0be6ba6 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/WebMvcConfig.java @@ -0,0 +1,28 @@ +package com.xxl.job.admin.controller.interceptor; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; + +/** + * web mvc config + * + * @author xuxueli 2018-04-02 20:48:20 + */ +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Resource + private PermissionInterceptor permissionInterceptor; + @Resource + private CookieInterceptor cookieInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(permissionInterceptor).addPathPatterns("/**"); + registry.addInterceptor(cookieInterceptor).addPathPatterns("/**"); + } + +} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java new file mode 100644 index 0000000..114407b --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java @@ -0,0 +1,66 @@ +package com.xxl.job.admin.controller.resolver; + +import com.xxl.job.admin.core.exception.XxlJobException; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.admin.core.util.JacksonUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * common exception resolver + * + * @author xuxueli 2016-1-6 19:22:18 + */ +@Component +public class WebExceptionResolver implements HandlerExceptionResolver { + private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class); + + @Override + public ModelAndView resolveException(HttpServletRequest request, + HttpServletResponse response, Object handler, Exception ex) { + + if (!(ex instanceof XxlJobException)) { + logger.error("WebExceptionResolver:{}", ex); + } + + // if json + boolean isJson = false; + if (handler instanceof HandlerMethod) { + HandlerMethod method = (HandlerMethod)handler; + ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); + if (responseBody != null) { + isJson = true; + } + } + + // error result + ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
")); + + // response + ModelAndView mv = new ModelAndView(); + if (isJson) { + try { + response.setContentType("application/json;charset=utf-8"); + response.getWriter().print(JacksonUtil.writeValueAsString(errorResult)); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return mv; + } else { + + mv.addObject("exceptionMsg", errorResult.getMsg()); + mv.setViewName("/common/common.exception"); + return mv; + } + } + +} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarm.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarm.java new file mode 100644 index 0000000..4165ff3 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarm.java @@ -0,0 +1,20 @@ +package com.xxl.job.admin.core.alarm; + +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; + +/** + * @author xuxueli 2020-01-19 + */ +public interface JobAlarm { + + /** + * job alarm + * + * @param info + * @param jobLog + * @return + */ + public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java new file mode 100644 index 0000000..797dc90 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/JobAlarmer.java @@ -0,0 +1,65 @@ +package com.xxl.job.admin.core.alarm; + +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Component +public class JobAlarmer implements ApplicationContextAware, InitializingBean { + private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class); + + private ApplicationContext applicationContext; + private List jobAlarmList; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void afterPropertiesSet() throws Exception { + Map serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class); + if (serviceBeanMap != null && serviceBeanMap.size() > 0) { + jobAlarmList = new ArrayList(serviceBeanMap.values()); + } + } + + /** + * job alarm + * + * @param info + * @param jobLog + * @return + */ + public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) { + + boolean result = false; + if (jobAlarmList!=null && jobAlarmList.size()>0) { + result = true; // success means all-success + for (JobAlarm alarm: jobAlarmList) { + boolean resultItem = false; + try { + resultItem = alarm.doAlarm(info, jobLog); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + if (!resultItem) { + result = false; + } + } + } + + return result; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java new file mode 100644 index 0000000..e7290d7 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/EmailJobAlarm.java @@ -0,0 +1,117 @@ +package com.xxl.job.admin.core.alarm.impl; + +import com.xxl.job.admin.core.alarm.JobAlarm; +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.model.ReturnT; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; + +import javax.mail.internet.MimeMessage; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * job alarm by email + * + * @author xuxueli 2020-01-19 + */ +@Component +public class EmailJobAlarm implements JobAlarm { + private static Logger logger = LoggerFactory.getLogger(EmailJobAlarm.class); + + /** + * fail alarm + * + * @param jobLog + */ + public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog){ + boolean alarmResult = true; + + // send monitor email + if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) { + + // alarmContent + String alarmContent = "Alarm Job LogId=" + jobLog.getId(); + if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) { + alarmContent += "
TriggerMsg=
" + jobLog.getTriggerMsg(); + } + if (jobLog.getHandleCode()>0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) { + alarmContent += "
HandleCode=" + jobLog.getHandleMsg(); + } + + // email info + XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(Integer.valueOf(info.getJobGroup())); + String personal = I18nUtil.getString("admin_name_full"); + String title = I18nUtil.getString("jobconf_monitor"); + String content = MessageFormat.format(loadEmailJobAlarmTemplate(), + group!=null?group.getTitle():"null", + info.getId(), + info.getJobDesc(), + alarmContent); + + Set emailSet = new HashSet(Arrays.asList(info.getAlarmEmail().split(","))); + for (String email: emailSet) { + + // make mail + try { + MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage(); + + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); + helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailFrom(), personal); + helper.setTo(email); + helper.setSubject(title); + helper.setText(content, true); + + XxlJobAdminConfig.getAdminConfig().getMailSender().send(mimeMessage); + } catch (Exception e) { + logger.error(">>>>>>>>>>> xxl-job, job fail alarm email send error, JobLogId:{}", jobLog.getId(), e); + + alarmResult = false; + } + + } + } + + return alarmResult; + } + + /** + * load email job alarm template + * + * @return + */ + private static final String loadEmailJobAlarmTemplate(){ + String mailBodyTemplate = "
" + I18nUtil.getString("jobconf_monitor_detail") + ":" + + "\n" + + " " + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
"+ I18nUtil.getString("jobinfo_field_jobgroup") +""+ I18nUtil.getString("jobinfo_field_id") +""+ I18nUtil.getString("jobinfo_field_jobdesc") +""+ I18nUtil.getString("jobconf_monitor_alarm_title") +""+ I18nUtil.getString("jobconf_monitor_alarm_content") +"
{0}{1}{2}"+ I18nUtil.getString("jobconf_monitor_alarm_type") +"{3}
"; + + return mailBodyTemplate; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java new file mode 100644 index 0000000..b9ac59a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/complete/XxlJobCompleter.java @@ -0,0 +1,99 @@ +package com.xxl.job.admin.core.complete; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.context.XxlJobContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.MessageFormat; + +/** + * @author xuxueli 2020-10-30 20:43:10 + */ +public class XxlJobCompleter { + private static Logger logger = LoggerFactory.getLogger(XxlJobCompleter.class); + + /** + * common fresh handle entrance (limit only once) + * + * @param xxlJobLog + * @return + */ + public static int updateHandleInfoAndFinish(XxlJobLog xxlJobLog) { + + // finish + finishJob(xxlJobLog); + + // text最大64kb 避免长度过长 + if (xxlJobLog.getHandleMsg().length() > 15000) { + xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg().substring(0, 15000) ); + } + + // fresh handle + return XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(xxlJobLog); + } + + + /** + * do somethind to finish job + */ + private static void finishJob(XxlJobLog xxlJobLog){ + + // 1、handle success, to trigger child job + String triggerChildMsg = null; + if (XxlJobContext.HANDLE_COCE_SUCCESS == xxlJobLog.getHandleCode()) { + XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId()); + if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) { + triggerChildMsg = "

>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<<
"; + + String[] childJobIds = xxlJobInfo.getChildJobId().split(","); + for (int i = 0; i < childJobIds.length; i++) { + int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1; + if (childJobId > 0) { + + JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null); + ReturnT triggerChildResult = ReturnT.SUCCESS; + + // add msg + triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"), + (i+1), + childJobIds.length, + childJobIds[i], + (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")), + triggerChildResult.getMsg()); + } else { + triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"), + (i+1), + childJobIds.length, + childJobIds[i]); + } + } + + } + } + + if (triggerChildMsg != null) { + xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg() + triggerChildMsg ); + } + + // 2、fix_delay trigger next + // on the way + + } + + private static boolean isNumeric(String str){ + try { + int result = Integer.valueOf(str); + return true; + } catch (NumberFormatException e) { + return false; + } + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java new file mode 100644 index 0000000..380b8a5 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java @@ -0,0 +1,158 @@ +package com.xxl.job.admin.core.conf; + +import com.xxl.job.admin.core.alarm.JobAlarmer; +import com.xxl.job.admin.core.scheduler.XxlJobScheduler; +import com.xxl.job.admin.dao.*; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.util.Arrays; + +/** + * xxl-job config + * + * @author xuxueli 2017-04-28 + */ + +@Component +public class XxlJobAdminConfig implements InitializingBean, DisposableBean { + + private static XxlJobAdminConfig adminConfig = null; + public static XxlJobAdminConfig getAdminConfig() { + return adminConfig; + } + + + // ---------------------- XxlJobScheduler ---------------------- + + private XxlJobScheduler xxlJobScheduler; + + @Override + public void afterPropertiesSet() throws Exception { + adminConfig = this; + + xxlJobScheduler = new XxlJobScheduler(); + xxlJobScheduler.init(); + } + + @Override + public void destroy() throws Exception { + xxlJobScheduler.destroy(); + } + + + // ---------------------- XxlJobScheduler ---------------------- + + // conf + @Value("${xxl.job.i18n}") + private String i18n; + + @Value("${xxl.job.accessToken}") + private String accessToken; + + @Value("${spring.mail.from}") + private String emailFrom; + + @Value("${xxl.job.triggerpool.fast.max}") + private int triggerPoolFastMax; + + @Value("${xxl.job.triggerpool.slow.max}") + private int triggerPoolSlowMax; + + @Value("${xxl.job.logretentiondays}") + private int logretentiondays; + + // dao, service + + @Resource + private XxlJobLogDao xxlJobLogDao; + @Resource + private XxlJobInfoDao xxlJobInfoDao; + @Resource + private XxlJobRegistryDao xxlJobRegistryDao; + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobLogReportDao xxlJobLogReportDao; + @Resource + private JavaMailSender mailSender; + @Resource + private DataSource dataSource; + @Resource + private JobAlarmer jobAlarmer; + + + public String getI18n() { + if (!Arrays.asList("zh_CN", "zh_TC", "en").contains(i18n)) { + return "zh_CN"; + } + return i18n; + } + + public String getAccessToken() { + return accessToken; + } + + public String getEmailFrom() { + return emailFrom; + } + + public int getTriggerPoolFastMax() { + if (triggerPoolFastMax < 200) { + return 200; + } + return triggerPoolFastMax; + } + + public int getTriggerPoolSlowMax() { + if (triggerPoolSlowMax < 100) { + return 100; + } + return triggerPoolSlowMax; + } + + public int getLogretentiondays() { + if (logretentiondays < 7) { + return -1; // Limit greater than or equal to 7, otherwise close + } + return logretentiondays; + } + + public XxlJobLogDao getXxlJobLogDao() { + return xxlJobLogDao; + } + + public XxlJobInfoDao getXxlJobInfoDao() { + return xxlJobInfoDao; + } + + public XxlJobRegistryDao getXxlJobRegistryDao() { + return xxlJobRegistryDao; + } + + public XxlJobGroupDao getXxlJobGroupDao() { + return xxlJobGroupDao; + } + + public XxlJobLogReportDao getXxlJobLogReportDao() { + return xxlJobLogReportDao; + } + + public JavaMailSender getMailSender() { + return mailSender; + } + + public DataSource getDataSource() { + return dataSource; + } + + public JobAlarmer getJobAlarmer() { + return jobAlarmer; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java new file mode 100644 index 0000000..fce2352 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/cron/CronExpression.java @@ -0,0 +1,1666 @@ +/* + * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved. + * + * 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. + * + */ + +package com.xxl.job.admin.core.cron; + +import java.io.Serializable; +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TimeZone; +import java.util.TreeSet; + +/** + * Provides a parser and evaluator for unix-like cron expressions. Cron + * expressions provide the ability to specify complex time combinations such as + * "At 8:00am every Monday through Friday" or "At 1:30am every + * last Friday of the month". + *

+ * Cron expressions are comprised of 6 required fields and one optional field + * separated by white space. The fields respectively are described as follows: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Field Name Allowed Values Allowed Special Characters
Seconds  + * 0-59  + * , - * /
Minutes  + * 0-59  + * , - * /
Hours  + * 0-23  + * , - * /
Day-of-month  + * 1-31  + * , - * ? / L W
Month  + * 0-11 or JAN-DEC  + * , - * /
Day-of-Week  + * 1-7 or SUN-SAT  + * , - * ? / L #
Year (Optional)  + * empty, 1970-2199  + * , - * /
+ *

+ * The '*' character is used to specify all values. For example, "*" + * in the minute field means "every minute". + *

+ * The '?' character is allowed for the day-of-month and day-of-week fields. It + * is used to specify 'no specific value'. This is useful when you need to + * specify something in one of the two fields, but not the other. + *

+ * The '-' character is used to specify ranges For example "10-12" in + * the hour field means "the hours 10, 11 and 12". + *

+ * The ',' character is used to specify additional values. For example + * "MON,WED,FRI" in the day-of-week field means "the days Monday, + * Wednesday, and Friday". + *

+ * The '/' character is used to specify increments. For example "0/15" + * in the seconds field means "the seconds 0, 15, 30, and 45". And + * "5/15" in the seconds field means "the seconds 5, 20, 35, and + * 50". Specifying '*' before the '/' is equivalent to specifying 0 is + * the value to start with. Essentially, for each field in the expression, there + * is a set of numbers that can be turned on or off. For seconds and minutes, + * the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to + * 31, and for months 0 to 11 (JAN to DEC). The "/" character simply helps you turn + * on every "nth" value in the given set. Thus "7/6" in the + * month field only turns on month "7", it does NOT mean every 6th + * month, please note that subtlety. + *

+ * The 'L' character is allowed for the day-of-month and day-of-week fields. + * This character is short-hand for "last", but it has different + * meaning in each of the two fields. For example, the value "L" in + * the day-of-month field means "the last day of the month" - day 31 + * for January, day 28 for February on non-leap years. If used in the + * day-of-week field by itself, it simply means "7" or + * "SAT". But if used in the day-of-week field after another value, it + * means "the last xxx day of the month" - for example "6L" + * means "the last friday of the month". You can also specify an offset + * from the last day of the month, such as "L-3" which would mean the third-to-last + * day of the calendar month. When using the 'L' option, it is important not to + * specify lists, or ranges of values, as you'll get confusing/unexpected results. + *

+ * The 'W' character is allowed for the day-of-month field. This character + * is used to specify the weekday (Monday-Friday) nearest the given day. As an + * example, if you were to specify "15W" as the value for the + * day-of-month field, the meaning is: "the nearest weekday to the 15th of + * the month". So if the 15th is a Saturday, the trigger will fire on + * Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the + * 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. + * However if you specify "1W" as the value for day-of-month, and the + * 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not + * 'jump' over the boundary of a month's days. The 'W' character can only be + * specified when the day-of-month is a single day, not a range or list of days. + *

+ * The 'L' and 'W' characters can also be combined for the day-of-month + * expression to yield 'LW', which translates to "last weekday of the + * month". + *

+ * The '#' character is allowed for the day-of-week field. This character is + * used to specify "the nth" XXX day of the month. For example, the + * value of "6#3" in the day-of-week field means the third Friday of + * the month (day 6 = Friday and "#3" = the 3rd one in the month). + * Other examples: "2#1" = the first Monday of the month and + * "4#5" = the fifth Wednesday of the month. Note that if you specify + * "#5" and there is not 5 of the given day-of-week in the month, then + * no firing will occur that month. If the '#' character is used, there can + * only be one expression in the day-of-week field ("3#1,6#3" is + * not valid, since there are two expressions). + *

+ * + *

+ * The legal characters and the names of months and days of the week are not + * case sensitive. + * + *

+ * NOTES: + *

    + *
  • Support for specifying both a day-of-week and a day-of-month value is + * not complete (you'll need to use the '?' character in one of these fields). + *
  • + *
  • Overflowing ranges is supported - that is, having a larger number on + * the left hand side than the right. You might do 22-2 to catch 10 o'clock + * at night until 2 o'clock in the morning, or you might have NOV-FEB. It is + * very important to note that overuse of overflowing ranges creates ranges + * that don't make sense and no effort has been made to determine which + * interpretation CronExpression chooses. An example would be + * "0 0 14-6 ? * FRI-MON".
  • + *
+ *

+ * + * + * @author Sharada Jambula, James House + * @author Contributions from Mads Henderson + * @author Refactoring from CronTrigger to CronExpression by Aaron Craven + * + * Borrowed from quartz v2.3.1 + * + */ +public final class CronExpression implements Serializable, Cloneable { + + private static final long serialVersionUID = 12423409423L; + + protected static final int SECOND = 0; + protected static final int MINUTE = 1; + protected static final int HOUR = 2; + protected static final int DAY_OF_MONTH = 3; + protected static final int MONTH = 4; + protected static final int DAY_OF_WEEK = 5; + protected static final int YEAR = 6; + protected static final int ALL_SPEC_INT = 99; // '*' + protected static final int NO_SPEC_INT = 98; // '?' + protected static final Integer ALL_SPEC = ALL_SPEC_INT; + protected static final Integer NO_SPEC = NO_SPEC_INT; + + protected static final Map monthMap = new HashMap(20); + protected static final Map dayMap = new HashMap(60); + static { + monthMap.put("JAN", 0); + monthMap.put("FEB", 1); + monthMap.put("MAR", 2); + monthMap.put("APR", 3); + monthMap.put("MAY", 4); + monthMap.put("JUN", 5); + monthMap.put("JUL", 6); + monthMap.put("AUG", 7); + monthMap.put("SEP", 8); + monthMap.put("OCT", 9); + monthMap.put("NOV", 10); + monthMap.put("DEC", 11); + + dayMap.put("SUN", 1); + dayMap.put("MON", 2); + dayMap.put("TUE", 3); + dayMap.put("WED", 4); + dayMap.put("THU", 5); + dayMap.put("FRI", 6); + dayMap.put("SAT", 7); + } + + private final String cronExpression; + private TimeZone timeZone = null; + protected transient TreeSet seconds; + protected transient TreeSet minutes; + protected transient TreeSet hours; + protected transient TreeSet daysOfMonth; + protected transient TreeSet months; + protected transient TreeSet daysOfWeek; + protected transient TreeSet years; + + protected transient boolean lastdayOfWeek = false; + protected transient int nthdayOfWeek = 0; + protected transient boolean lastdayOfMonth = false; + protected transient boolean nearestWeekday = false; + protected transient int lastdayOffset = 0; + protected transient boolean expressionParsed = false; + + public static final int MAX_YEAR = Calendar.getInstance().get(Calendar.YEAR) + 100; + + /** + * Constructs a new CronExpression based on the specified + * parameter. + * + * @param cronExpression String representation of the cron expression the + * new object should represent + * @throws java.text.ParseException + * if the string expression cannot be parsed into a valid + * CronExpression + */ + public CronExpression(String cronExpression) throws ParseException { + if (cronExpression == null) { + throw new IllegalArgumentException("cronExpression cannot be null"); + } + + this.cronExpression = cronExpression.toUpperCase(Locale.US); + + buildExpression(this.cronExpression); + } + + /** + * Constructs a new {@code CronExpression} as a copy of an existing + * instance. + * + * @param expression + * The existing cron expression to be copied + */ + public CronExpression(CronExpression expression) { + /* + * We don't call the other constructor here since we need to swallow the + * ParseException. We also elide some of the sanity checking as it is + * not logically trippable. + */ + this.cronExpression = expression.getCronExpression(); + try { + buildExpression(cronExpression); + } catch (ParseException ex) { + throw new AssertionError(); + } + if (expression.getTimeZone() != null) { + setTimeZone((TimeZone) expression.getTimeZone().clone()); + } + } + + /** + * Indicates whether the given date satisfies the cron expression. Note that + * milliseconds are ignored, so two Dates falling on different milliseconds + * of the same second will always have the same result here. + * + * @param date the date to evaluate + * @return a boolean indicating whether the given date satisfies the cron + * expression + */ + public boolean isSatisfiedBy(Date date) { + Calendar testDateCal = Calendar.getInstance(getTimeZone()); + testDateCal.setTime(date); + testDateCal.set(Calendar.MILLISECOND, 0); + Date originalDate = testDateCal.getTime(); + + testDateCal.add(Calendar.SECOND, -1); + + Date timeAfter = getTimeAfter(testDateCal.getTime()); + + return ((timeAfter != null) && (timeAfter.equals(originalDate))); + } + + /** + * Returns the next date/time after the given date/time which + * satisfies the cron expression. + * + * @param date the date/time at which to begin the search for the next valid + * date/time + * @return the next valid date/time + */ + public Date getNextValidTimeAfter(Date date) { + return getTimeAfter(date); + } + + /** + * Returns the next date/time after the given date/time which does + * not satisfy the expression + * + * @param date the date/time at which to begin the search for the next + * invalid date/time + * @return the next valid date/time + */ + public Date getNextInvalidTimeAfter(Date date) { + long difference = 1000; + + //move back to the nearest second so differences will be accurate + Calendar adjustCal = Calendar.getInstance(getTimeZone()); + adjustCal.setTime(date); + adjustCal.set(Calendar.MILLISECOND, 0); + Date lastDate = adjustCal.getTime(); + + Date newDate; + + //FUTURE_TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very bad here, depending on the cron expression. It is, however A solution. + + //keep getting the next included time until it's farther than one second + // apart. At that point, lastDate is the last valid fire time. We return + // the second immediately following it. + while (difference == 1000) { + newDate = getTimeAfter(lastDate); + if(newDate == null) + break; + + difference = newDate.getTime() - lastDate.getTime(); + + if (difference == 1000) { + lastDate = newDate; + } + } + + return new Date(lastDate.getTime() + 1000); + } + + /** + * Returns the time zone for which this CronExpression + * will be resolved. + */ + public TimeZone getTimeZone() { + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + + return timeZone; + } + + /** + * Sets the time zone for which this CronExpression + * will be resolved. + */ + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } + + /** + * Returns the string representation of the CronExpression + * + * @return a string representation of the CronExpression + */ + @Override + public String toString() { + return cronExpression; + } + + /** + * Indicates whether the specified cron expression can be parsed into a + * valid cron expression + * + * @param cronExpression the expression to evaluate + * @return a boolean indicating whether the given expression is a valid cron + * expression + */ + public static boolean isValidExpression(String cronExpression) { + + try { + new CronExpression(cronExpression); + } catch (ParseException pe) { + return false; + } + + return true; + } + + public static void validateExpression(String cronExpression) throws ParseException { + + new CronExpression(cronExpression); + } + + + //////////////////////////////////////////////////////////////////////////// + // + // Expression Parsing Functions + // + //////////////////////////////////////////////////////////////////////////// + + protected void buildExpression(String expression) throws ParseException { + expressionParsed = true; + + try { + + if (seconds == null) { + seconds = new TreeSet(); + } + if (minutes == null) { + minutes = new TreeSet(); + } + if (hours == null) { + hours = new TreeSet(); + } + if (daysOfMonth == null) { + daysOfMonth = new TreeSet(); + } + if (months == null) { + months = new TreeSet(); + } + if (daysOfWeek == null) { + daysOfWeek = new TreeSet(); + } + if (years == null) { + years = new TreeSet(); + } + + int exprOn = SECOND; + + StringTokenizer exprsTok = new StringTokenizer(expression, " \t", + false); + + while (exprsTok.hasMoreTokens() && exprOn <= YEAR) { + String expr = exprsTok.nextToken().trim(); + + // throw an exception if L is used with other days of the month + if(exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { + throw new ParseException("Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1); + } + // throw an exception if L is used with other days of the week + if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) { + throw new ParseException("Support for specifying 'L' with other days of the week is not implemented", -1); + } + if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) { + throw new ParseException("Support for specifying multiple \"nth\" days is not implemented.", -1); + } + + StringTokenizer vTok = new StringTokenizer(expr, ","); + while (vTok.hasMoreTokens()) { + String v = vTok.nextToken(); + storeExpressionVals(0, v, exprOn); + } + + exprOn++; + } + + if (exprOn <= DAY_OF_WEEK) { + throw new ParseException("Unexpected end of expression.", + expression.length()); + } + + if (exprOn <= YEAR) { + storeExpressionVals(0, "*", YEAR); + } + + TreeSet dow = getSet(DAY_OF_WEEK); + TreeSet dom = getSet(DAY_OF_MONTH); + + // Copying the logic from the UnsupportedOperationException below + boolean dayOfMSpec = !dom.contains(NO_SPEC); + boolean dayOfWSpec = !dow.contains(NO_SPEC); + + if (!dayOfMSpec || dayOfWSpec) { + if (!dayOfWSpec || dayOfMSpec) { + throw new ParseException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0); + } + } + } catch (ParseException pe) { + throw pe; + } catch (Exception e) { + throw new ParseException("Illegal cron expression format (" + + e.toString() + ")", 0); + } + } + + protected int storeExpressionVals(int pos, String s, int type) + throws ParseException { + + int incr = 0; + int i = skipWhiteSpace(pos, s); + if (i >= s.length()) { + return i; + } + char c = s.charAt(i); + if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) { + String sub = s.substring(i, i + 3); + int sval = -1; + int eval = -1; + if (type == MONTH) { + sval = getMonthNumber(sub) + 1; + if (sval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getMonthNumber(sub) + 1; + if (eval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + } + } + } else if (type == DAY_OF_WEEK) { + sval = getDayOfWeekNumber(sub); + if (sval < 0) { + throw new ParseException("Invalid Day-of-Week value: '" + + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getDayOfWeekNumber(sub); + if (eval < 0) { + throw new ParseException( + "Invalid Day-of-Week value: '" + sub + + "'", i); + } + } else if (c == '#') { + try { + i += 4; + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } catch (Exception e) { + throw new ParseException( + "A numeric value between 1 and 5 must follow the '#' option", + i); + } + } else if (c == 'L') { + lastdayOfWeek = true; + i++; + } + } + + } else { + throw new ParseException( + "Illegal characters for this position: '" + sub + "'", + i); + } + if (eval != -1) { + incr = 1; + } + addToSet(sval, eval, incr, type); + return (i + 3); + } + + if (c == '?') { + i++; + if ((i + 1) < s.length() + && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) { + throw new ParseException("Illegal character after '?': " + + s.charAt(i), i); + } + if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) { + throw new ParseException( + "'?' can only be specified for Day-of-Month or Day-of-Week.", + i); + } + if (type == DAY_OF_WEEK && !lastdayOfMonth) { + int val = daysOfMonth.last(); + if (val == NO_SPEC_INT) { + throw new ParseException( + "'?' can only be specified for Day-of-Month -OR- Day-of-Week.", + i); + } + } + + addToSet(NO_SPEC_INT, -1, 0, type); + return i; + } + + if (c == '*' || c == '/') { + if (c == '*' && (i + 1) >= s.length()) { + addToSet(ALL_SPEC_INT, -1, incr, type); + return i + 1; + } else if (c == '/' + && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s + .charAt(i + 1) == '\t')) { + throw new ParseException("'/' must be followed by an integer.", i); + } else if (c == '*') { + i++; + } + c = s.charAt(i); + if (c == '/') { // is an increment specified? + i++; + if (i >= s.length()) { + throw new ParseException("Unexpected end of string.", i); + } + + incr = getNumericValue(s, i); + + i++; + if (incr > 10) { + i++; + } + checkIncrementRange(incr, type, i); + } else { + incr = 1; + } + + addToSet(ALL_SPEC_INT, -1, incr, type); + return i; + } else if (c == 'L') { + i++; + if (type == DAY_OF_MONTH) { + lastdayOfMonth = true; + } + if (type == DAY_OF_WEEK) { + addToSet(7, 7, 0, type); + } + if(type == DAY_OF_MONTH && s.length() > i) { + c = s.charAt(i); + if(c == '-') { + ValueSet vs = getValue(0, s, i+1); + lastdayOffset = vs.value; + if(lastdayOffset > 30) + throw new ParseException("Offset from last day must be <= 30", i+1); + i = vs.pos; + } + if(s.length() > i) { + c = s.charAt(i); + if(c == 'W') { + nearestWeekday = true; + i++; + } + } + } + return i; + } else if (c >= '0' && c <= '9') { + int val = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, -1, -1, type); + } else { + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(val, s, i); + val = vs.value; + i = vs.pos; + } + i = checkNext(i, s, val, type); + return i; + } + } else { + throw new ParseException("Unexpected character: " + c, i); + } + + return i; + } + + private void checkIncrementRange(int incr, int type, int idxPos) throws ParseException { + if (incr > 59 && (type == SECOND || type == MINUTE)) { + throw new ParseException("Increment > 60 : " + incr, idxPos); + } else if (incr > 23 && (type == HOUR)) { + throw new ParseException("Increment > 24 : " + incr, idxPos); + } else if (incr > 31 && (type == DAY_OF_MONTH)) { + throw new ParseException("Increment > 31 : " + incr, idxPos); + } else if (incr > 7 && (type == DAY_OF_WEEK)) { + throw new ParseException("Increment > 7 : " + incr, idxPos); + } else if (incr > 12 && (type == MONTH)) { + throw new ParseException("Increment > 12 : " + incr, idxPos); + } + } + + protected int checkNext(int pos, String s, int val, int type) + throws ParseException { + + int end = -1; + int i = pos; + + if (i >= s.length()) { + addToSet(val, end, -1, type); + return i; + } + + char c = s.charAt(pos); + + if (c == 'L') { + if (type == DAY_OF_WEEK) { + if(val < 1 || val > 7) + throw new ParseException("Day-of-Week values must be between 1 and 7", -1); + lastdayOfWeek = true; + } else { + throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); + } + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == 'W') { + if (type == DAY_OF_MONTH) { + nearestWeekday = true; + } else { + throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); + } + if(val > 31) + throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i); + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == '#') { + if (type != DAY_OF_WEEK) { + throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i); + } + i++; + try { + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } catch (Exception e) { + throw new ParseException( + "A numeric value between 1 and 5 must follow the '#' option", + i); + } + + TreeSet set = getSet(type); + set.add(val); + i++; + return i; + } + + if (c == '-') { + i++; + c = s.charAt(i); + int v = Integer.parseInt(String.valueOf(c)); + end = v; + i++; + if (i >= s.length()) { + addToSet(val, end, 1, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v, s, i); + end = vs.value; + i = vs.pos; + } + if (i < s.length() && ((c = s.charAt(i)) == '/')) { + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } else { + addToSet(val, end, v2, type); + return i; + } + } else { + addToSet(val, end, 1, type); + return i; + } + } + + if (c == '/') { + if ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\t') { + throw new ParseException("'/' must be followed by an integer.", i); + } + + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + checkIncrementRange(v2, type, i); + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + checkIncrementRange(v3, type, i); + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } else { + throw new ParseException("Unexpected character '" + c + "' after '/'", i); + } + } + + addToSet(val, end, 0, type); + i++; + return i; + } + + public String getCronExpression() { + return cronExpression; + } + + public String getExpressionSummary() { + StringBuilder buf = new StringBuilder(); + + buf.append("seconds: "); + buf.append(getExpressionSetSummary(seconds)); + buf.append("\n"); + buf.append("minutes: "); + buf.append(getExpressionSetSummary(minutes)); + buf.append("\n"); + buf.append("hours: "); + buf.append(getExpressionSetSummary(hours)); + buf.append("\n"); + buf.append("daysOfMonth: "); + buf.append(getExpressionSetSummary(daysOfMonth)); + buf.append("\n"); + buf.append("months: "); + buf.append(getExpressionSetSummary(months)); + buf.append("\n"); + buf.append("daysOfWeek: "); + buf.append(getExpressionSetSummary(daysOfWeek)); + buf.append("\n"); + buf.append("lastdayOfWeek: "); + buf.append(lastdayOfWeek); + buf.append("\n"); + buf.append("nearestWeekday: "); + buf.append(nearestWeekday); + buf.append("\n"); + buf.append("NthDayOfWeek: "); + buf.append(nthdayOfWeek); + buf.append("\n"); + buf.append("lastdayOfMonth: "); + buf.append(lastdayOfMonth); + buf.append("\n"); + buf.append("years: "); + buf.append(getExpressionSetSummary(years)); + buf.append("\n"); + + return buf.toString(); + } + + protected String getExpressionSetSummary(java.util.Set set) { + + if (set.contains(NO_SPEC)) { + return "?"; + } + if (set.contains(ALL_SPEC)) { + return "*"; + } + + StringBuilder buf = new StringBuilder(); + + Iterator itr = set.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected String getExpressionSetSummary(java.util.ArrayList list) { + + if (list.contains(NO_SPEC)) { + return "?"; + } + if (list.contains(ALL_SPEC)) { + return "*"; + } + + StringBuilder buf = new StringBuilder(); + + Iterator itr = list.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected int skipWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) { + } + + return i; + } + + protected int findNextWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) { + } + + return i; + } + + protected void addToSet(int val, int end, int incr, int type) + throws ParseException { + + TreeSet set = getSet(type); + + if (type == SECOND || type == MINUTE) { + if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Minute and Second values must be between 0 and 59", + -1); + } + } else if (type == HOUR) { + if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Hour values must be between 0 and 23", -1); + } + } else if (type == DAY_OF_MONTH) { + if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT) + && (val != NO_SPEC_INT)) { + throw new ParseException( + "Day of month values must be between 1 and 31", -1); + } + } else if (type == MONTH) { + if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) { + throw new ParseException( + "Month values must be between 1 and 12", -1); + } + } else if (type == DAY_OF_WEEK) { + if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) + && (val != NO_SPEC_INT)) { + throw new ParseException( + "Day-of-Week values must be between 1 and 7", -1); + } + } + + if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) { + if (val != -1) { + set.add(val); + } else { + set.add(NO_SPEC); + } + + return; + } + + int startAt = val; + int stopAt = end; + + if (val == ALL_SPEC_INT && incr <= 0) { + incr = 1; + set.add(ALL_SPEC); // put in a marker, but also fill values + } + + if (type == SECOND || type == MINUTE) { + if (stopAt == -1) { + stopAt = 59; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } else if (type == HOUR) { + if (stopAt == -1) { + stopAt = 23; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } else if (type == DAY_OF_MONTH) { + if (stopAt == -1) { + stopAt = 31; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == MONTH) { + if (stopAt == -1) { + stopAt = 12; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == DAY_OF_WEEK) { + if (stopAt == -1) { + stopAt = 7; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } else if (type == YEAR) { + if (stopAt == -1) { + stopAt = MAX_YEAR; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1970; + } + } + + // if the end of the range is before the start, then we need to overflow into + // the next day, month etc. This is done by adding the maximum amount for that + // type, and using modulus max to determine the value being added. + int max = -1; + if (stopAt < startAt) { + switch (type) { + case SECOND : max = 60; break; + case MINUTE : max = 60; break; + case HOUR : max = 24; break; + case MONTH : max = 12; break; + case DAY_OF_WEEK : max = 7; break; + case DAY_OF_MONTH : max = 31; break; + case YEAR : throw new IllegalArgumentException("Start year must be less than stop year"); + default : throw new IllegalArgumentException("Unexpected type encountered"); + } + stopAt += max; + } + + for (int i = startAt; i <= stopAt; i += incr) { + if (max == -1) { + // ie: there's no max to overflow over + set.add(i); + } else { + // take the modulus to get the real value + int i2 = i % max; + + // 1-indexed ranges should not include 0, and should include their max + if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH) ) { + i2 = max; + } + + set.add(i2); + } + } + } + + TreeSet getSet(int type) { + switch (type) { + case SECOND: + return seconds; + case MINUTE: + return minutes; + case HOUR: + return hours; + case DAY_OF_MONTH: + return daysOfMonth; + case MONTH: + return months; + case DAY_OF_WEEK: + return daysOfWeek; + case YEAR: + return years; + default: + return null; + } + } + + protected ValueSet getValue(int v, String s, int i) { + char c = s.charAt(i); + StringBuilder s1 = new StringBuilder(String.valueOf(v)); + while (c >= '0' && c <= '9') { + s1.append(c); + i++; + if (i >= s.length()) { + break; + } + c = s.charAt(i); + } + ValueSet val = new ValueSet(); + + val.pos = (i < s.length()) ? i : i + 1; + val.value = Integer.parseInt(s1.toString()); + return val; + } + + protected int getNumericValue(String s, int i) { + int endOfVal = findNextWhiteSpace(i, s); + String val = s.substring(i, endOfVal); + return Integer.parseInt(val); + } + + protected int getMonthNumber(String s) { + Integer integer = monthMap.get(s); + + if (integer == null) { + return -1; + } + + return integer; + } + + protected int getDayOfWeekNumber(String s) { + Integer integer = dayMap.get(s); + + if (integer == null) { + return -1; + } + + return integer; + } + + //////////////////////////////////////////////////////////////////////////// + // + // Computation Functions + // + //////////////////////////////////////////////////////////////////////////// + + public Date getTimeAfter(Date afterTime) { + + // Computation is based on Gregorian year only. + Calendar cl = new java.util.GregorianCalendar(getTimeZone()); + + // move ahead one second, since we're computing the time *after* the + // given time + afterTime = new Date(afterTime.getTime() + 1000); + // CronTrigger does not deal with milliseconds + cl.setTime(afterTime); + cl.set(Calendar.MILLISECOND, 0); + + boolean gotOne = false; + // loop until we've computed the next time, or we've past the endTime + while (!gotOne) { + + //if (endTime != null && cl.getTime().after(endTime)) return null; + if(cl.get(Calendar.YEAR) > 2999) { // prevent endless loop... + return null; + } + + SortedSet st = null; + int t = 0; + + int sec = cl.get(Calendar.SECOND); + int min = cl.get(Calendar.MINUTE); + + // get second................................................. + st = seconds.tailSet(sec); + if (st != null && st.size() != 0) { + sec = st.first(); + } else { + sec = seconds.first(); + min++; + cl.set(Calendar.MINUTE, min); + } + cl.set(Calendar.SECOND, sec); + + min = cl.get(Calendar.MINUTE); + int hr = cl.get(Calendar.HOUR_OF_DAY); + t = -1; + + // get minute................................................. + st = minutes.tailSet(min); + if (st != null && st.size() != 0) { + t = min; + min = st.first(); + } else { + min = minutes.first(); + hr++; + } + if (min != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, min); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.MINUTE, min); + + hr = cl.get(Calendar.HOUR_OF_DAY); + int day = cl.get(Calendar.DAY_OF_MONTH); + t = -1; + + // get hour................................................... + st = hours.tailSet(hr); + if (st != null && st.size() != 0) { + t = hr; + hr = st.first(); + } else { + hr = hours.first(); + day++; + } + if (hr != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.HOUR_OF_DAY, hr); + + day = cl.get(Calendar.DAY_OF_MONTH); + int mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + t = -1; + int tmon = mon; + + // get day................................................... + boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); + boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); + if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule + st = daysOfMonth.tailSet(day); + if (lastdayOfMonth) { + if(!nearestWeekday) { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + day -= lastdayOffset; + if(t > day) { + mon++; + if(mon > 12) { + mon = 1; + tmon = 3333; // ensure test of mon != tmon further below fails + cl.add(Calendar.YEAR, 1); + } + day = 1; + } + } else { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + day -= lastdayOffset; + + java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if(dow == Calendar.SATURDAY && day == 1) { + day += 2; + } else if(dow == Calendar.SATURDAY) { + day -= 1; + } else if(dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } else if(dow == Calendar.SUNDAY) { + day += 1; + } + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if(nTime.before(afterTime)) { + day = 1; + mon++; + } + } + } else if(nearestWeekday) { + t = day; + day = daysOfMonth.first(); + + java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if(dow == Calendar.SATURDAY && day == 1) { + day += 2; + } else if(dow == Calendar.SATURDAY) { + day -= 1; + } else if(dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } else if(dow == Calendar.SUNDAY) { + day += 1; + } + + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if(nTime.before(afterTime)) { + day = daysOfMonth.first(); + mon++; + } + } else if (st != null && st.size() != 0) { + t = day; + day = st.first(); + // make sure we don't over-run a short month, such as february + int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + if (day > lastDay) { + day = daysOfMonth.first(); + mon++; + } + } else { + day = daysOfMonth.first(); + mon++; + } + + if (day != t || mon != tmon) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we + // are 1-based + continue; + } + } else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule + if (lastdayOfWeek) { // are we looking for the last XXX day of + // the month? + int dow = daysOfWeek.first(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // did we already miss the + // last one? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } + + // find date of last occurrence of this day in this month... + while ((day + daysToAdd + 7) <= lDay) { + daysToAdd += 7; + } + + day += daysToAdd; + + if (daysToAdd > 0) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are not promoting the month + continue; + } + + } else if (nthdayOfWeek != 0) { + // are we looking for the Nth XXX day in the month? + int dow = daysOfWeek.first(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } else if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + boolean dayShifted = false; + if (daysToAdd > 0) { + dayShifted = true; + } + + day += daysToAdd; + int weekOfMonth = day / 7; + if (day % 7 > 0) { + weekOfMonth++; + } + + daysToAdd = (nthdayOfWeek - weekOfMonth) * 7; + day += daysToAdd; + if (daysToAdd < 0 + || day > getLastDayOfMonth(mon, cl + .get(Calendar.YEAR))) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } else if (daysToAdd > 0 || dayShifted) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are NOT promoting the month + continue; + } + } else { + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int dow = daysOfWeek.first(); // desired + // d-o-w + st = daysOfWeek.tailSet(cDow); + if (st != null && st.size() > 0) { + dow = st.first(); + } + + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // will we pass the end of + // the month? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } else if (daysToAdd > 0) { // are we swithing days? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, + // and we are 1-based + continue; + } + } + } else { // dayOfWSpec && !dayOfMSpec + throw new UnsupportedOperationException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); + } + cl.set(Calendar.DAY_OF_MONTH, day); + + mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + int year = cl.get(Calendar.YEAR); + t = -1; + + // test for expressions that never generate a valid fire date, + // but keep looping... + if (year > MAX_YEAR) { + return null; + } + + // get month................................................... + st = months.tailSet(mon); + if (st != null && st.size() != 0) { + t = mon; + mon = st.first(); + } else { + mon = months.first(); + year++; + } + if (mon != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + + year = cl.get(Calendar.YEAR); + t = -1; + + // get year................................................... + st = years.tailSet(year); + if (st != null && st.size() != 0) { + t = year; + year = st.first(); + } else { + return null; // ran out of years... + } + + if (year != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, 0); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.YEAR, year); + + gotOne = true; + } // while( !done ) + + return cl.getTime(); + } + + /** + * Advance the calendar to the particular hour paying particular attention + * to daylight saving problems. + * + * @param cal the calendar to operate on + * @param hour the hour to set + */ + protected void setCalendarHour(Calendar cal, int hour) { + cal.set(java.util.Calendar.HOUR_OF_DAY, hour); + if (cal.get(java.util.Calendar.HOUR_OF_DAY) != hour && hour != 24) { + cal.set(java.util.Calendar.HOUR_OF_DAY, hour + 1); + } + } + + /** + * NOT YET IMPLEMENTED: Returns the time before the given time + * that the CronExpression matches. + */ + public Date getTimeBefore(Date endTime) { + // FUTURE_TODO: implement QUARTZ-423 + return null; + } + + /** + * NOT YET IMPLEMENTED: Returns the final time that the + * CronExpression will match. + */ + public Date getFinalFireTime() { + // FUTURE_TODO: implement QUARTZ-423 + return null; + } + + protected boolean isLeapYear(int year) { + return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); + } + + protected int getLastDayOfMonth(int monthNum, int year) { + + switch (monthNum) { + case 1: + return 31; + case 2: + return (isLeapYear(year)) ? 29 : 28; + case 3: + return 31; + case 4: + return 30; + case 5: + return 31; + case 6: + return 30; + case 7: + return 31; + case 8: + return 31; + case 9: + return 30; + case 10: + return 31; + case 11: + return 30; + case 12: + return 31; + default: + throw new IllegalArgumentException("Illegal month number: " + + monthNum); + } + } + + + private void readObject(java.io.ObjectInputStream stream) + throws java.io.IOException, ClassNotFoundException { + + stream.defaultReadObject(); + try { + buildExpression(cronExpression); + } catch (Exception ignore) { + } // never happens + } + + @Override + @Deprecated + public Object clone() { + return new CronExpression(this); + } +} + +class ValueSet { + public int value; + + public int pos; +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/exception/XxlJobException.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/exception/XxlJobException.java new file mode 100644 index 0000000..faa6063 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/exception/XxlJobException.java @@ -0,0 +1,14 @@ +package com.xxl.job.admin.core.exception; + +/** + * @author xuxueli 2019-05-04 23:19:29 + */ +public class XxlJobException extends RuntimeException { + + public XxlJobException() { + } + public XxlJobException(String message) { + super(message); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobGroup.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobGroup.java new file mode 100644 index 0000000..dde4b39 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobGroup.java @@ -0,0 +1,77 @@ +package com.xxl.job.admin.core.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * Created by xuxueli on 16/9/30. + */ +public class XxlJobGroup { + + private int id; + private String appname; + private String title; + private int addressType; // 执行器地址类型:0=自动注册、1=手动录入 + private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入) + private Date updateTime; + + // registry list + private List registryList; // 执行器地址列表(系统注册) + public List getRegistryList() { + if (addressList!=null && addressList.trim().length()>0) { + registryList = new ArrayList(Arrays.asList(addressList.split(","))); + } + return registryList; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAppname() { + return appname; + } + + public void setAppname(String appname) { + this.appname = appname; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getAddressType() { + return addressType; + } + + public void setAddressType(int addressType) { + this.addressType = addressType; + } + + public String getAddressList() { + return addressList; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public void setAddressList(String addressList) { + this.addressList = addressList; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java new file mode 100644 index 0000000..960a88d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java @@ -0,0 +1,261 @@ +package com.xxl.job.admin.core.model; + +import java.util.Date; + +/** + * xxl-job info + * + * @author xuxueli 2016-1-12 18:25:49 + */ +public class XxlJobInfo { + + private int id; // 主键ID + + private int jobGroup; // 执行器主键ID + + private String jobGroupName; + + private String jobDesc; + + private Date addTime; + private Date updateTime; + + private String author; // 负责人 + private String alarmEmail; // 报警邮件 + + private String scheduleType; // 调度类型 + private String scheduleConf; // 调度配置,值含义取决于调度类型 + private String misfireStrategy; // 调度过期策略 + + private String executorRouteStrategy; // 执行器路由策略 + private String executorHandler; // 执行器,任务Handler名称 + private String executorParam; // 执行器,任务参数 + private String executorBlockStrategy; // 阻塞处理策略 + private int executorTimeout; // 任务执行超时时间,单位秒 + private int executorFailRetryCount; // 失败重试次数 + + private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum + private String glueSource; // GLUE源代码 + private String glueRemark; // GLUE备注 + private Date glueUpdatetime; // GLUE更新时间 + + private String childJobId; // 子任务ID,多个逗号分隔 + + private int triggerStatus; // 调度状态:0-停止,1-运行 + private long triggerLastTime; // 上次调度时间 + private long triggerNextTime; // 下次调度时间 + + /** + * 日程id,工作计划id等 + */ + private String objectId; + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getJobGroup() { + return jobGroup; + } + + public void setJobGroup(int jobGroup) { + this.jobGroup = jobGroup; + } + + public String getJobDesc() { + return jobDesc; + } + + public void setJobDesc(String jobDesc) { + this.jobDesc = jobDesc; + } + + public Date getAddTime() { + return addTime; + } + + public void setAddTime(Date addTime) { + this.addTime = addTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAlarmEmail() { + return alarmEmail; + } + + public void setAlarmEmail(String alarmEmail) { + this.alarmEmail = alarmEmail; + } + + public String getScheduleType() { + return scheduleType; + } + + public void setScheduleType(String scheduleType) { + this.scheduleType = scheduleType; + } + + public String getScheduleConf() { + return scheduleConf; + } + + public void setScheduleConf(String scheduleConf) { + this.scheduleConf = scheduleConf; + } + + public String getMisfireStrategy() { + return misfireStrategy; + } + + public void setMisfireStrategy(String misfireStrategy) { + this.misfireStrategy = misfireStrategy; + } + + public String getExecutorRouteStrategy() { + return executorRouteStrategy; + } + + public void setExecutorRouteStrategy(String executorRouteStrategy) { + this.executorRouteStrategy = executorRouteStrategy; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public String getExecutorBlockStrategy() { + return executorBlockStrategy; + } + + public void setExecutorBlockStrategy(String executorBlockStrategy) { + this.executorBlockStrategy = executorBlockStrategy; + } + + public int getExecutorTimeout() { + return executorTimeout; + } + + public void setExecutorTimeout(int executorTimeout) { + this.executorTimeout = executorTimeout; + } + + public int getExecutorFailRetryCount() { + return executorFailRetryCount; + } + + public void setExecutorFailRetryCount(int executorFailRetryCount) { + this.executorFailRetryCount = executorFailRetryCount; + } + + public String getGlueType() { + return glueType; + } + + public void setGlueType(String glueType) { + this.glueType = glueType; + } + + public String getGlueSource() { + return glueSource; + } + + public void setGlueSource(String glueSource) { + this.glueSource = glueSource; + } + + public String getGlueRemark() { + return glueRemark; + } + + public void setGlueRemark(String glueRemark) { + this.glueRemark = glueRemark; + } + + public Date getGlueUpdatetime() { + return glueUpdatetime; + } + + public void setGlueUpdatetime(Date glueUpdatetime) { + this.glueUpdatetime = glueUpdatetime; + } + + public String getChildJobId() { + return childJobId; + } + + public void setChildJobId(String childJobId) { + this.childJobId = childJobId; + } + + public int getTriggerStatus() { + return triggerStatus; + } + + public void setTriggerStatus(int triggerStatus) { + this.triggerStatus = triggerStatus; + } + + public long getTriggerLastTime() { + return triggerLastTime; + } + + public void setTriggerLastTime(long triggerLastTime) { + this.triggerLastTime = triggerLastTime; + } + + public long getTriggerNextTime() { + return triggerNextTime; + } + + public void setTriggerNextTime(long triggerNextTime) { + this.triggerNextTime = triggerNextTime; + } + + public String getJobGroupName() { + return jobGroupName; + } + + public void setJobGroupName(String jobGroupName) { + this.jobGroupName = jobGroupName; + } + + public String getObjectId() { + return objectId; + } + + public void setObjectId(String objectId) { + this.objectId = objectId; + } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java new file mode 100644 index 0000000..7d3072a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java @@ -0,0 +1,157 @@ +package com.xxl.job.admin.core.model; + +import java.util.Date; + +/** + * xxl-job log, used to track trigger process + * @author xuxueli 2015-12-19 23:19:09 + */ +public class XxlJobLog { + + private long id; + + // job info + private int jobGroup; + private int jobId; + + // execute info + private String executorAddress; + private String executorHandler; + private String executorParam; + private String executorShardingParam; + private int executorFailRetryCount; + + // trigger info + private Date triggerTime; + private int triggerCode; + private String triggerMsg; + + // handle info + private Date handleTime; + private int handleCode; + private String handleMsg; + + // alarm info + private int alarmStatus; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public int getJobGroup() { + return jobGroup; + } + + public void setJobGroup(int jobGroup) { + this.jobGroup = jobGroup; + } + + public int getJobId() { + return jobId; + } + + public void setJobId(int jobId) { + this.jobId = jobId; + } + + public String getExecutorAddress() { + return executorAddress; + } + + public void setExecutorAddress(String executorAddress) { + this.executorAddress = executorAddress; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public String getExecutorShardingParam() { + return executorShardingParam; + } + + public void setExecutorShardingParam(String executorShardingParam) { + this.executorShardingParam = executorShardingParam; + } + + public int getExecutorFailRetryCount() { + return executorFailRetryCount; + } + + public void setExecutorFailRetryCount(int executorFailRetryCount) { + this.executorFailRetryCount = executorFailRetryCount; + } + + public Date getTriggerTime() { + return triggerTime; + } + + public void setTriggerTime(Date triggerTime) { + this.triggerTime = triggerTime; + } + + public int getTriggerCode() { + return triggerCode; + } + + public void setTriggerCode(int triggerCode) { + this.triggerCode = triggerCode; + } + + public String getTriggerMsg() { + return triggerMsg; + } + + public void setTriggerMsg(String triggerMsg) { + this.triggerMsg = triggerMsg; + } + + public Date getHandleTime() { + return handleTime; + } + + public void setHandleTime(Date handleTime) { + this.handleTime = handleTime; + } + + public int getHandleCode() { + return handleCode; + } + + public void setHandleCode(int handleCode) { + this.handleCode = handleCode; + } + + public String getHandleMsg() { + return handleMsg; + } + + public void setHandleMsg(String handleMsg) { + this.handleMsg = handleMsg; + } + + public int getAlarmStatus() { + return alarmStatus; + } + + public void setAlarmStatus(int alarmStatus) { + this.alarmStatus = alarmStatus; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java new file mode 100644 index 0000000..2f59ffa --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java @@ -0,0 +1,75 @@ +package com.xxl.job.admin.core.model; + +import java.util.Date; + +/** + * xxl-job log for glue, used to track job code process + * @author xuxueli 2016-5-19 17:57:46 + */ +public class XxlJobLogGlue { + + private int id; + private int jobId; // 任务主键ID + private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum + private String glueSource; + private String glueRemark; + private Date addTime; + private Date updateTime; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getJobId() { + return jobId; + } + + public void setJobId(int jobId) { + this.jobId = jobId; + } + + public String getGlueType() { + return glueType; + } + + public void setGlueType(String glueType) { + this.glueType = glueType; + } + + public String getGlueSource() { + return glueSource; + } + + public void setGlueSource(String glueSource) { + this.glueSource = glueSource; + } + + public String getGlueRemark() { + return glueRemark; + } + + public void setGlueRemark(String glueRemark) { + this.glueRemark = glueRemark; + } + + public Date getAddTime() { + return addTime; + } + + public void setAddTime(Date addTime) { + this.addTime = addTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogReport.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogReport.java new file mode 100644 index 0000000..e58ff1a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogReport.java @@ -0,0 +1,54 @@ +package com.xxl.job.admin.core.model; + +import java.util.Date; + +public class XxlJobLogReport { + + private int id; + + private Date triggerDay; + + private int runningCount; + private int sucCount; + private int failCount; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Date getTriggerDay() { + return triggerDay; + } + + public void setTriggerDay(Date triggerDay) { + this.triggerDay = triggerDay; + } + + public int getRunningCount() { + return runningCount; + } + + public void setRunningCount(int runningCount) { + this.runningCount = runningCount; + } + + public int getSucCount() { + return sucCount; + } + + public void setSucCount(int sucCount) { + this.sucCount = sucCount; + } + + public int getFailCount() { + return failCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobRegistry.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobRegistry.java new file mode 100644 index 0000000..924d6d3 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobRegistry.java @@ -0,0 +1,55 @@ +package com.xxl.job.admin.core.model; + +import java.util.Date; + +/** + * Created by xuxueli on 16/9/30. + */ +public class XxlJobRegistry { + + private int id; + private String registryGroup; + private String registryKey; + private String registryValue; + private Date updateTime; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getRegistryGroup() { + return registryGroup; + } + + public void setRegistryGroup(String registryGroup) { + this.registryGroup = registryGroup; + } + + public String getRegistryKey() { + return registryKey; + } + + public void setRegistryKey(String registryKey) { + this.registryKey = registryKey; + } + + public String getRegistryValue() { + return registryValue; + } + + public void setRegistryValue(String registryValue) { + this.registryValue = registryValue; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobUser.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobUser.java new file mode 100644 index 0000000..db17327 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobUser.java @@ -0,0 +1,73 @@ +package com.xxl.job.admin.core.model; + +import org.springframework.util.StringUtils; + +/** + * @author xuxueli 2019-05-04 16:43:12 + */ +public class XxlJobUser { + + private int id; + private String username; // 账号 + private String password; // 密码 + private int role; // 角色:0-普通用户、1-管理员 + private String permission; // 权限:执行器ID列表,多个逗号分割 + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + 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 int getRole() { + return role; + } + + public void setRole(int role) { + this.role = role; + } + + public String getPermission() { + return permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + // plugin + public boolean validPermission(int jobGroup){ + if (this.role == 1) { + return true; + } else { + if (StringUtils.hasText(this.permission)) { + for (String permissionItem : this.permission.split(",")) { + if (String.valueOf(jobGroup).equals(permissionItem)) { + return true; + } + } + } + return false; + } + + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/RemoteHttpJobBean.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/RemoteHttpJobBean.java new file mode 100644 index 0000000..b2dd151 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/RemoteHttpJobBean.java @@ -0,0 +1,32 @@ +//package com.xxl.job.admin.core.jobbean; +// +//import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; +//import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +//import org.quartz.JobExecutionContext; +//import org.quartz.JobExecutionException; +//import org.quartz.JobKey; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.scheduling.quartz.QuartzJobBean; +// +///** +// * http job bean +// * “@DisallowConcurrentExecution” disable concurrent, thread size can not be only one, better given more +// * @author xuxueli 2015-12-17 18:20:34 +// */ +////@DisallowConcurrentExecution +//public class RemoteHttpJobBean extends QuartzJobBean { +// private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class); +// +// @Override +// protected void executeInternal(JobExecutionContext context) +// throws JobExecutionException { +// +// // load jobId +// JobKey jobKey = context.getTrigger().getJobKey(); +// Integer jobId = Integer.valueOf(jobKey.getName()); +// +// +// } +// +//} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobDynamicScheduler.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobDynamicScheduler.java new file mode 100644 index 0000000..1e62aa1 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobDynamicScheduler.java @@ -0,0 +1,413 @@ +//package com.xxl.job.admin.core.schedule; +// +//import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +//import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean; +//import com.xxl.job.admin.core.model.XxlJobInfo; +//import com.xxl.job.admin.core.thread.JobFailMonitorHelper; +//import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper; +//import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; +//import com.xxl.job.admin.core.util.I18nUtil; +//import com.xxl.job.core.biz.AdminBiz; +//import com.xxl.job.core.biz.ExecutorBiz; +//import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +//import com.xxl.rpc.remoting.invoker.XxlRpcInvokerFactory; +//import com.xxl.rpc.remoting.invoker.call.CallType; +//import com.xxl.rpc.remoting.invoker.reference.XxlRpcReferenceBean; +//import com.xxl.rpc.remoting.invoker.route.LoadBalance; +//import com.xxl.rpc.remoting.net.NetEnum; +//import com.xxl.rpc.remoting.net.impl.servlet.server.ServletServerHandler; +//import com.xxl.rpc.remoting.provider.XxlRpcProviderFactory; +//import com.xxl.rpc.serialize.Serializer; +//import org.quartz.*; +//import org.quartz.Trigger.TriggerState; +//import org.quartz.impl.triggers.CronTriggerImpl; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.util.Assert; +// +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.io.IOException; +//import java.util.Date; +//import java.util.concurrent.ConcurrentHashMap; +// +///** +// * base quartz scheduler util +// * @author xuxueli 2015-12-19 16:13:53 +// */ +//public final class XxlJobDynamicScheduler { +// private static final Logger logger = LoggerFactory.getLogger(XxlJobDynamicScheduler_old.class); +// +// // ---------------------- param ---------------------- +// +// // scheduler +// private static Scheduler scheduler; +// public void setScheduler(Scheduler scheduler) { +// XxlJobDynamicScheduler_old.scheduler = scheduler; +// } +// +// +// // ---------------------- init + destroy ---------------------- +// public void start() throws Exception { +// // valid +// Assert.notNull(scheduler, "quartz scheduler is null"); +// +// // init i18n +// initI18n(); +// +// // admin registry monitor run +// JobRegistryMonitorHelper.getInstance().start(); +// +// // admin monitor run +// JobFailMonitorHelper.getInstance().start(); +// +// // admin-server +// initRpcProvider(); +// +// logger.info(">>>>>>>>> init xxl-job admin success."); +// } +// +// +// public void destroy() throws Exception { +// // admin trigger pool stop +// JobTriggerPoolHelper.toStop(); +// +// // admin registry stop +// JobRegistryMonitorHelper.getInstance().toStop(); +// +// // admin monitor stop +// JobFailMonitorHelper.getInstance().toStop(); +// +// // admin-server +// stopRpcProvider(); +// } +// +// +// // ---------------------- I18n ---------------------- +// +// private void initI18n(){ +// for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) { +// item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name()))); +// } +// } +// +// +// // ---------------------- admin rpc provider (no server version) ---------------------- +// private static ServletServerHandler servletServerHandler; +// private void initRpcProvider(){ +// // init +// XxlRpcProviderFactory xxlRpcProviderFactory = new XxlRpcProviderFactory(); +// xxlRpcProviderFactory.initConfig( +// NetEnum.NETTY_HTTP, +// Serializer.SerializeEnum.HESSIAN.getSerializer(), +// null, +// 0, +// XxlJobAdminConfig.getAdminConfig().getAccessToken(), +// null, +// null); +// +// // add services +// xxlRpcProviderFactory.addService(AdminBiz.class.getName(), null, XxlJobAdminConfig.getAdminConfig().getAdminBiz()); +// +// // servlet handler +// servletServerHandler = new ServletServerHandler(xxlRpcProviderFactory); +// } +// private void stopRpcProvider() throws Exception { +// XxlRpcInvokerFactory.getInstance().stop(); +// } +// public static void invokeAdminService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// servletServerHandler.handle(null, request, response); +// } +// +// +// // ---------------------- executor-client ---------------------- +// private static ConcurrentHashMap executorBizRepository = new ConcurrentHashMap(); +// public static ExecutorBiz getExecutorBiz(String address) throws Exception { +// // valid +// if (address==null || address.trim().length()==0) { +// return null; +// } +// +// // load-cache +// address = address.trim(); +// ExecutorBiz executorBiz = executorBizRepository.get(address); +// if (executorBiz != null) { +// return executorBiz; +// } +// +// // set-cache +// executorBiz = (ExecutorBiz) new XxlRpcReferenceBean( +// NetEnum.NETTY_HTTP, +// Serializer.SerializeEnum.HESSIAN.getSerializer(), +// CallType.SYNC, +// LoadBalance.ROUND, +// ExecutorBiz.class, +// null, +// 5000, +// address, +// XxlJobAdminConfig.getAdminConfig().getAccessToken(), +// null, +// null).getObject(); +// +// executorBizRepository.put(address, executorBiz); +// return executorBiz; +// } +// +// +// // ---------------------- schedule util ---------------------- +// +// /** +// * fill job info +// * +// * @param jobInfo +// */ +// public static void fillJobInfo(XxlJobInfo jobInfo) { +// +// String name = String.valueOf(jobInfo.getId()); +// +// // trigger key +// TriggerKey triggerKey = TriggerKey.triggerKey(name); +// try { +// +// // trigger cron +// Trigger trigger = scheduler.getTrigger(triggerKey); +// if (trigger!=null && trigger instanceof CronTriggerImpl) { +// String cronExpression = ((CronTriggerImpl) trigger).getCronExpression(); +// jobInfo.setJobCron(cronExpression); +// } +// +// // trigger state +// TriggerState triggerState = scheduler.getTriggerState(triggerKey); +// if (triggerState!=null) { +// jobInfo.setJobStatus(triggerState.name()); +// } +// +// //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup())); +// //JobDetail jobDetail = scheduler.getJobDetail(jobKey); +// //String jobClass = jobDetail.getJobClass().getName(); +// +// } catch (SchedulerException e) { +// logger.error(e.getMessage(), e); +// } +// } +// +// +// /** +// * add trigger + job +// * +// * @param jobName +// * @param cronExpression +// * @return +// * @throws SchedulerException +// */ +// public static boolean addJob(String jobName, String cronExpression) throws SchedulerException { +// // 1、job key +// TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// JobKey jobKey = new JobKey(jobName); +// +// // 2、valid +// if (scheduler.checkExists(triggerKey)) { +// return true; // PASS +// } +// +// // 3、corn trigger +// CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing(); // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度 +// CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); +// +// // 4、job detail +// Class jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass()); +// JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build(); +// +// /*if (jobInfo.getJobData()!=null) { +// JobDataMap jobDataMap = jobDetail.getJobDataMap(); +// jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class)); +// // JobExecutionContext context.getMergedJobDataMap().get("mailGuid"); +// }*/ +// +// // 5、schedule job +// Date date = scheduler.scheduleJob(jobDetail, cronTrigger); +// +// logger.info(">>>>>>>>>>> addJob success(quartz), jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date); +// return true; +// } +// +// +// /** +// * remove trigger + job +// * +// * @param jobName +// * @return +// * @throws SchedulerException +// */ +// public static boolean removeJob(String jobName) throws SchedulerException { +// +// JobKey jobKey = new JobKey(jobName); +// scheduler.deleteJob(jobKey); +// +// /*TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// if (scheduler.checkExists(triggerKey)) { +// scheduler.unscheduleJob(triggerKey); // trigger + job +// }*/ +// +// logger.info(">>>>>>>>>>> removeJob success(quartz), jobKey:{}", jobKey); +// return true; +// } +// +// +// /** +// * updateJobCron +// * +// * @param jobName +// * @param cronExpression +// * @return +// * @throws SchedulerException +// */ +// public static boolean updateJobCron(String jobName, String cronExpression) throws SchedulerException { +// +// // 1、job key +// TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// +// // 2、valid +// if (!scheduler.checkExists(triggerKey)) { +// return true; // PASS +// } +// +// CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey); +// +// // 3、avoid repeat cron +// String oldCron = oldTrigger.getCronExpression(); +// if (oldCron.equals(cronExpression)){ +// return true; // PASS +// } +// +// // 4、new cron trigger +// CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing(); +// oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); +// +// // 5、rescheduleJob +// scheduler.rescheduleJob(triggerKey, oldTrigger); +// +// /* +// JobKey jobKey = new JobKey(jobName); +// +// // old job detail +// JobDetail jobDetail = scheduler.getJobDetail(jobKey); +// +// // new trigger +// HashSet triggerSet = new HashSet(); +// triggerSet.add(cronTrigger); +// // cover trigger of job detail +// scheduler.scheduleJob(jobDetail, triggerSet, true);*/ +// +// logger.info(">>>>>>>>>>> resumeJob success, JobName:{}", jobName); +// return true; +// } +// +// +// /** +// * pause +// * +// * @param jobName +// * @return +// * @throws SchedulerException +// */ +// /*public static boolean pauseJob(String jobName) throws SchedulerException { +// +// TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// +// boolean result = false; +// if (scheduler.checkExists(triggerKey)) { +// scheduler.pauseTrigger(triggerKey); +// result = true; +// } +// +// logger.info(">>>>>>>>>>> pauseJob {}, triggerKey:{}", (result?"success":"fail"),triggerKey); +// return result; +// }*/ +// +// +// /** +// * resume +// * +// * @param jobName +// * @return +// * @throws SchedulerException +// */ +// /*public static boolean resumeJob(String jobName) throws SchedulerException { +// +// TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// +// boolean result = false; +// if (scheduler.checkExists(triggerKey)) { +// scheduler.resumeTrigger(triggerKey); +// result = true; +// } +// +// logger.info(">>>>>>>>>>> resumeJob {}, triggerKey:{}", (result?"success":"fail"), triggerKey); +// return result; +// }*/ +// +// +// /** +// * run +// * +// * @param jobName +// * @return +// * @throws SchedulerException +// */ +// /*public static boolean triggerJob(String jobName) throws SchedulerException { +// // TriggerKey : name + group +// JobKey jobKey = new JobKey(jobName); +// TriggerKey triggerKey = TriggerKey.triggerKey(jobName); +// +// boolean result = false; +// if (scheduler.checkExists(triggerKey)) { +// scheduler.triggerJob(jobKey); +// result = true; +// logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey); +// } else { +// logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey); +// } +// return result; +// }*/ +// +// +// /** +// * finaAllJobList +// * +// * @return +// *//* +// @Deprecated +// public static List> finaAllJobList(){ +// List> jobList = new ArrayList>(); +// +// try { +// if (scheduler.getJobGroupNames()==null || scheduler.getJobGroupNames().size()==0) { +// return null; +// } +// String groupName = scheduler.getJobGroupNames().get(0); +// Set jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName)); +// if (jobKeys!=null && jobKeys.size()>0) { +// for (JobKey jobKey : jobKeys) { +// TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), Scheduler.DEFAULT_GROUP); +// Trigger trigger = scheduler.getTrigger(triggerKey); +// JobDetail jobDetail = scheduler.getJobDetail(jobKey); +// TriggerState triggerState = scheduler.getTriggerState(triggerKey); +// Map jobMap = new HashMap(); +// jobMap.put("TriggerKey", triggerKey); +// jobMap.put("Trigger", trigger); +// jobMap.put("JobDetail", jobDetail); +// jobMap.put("TriggerState", triggerState); +// jobList.add(jobMap); +// } +// } +// +// } catch (SchedulerException e) { +// logger.error(e.getMessage(), e); +// return null; +// } +// return jobList; +// }*/ +// +//} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobThreadPool.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobThreadPool.java new file mode 100644 index 0000000..ad07430 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/old/XxlJobThreadPool.java @@ -0,0 +1,58 @@ +//package com.xxl.job.admin.core.quartz; +// +//import org.quartz.SchedulerConfigException; +//import org.quartz.spi.ThreadPool; +// +///** +// * single thread pool, for async trigger +// * +// * @author xuxueli 2019-03-06 +// */ +//public class XxlJobThreadPool implements ThreadPool { +// +// @Override +// public boolean runInThread(Runnable runnable) { +// +// // async run +// runnable.run(); +// return true; +// +// //return false; +// } +// +// @Override +// public int blockForAvailableThreads() { +// return 1; +// } +// +// @Override +// public void initialize() throws SchedulerConfigException { +// +// } +// +// @Override +// public void shutdown(boolean waitForJobsToComplete) { +// +// } +// +// @Override +// public int getPoolSize() { +// return 1; +// } +// +// @Override +// public void setInstanceId(String schedInstId) { +// +// } +// +// @Override +// public void setInstanceName(String schedName) { +// +// } +// +// // support +// public void setThreadCount(int count) { +// // +// } +// +//} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java new file mode 100644 index 0000000..7fff93a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java @@ -0,0 +1,48 @@ +package com.xxl.job.admin.core.route; + +import com.xxl.job.admin.core.route.strategy.*; +import com.xxl.job.admin.core.util.I18nUtil; + +/** + * Created by xuxueli on 17/3/10. + */ +public enum ExecutorRouteStrategyEnum { + + FIRST(I18nUtil.getString("jobconf_route_first"), new ExecutorRouteFirst()), + LAST(I18nUtil.getString("jobconf_route_last"), new ExecutorRouteLast()), + ROUND(I18nUtil.getString("jobconf_route_round"), new ExecutorRouteRound()), + RANDOM(I18nUtil.getString("jobconf_route_random"), new ExecutorRouteRandom()), + CONSISTENT_HASH(I18nUtil.getString("jobconf_route_consistenthash"), new ExecutorRouteConsistentHash()), + LEAST_FREQUENTLY_USED(I18nUtil.getString("jobconf_route_lfu"), new ExecutorRouteLFU()), + LEAST_RECENTLY_USED(I18nUtil.getString("jobconf_route_lru"), new ExecutorRouteLRU()), + FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover()), + BUSYOVER(I18nUtil.getString("jobconf_route_busyover"), new ExecutorRouteBusyover()), + SHARDING_BROADCAST(I18nUtil.getString("jobconf_route_shard"), null); + + ExecutorRouteStrategyEnum(String title, ExecutorRouter router) { + this.title = title; + this.router = router; + } + + private String title; + private ExecutorRouter router; + + public String getTitle() { + return title; + } + public ExecutorRouter getRouter() { + return router; + } + + public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){ + if (name != null) { + for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) { + if (item.name().equals(name)) { + return item; + } + } + } + return defaultItem; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java new file mode 100644 index 0000000..5de9a1d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java @@ -0,0 +1,24 @@ +package com.xxl.job.admin.core.route; + +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Created by xuxueli on 17/3/10. + */ +public abstract class ExecutorRouter { + protected static Logger logger = LoggerFactory.getLogger(ExecutorRouter.class); + + /** + * route address + * + * @param addressList + * @return ReturnT.content=address + */ + public abstract ReturnT route(TriggerParam triggerParam, List addressList); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java new file mode 100644 index 0000000..868560f --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java @@ -0,0 +1,48 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.scheduler.XxlJobScheduler; +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.ExecutorBiz; +import com.xxl.job.core.biz.model.IdleBeatParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteBusyover extends ExecutorRouter { + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + StringBuffer idleBeatResultSB = new StringBuffer(); + for (String address : addressList) { + // beat + ReturnT idleBeatResult = null; + try { + ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); + idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId())); + } catch (Exception e) { + logger.error(e.getMessage(), e); + idleBeatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); + } + idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"

":"") + .append(I18nUtil.getString("jobconf_idleBeat") + ":") + .append("
address:").append(address) + .append("
code:").append(idleBeatResult.getCode()) + .append("
msg:").append(idleBeatResult.getMsg()); + + // beat success + if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) { + idleBeatResult.setMsg(idleBeatResultSB.toString()); + idleBeatResult.setContent(address); + return idleBeatResult; + } + } + + return new ReturnT(ReturnT.FAIL_CODE, idleBeatResultSB.toString()); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteConsistentHash.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteConsistentHash.java new file mode 100644 index 0000000..41ac671 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteConsistentHash.java @@ -0,0 +1,85 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * 分组下机器地址相同,不同JOB均匀散列在不同机器上,保证分组下机器分配JOB平均;且每个JOB固定调度其中一台机器; + * a、virtual node:解决不均衡问题 + * b、hash method replace hashCode:String的hashCode可能重复,需要进一步扩大hashCode的取值范围 + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteConsistentHash extends ExecutorRouter { + + private static int VIRTUAL_NODE_NUM = 100; + + /** + * get hash code on 2^32 ring (md5散列的方式计算hash值) + * @param key + * @return + */ + private static long hash(String key) { + + // md5 byte + MessageDigest md5; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("MD5 not supported", e); + } + md5.reset(); + byte[] keyBytes = null; + try { + keyBytes = key.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Unknown string :" + key, e); + } + + md5.update(keyBytes); + byte[] digest = md5.digest(); + + // hash code, Truncate to 32-bits + long hashCode = ((long) (digest[3] & 0xFF) << 24) + | ((long) (digest[2] & 0xFF) << 16) + | ((long) (digest[1] & 0xFF) << 8) + | (digest[0] & 0xFF); + + long truncateHashCode = hashCode & 0xffffffffL; + return truncateHashCode; + } + + public String hashJob(int jobId, List addressList) { + + // ------A1------A2-------A3------ + // -----------J1------------------ + TreeMap addressRing = new TreeMap(); + for (String address: addressList) { + for (int i = 0; i < VIRTUAL_NODE_NUM; i++) { + long addressHash = hash("SHARD-" + address + "-NODE-" + i); + addressRing.put(addressHash, address); + } + } + + long jobHash = hash(String.valueOf(jobId)); + SortedMap lastRing = addressRing.tailMap(jobHash); + if (!lastRing.isEmpty()) { + return lastRing.get(lastRing.firstKey()); + } + return addressRing.firstEntry().getValue(); + } + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + String address = hashJob(triggerParam.getJobId(), addressList); + return new ReturnT(address); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java new file mode 100644 index 0000000..a2e4c90 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java @@ -0,0 +1,48 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.scheduler.XxlJobScheduler; +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.ExecutorBiz; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteFailover extends ExecutorRouter { + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + + StringBuffer beatResultSB = new StringBuffer(); + for (String address : addressList) { + // beat + ReturnT beatResult = null; + try { + ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); + beatResult = executorBiz.beat(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + beatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); + } + beatResultSB.append( (beatResultSB.length()>0)?"

":"") + .append(I18nUtil.getString("jobconf_beat") + ":") + .append("
address:").append(address) + .append("
code:").append(beatResult.getCode()) + .append("
msg:").append(beatResult.getMsg()); + + // beat success + if (beatResult.getCode() == ReturnT.SUCCESS_CODE) { + + beatResult.setMsg(beatResultSB.toString()); + beatResult.setContent(address); + return beatResult; + } + } + return new ReturnT(ReturnT.FAIL_CODE, beatResultSB.toString()); + + } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java new file mode 100644 index 0000000..de4d7af --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java @@ -0,0 +1,19 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteFirst extends ExecutorRouter { + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList){ + return new ReturnT(addressList.get(0)); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java new file mode 100644 index 0000000..9df1972 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java @@ -0,0 +1,79 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * 单个JOB对应的每个执行器,使用频率最低的优先被选举 + * a(*)、LFU(Least Frequently Used):最不经常使用,频率/次数 + * b、LRU(Least Recently Used):最近最久未使用,时间 + * + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteLFU extends ExecutorRouter { + + private static ConcurrentMap> jobLfuMap = new ConcurrentHashMap>(); + private static long CACHE_VALID_TIME = 0; + + public String route(int jobId, List addressList) { + + // cache clear + if (System.currentTimeMillis() > CACHE_VALID_TIME) { + jobLfuMap.clear(); + CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; + } + + // lfu item init + HashMap lfuItemMap = jobLfuMap.get(jobId); // Key排序可以用TreeMap+构造入参Compare;Value排序暂时只能通过ArrayList; + if (lfuItemMap == null) { + lfuItemMap = new HashMap(); + jobLfuMap.putIfAbsent(jobId, lfuItemMap); // 避免重复覆盖 + } + + // put new + for (String address: addressList) { + if (!lfuItemMap.containsKey(address) || lfuItemMap.get(address) >1000000 ) { + lfuItemMap.put(address, new Random().nextInt(addressList.size())); // 初始化时主动Random一次,缓解首次压力 + } + } + // remove old + List delKeys = new ArrayList<>(); + for (String existKey: lfuItemMap.keySet()) { + if (!addressList.contains(existKey)) { + delKeys.add(existKey); + } + } + if (delKeys.size() > 0) { + for (String delKey: delKeys) { + lfuItemMap.remove(delKey); + } + } + + // load least userd count address + List> lfuItemList = new ArrayList>(lfuItemMap.entrySet()); + Collections.sort(lfuItemList, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o1.getValue().compareTo(o2.getValue()); + } + }); + + Map.Entry addressItem = lfuItemList.get(0); + String minAddress = addressItem.getKey(); + addressItem.setValue(addressItem.getValue() + 1); + + return addressItem.getKey(); + } + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + String address = route(triggerParam.getJobId(), addressList); + return new ReturnT(address); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLRU.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLRU.java new file mode 100644 index 0000000..2d54006 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLRU.java @@ -0,0 +1,76 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * 单个JOB对应的每个执行器,最久为使用的优先被选举 + * a、LFU(Least Frequently Used):最不经常使用,频率/次数 + * b(*)、LRU(Least Recently Used):最近最久未使用,时间 + * + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteLRU extends ExecutorRouter { + + private static ConcurrentMap> jobLRUMap = new ConcurrentHashMap>(); + private static long CACHE_VALID_TIME = 0; + + public String route(int jobId, List addressList) { + + // cache clear + if (System.currentTimeMillis() > CACHE_VALID_TIME) { + jobLRUMap.clear(); + CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; + } + + // init lru + LinkedHashMap lruItem = jobLRUMap.get(jobId); + if (lruItem == null) { + /** + * LinkedHashMap + * a、accessOrder:true=访问顺序排序(get/put时排序);false=插入顺序排期; + * b、removeEldestEntry:新增元素时将会调用,返回true时会删除最老元素;可封装LinkedHashMap并重写该方法,比如定义最大容量,超出是返回true即可实现固定长度的LRU算法; + */ + lruItem = new LinkedHashMap(16, 0.75f, true); + jobLRUMap.putIfAbsent(jobId, lruItem); + } + + // put new + for (String address: addressList) { + if (!lruItem.containsKey(address)) { + lruItem.put(address, address); + } + } + // remove old + List delKeys = new ArrayList<>(); + for (String existKey: lruItem.keySet()) { + if (!addressList.contains(existKey)) { + delKeys.add(existKey); + } + } + if (delKeys.size() > 0) { + for (String delKey: delKeys) { + lruItem.remove(delKey); + } + } + + // load + String eldestKey = lruItem.entrySet().iterator().next().getKey(); + String eldestValue = lruItem.get(eldestKey); + return eldestValue; + } + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + String address = route(triggerParam.getJobId(), addressList); + return new ReturnT(address); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java new file mode 100644 index 0000000..4ff3cf6 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java @@ -0,0 +1,19 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteLast extends ExecutorRouter { + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + return new ReturnT(addressList.get(addressList.size()-1)); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java new file mode 100644 index 0000000..5ea4a38 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java @@ -0,0 +1,23 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; +import java.util.Random; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteRandom extends ExecutorRouter { + + private static Random localRandom = new Random(); + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + String address = addressList.get(localRandom.nextInt(addressList.size())); + return new ReturnT(address); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java new file mode 100644 index 0000000..d0ea2ba --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java @@ -0,0 +1,46 @@ +package com.xxl.job.admin.core.route.strategy; + +import com.xxl.job.admin.core.route.ExecutorRouter; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; + +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by xuxueli on 17/3/10. + */ +public class ExecutorRouteRound extends ExecutorRouter { + + private static ConcurrentMap routeCountEachJob = new ConcurrentHashMap<>(); + private static long CACHE_VALID_TIME = 0; + + private static int count(int jobId) { + // cache clear + if (System.currentTimeMillis() > CACHE_VALID_TIME) { + routeCountEachJob.clear(); + CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; + } + + AtomicInteger count = routeCountEachJob.get(jobId); + if (count == null || count.get() > 1000000) { + // 初始化时主动Random一次,缓解首次压力 + count = new AtomicInteger(new Random().nextInt(100)); + } else { + // count++ + count.addAndGet(1); + } + routeCountEachJob.put(jobId, count); + return count.get(); + } + + @Override + public ReturnT route(TriggerParam triggerParam, List addressList) { + String address = addressList.get(count(triggerParam.getJobId())%addressList.size()); + return new ReturnT(address); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/MisfireStrategyEnum.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/MisfireStrategyEnum.java new file mode 100644 index 0000000..0b9b4a9 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/MisfireStrategyEnum.java @@ -0,0 +1,39 @@ +package com.xxl.job.admin.core.scheduler; + +import com.xxl.job.admin.core.util.I18nUtil; + +/** + * @author xuxueli 2020-10-29 21:11:23 + */ +public enum MisfireStrategyEnum { + + /** + * do nothing + */ + DO_NOTHING(I18nUtil.getString("misfire_strategy_do_nothing")), + + /** + * fire once now + */ + FIRE_ONCE_NOW(I18nUtil.getString("misfire_strategy_fire_once_now")); + + private String title; + + MisfireStrategyEnum(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public static MisfireStrategyEnum match(String name, MisfireStrategyEnum defaultItem){ + for (MisfireStrategyEnum item: MisfireStrategyEnum.values()) { + if (item.name().equals(name)) { + return item; + } + } + return defaultItem; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/ScheduleTypeEnum.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/ScheduleTypeEnum.java new file mode 100644 index 0000000..aa334fd --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/ScheduleTypeEnum.java @@ -0,0 +1,46 @@ +package com.xxl.job.admin.core.scheduler; + +import com.xxl.job.admin.core.util.I18nUtil; + +/** + * @author xuxueli 2020-10-29 21:11:23 + */ +public enum ScheduleTypeEnum { + + NONE(I18nUtil.getString("schedule_type_none")), + + /** + * schedule by cron + */ + CRON(I18nUtil.getString("schedule_type_cron")), + + /** + * schedule by fixed rate (in seconds) + */ + FIX_RATE(I18nUtil.getString("schedule_type_fix_rate")), + + /** + * schedule by fix delay (in seconds), after the last time + */ + /*FIX_DELAY(I18nUtil.getString("schedule_type_fix_delay"))*/; + + private String title; + + ScheduleTypeEnum(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public static ScheduleTypeEnum match(String name, ScheduleTypeEnum defaultItem){ + for (ScheduleTypeEnum item: ScheduleTypeEnum.values()) { + if (item.name().equals(name)) { + return item; + } + } + return defaultItem; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java new file mode 100644 index 0000000..bb2cda8 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/scheduler/XxlJobScheduler.java @@ -0,0 +1,101 @@ +package com.xxl.job.admin.core.scheduler; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.thread.*; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.ExecutorBiz; +import com.xxl.job.core.biz.client.ExecutorBizClient; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author xuxueli 2018-10-28 00:18:17 + */ + +public class XxlJobScheduler { + private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class); + + + public void init() throws Exception { + // init i18n + initI18n(); + + // admin trigger pool start + JobTriggerPoolHelper.toStart(); + + // admin registry monitor run + JobRegistryHelper.getInstance().start(); + + // admin fail-monitor run + JobFailMonitorHelper.getInstance().start(); + + // admin lose-monitor run ( depend on JobTriggerPoolHelper ) + JobCompleteHelper.getInstance().start(); + + // admin log report start + JobLogReportHelper.getInstance().start(); + + // start-schedule ( depend on JobTriggerPoolHelper ) + JobScheduleHelper.getInstance().start(); + + logger.info(">>>>>>>>> init xxl-job admin success."); + } + + + public void destroy() throws Exception { + + // stop-schedule + JobScheduleHelper.getInstance().toStop(); + + // admin log report stop + JobLogReportHelper.getInstance().toStop(); + + // admin lose-monitor stop + JobCompleteHelper.getInstance().toStop(); + + // admin fail-monitor stop + JobFailMonitorHelper.getInstance().toStop(); + + // admin registry stop + JobRegistryHelper.getInstance().toStop(); + + // admin trigger pool stop + JobTriggerPoolHelper.toStop(); + + } + + // ---------------------- I18n ---------------------- + + private void initI18n(){ + for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) { + item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name()))); + } + } + + // ---------------------- executor-client ---------------------- + private static ConcurrentMap executorBizRepository = new ConcurrentHashMap(); + public static ExecutorBiz getExecutorBiz(String address) throws Exception { + // valid + if (address==null || address.trim().length()==0) { + return null; + } + + // load-cache + address = address.trim(); + ExecutorBiz executorBiz = executorBizRepository.get(address); + if (executorBiz != null) { + return executorBiz; + } + + // set-cache + executorBiz = new ExecutorBizClient(address, XxlJobAdminConfig.getAdminConfig().getAccessToken()); + + executorBizRepository.put(address, executorBiz); + return executorBiz; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobCompleteHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobCompleteHelper.java new file mode 100644 index 0000000..5698926 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobCompleteHelper.java @@ -0,0 +1,184 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.complete.XxlJobCompleter; +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.model.HandleCallbackParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.*; + +/** + * job lose-monitor instance + * + * @author xuxueli 2015-9-1 18:05:56 + */ +public class JobCompleteHelper { + private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class); + + private static JobCompleteHelper instance = new JobCompleteHelper(); + public static JobCompleteHelper getInstance(){ + return instance; + } + + // ---------------------- monitor ---------------------- + + private ThreadPoolExecutor callbackThreadPool = null; + private Thread monitorThread; + private volatile boolean toStop = false; + public void start(){ + + // for callback + callbackThreadPool = new ThreadPoolExecutor( + 2, + 20, + 30L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(3000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode()); + } + }, + new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + r.run(); + logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now)."); + } + }); + + + // for monitor + monitorThread = new Thread(new Runnable() { + + @Override + public void run() { + + // wait for JobTriggerPoolHelper-init + try { + TimeUnit.MILLISECONDS.sleep(50); + } catch (InterruptedException e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + // monitor + while (!toStop) { + try { + // 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败; + Date losedTime = DateUtil.addMinutes(new Date(), -10); + List losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime); + + if (losedJobIds!=null && losedJobIds.size()>0) { + for (Long logId: losedJobIds) { + + XxlJobLog jobLog = new XxlJobLog(); + jobLog.setId(logId); + + jobLog.setHandleTime(new Date()); + jobLog.setHandleCode(ReturnT.FAIL_CODE); + jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") ); + + XxlJobCompleter.updateHandleInfoAndFinish(jobLog); + } + + } + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); + } + } + + try { + TimeUnit.SECONDS.sleep(60); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop"); + + } + }); + monitorThread.setDaemon(true); + monitorThread.setName("xxl-job, admin JobLosedMonitorHelper"); + monitorThread.start(); + } + + public void toStop(){ + toStop = true; + + // stop registryOrRemoveThreadPool + callbackThreadPool.shutdownNow(); + + // stop monitorThread (interrupt and wait) + monitorThread.interrupt(); + try { + monitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + + // ---------------------- helper ---------------------- + + public ReturnT callback(List callbackParamList) { + + callbackThreadPool.execute(new Runnable() { + @Override + public void run() { + for (HandleCallbackParam handleCallbackParam: callbackParamList) { + ReturnT callbackResult = callback(handleCallbackParam); + logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}", + (callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult); + } + } + }); + + return ReturnT.SUCCESS; + } + + private ReturnT callback(HandleCallbackParam handleCallbackParam) { + // valid log item + XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId()); + if (log == null) { + return new ReturnT(ReturnT.FAIL_CODE, "log item not found."); + } + if (log.getHandleCode() > 0) { + return new ReturnT(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc + } + + // handle msg + StringBuffer handleMsg = new StringBuffer(); + if (log.getHandleMsg()!=null) { + handleMsg.append(log.getHandleMsg()).append("
"); + } + if (handleCallbackParam.getHandleMsg() != null) { + handleMsg.append(handleCallbackParam.getHandleMsg()); + } + + // success, save log + log.setHandleTime(new Date()); + log.setHandleCode(handleCallbackParam.getHandleCode()); + log.setHandleMsg(handleMsg.toString()); + XxlJobCompleter.updateHandleInfoAndFinish(log); + + return ReturnT.SUCCESS; + } + + + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java new file mode 100644 index 0000000..33e4d25 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java @@ -0,0 +1,110 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.util.I18nUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * job monitor instance + * + * @author xuxueli 2015-9-1 18:05:56 + */ +public class JobFailMonitorHelper { + private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class); + + private static JobFailMonitorHelper instance = new JobFailMonitorHelper(); + public static JobFailMonitorHelper getInstance(){ + return instance; + } + + // ---------------------- monitor ---------------------- + + private Thread monitorThread; + private volatile boolean toStop = false; + public void start(){ + monitorThread = new Thread(new Runnable() { + + @Override + public void run() { + + // monitor + while (!toStop) { + try { + + List failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000); + if (failLogIds!=null && !failLogIds.isEmpty()) { + for (long failLogId: failLogIds) { + + // lock log + int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1); + if (lockRet < 1) { + continue; + } + XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId); + XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId()); + + // 1、fail retry monitor + if (log.getExecutorFailRetryCount() > 0) { + JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam(), null); + String retryMsg = "

>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<<
"; + log.setTriggerMsg(log.getTriggerMsg() + retryMsg); + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log); + } + + // 2、fail alarm monitor + int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败 + if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) { + boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log); + newAlarmStatus = alarmResult?2:3; + } else { + newAlarmStatus = 1; + } + + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus); + } + } + + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); + } + } + + try { + TimeUnit.SECONDS.sleep(10); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop"); + + } + }); + monitorThread.setDaemon(true); + monitorThread.setName("xxl-job, admin JobFailMonitorHelper"); + monitorThread.start(); + } + + public void toStop(){ + toStop = true; + // interrupt and wait + monitorThread.interrupt(); + try { + monitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobLogReportHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobLogReportHelper.java new file mode 100644 index 0000000..2387a0c --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobLogReportHelper.java @@ -0,0 +1,152 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobLogReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * job log report helper + * + * @author xuxueli 2019-11-22 + */ +public class JobLogReportHelper { + private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class); + + private static JobLogReportHelper instance = new JobLogReportHelper(); + public static JobLogReportHelper getInstance(){ + return instance; + } + + + private Thread logrThread; + private volatile boolean toStop = false; + public void start(){ + logrThread = new Thread(new Runnable() { + + @Override + public void run() { + + // last clean log time + long lastCleanLogTime = 0; + + + while (!toStop) { + + // 1、log-report refresh: refresh log report in 3 days + try { + + for (int i = 0; i < 3; i++) { + + // today + Calendar itemDay = Calendar.getInstance(); + itemDay.add(Calendar.DAY_OF_MONTH, -i); + itemDay.set(Calendar.HOUR_OF_DAY, 0); + itemDay.set(Calendar.MINUTE, 0); + itemDay.set(Calendar.SECOND, 0); + itemDay.set(Calendar.MILLISECOND, 0); + + Date todayFrom = itemDay.getTime(); + + itemDay.set(Calendar.HOUR_OF_DAY, 23); + itemDay.set(Calendar.MINUTE, 59); + itemDay.set(Calendar.SECOND, 59); + itemDay.set(Calendar.MILLISECOND, 999); + + Date todayTo = itemDay.getTime(); + + // refresh log-report every minute + XxlJobLogReport xxlJobLogReport = new XxlJobLogReport(); + xxlJobLogReport.setTriggerDay(todayFrom); + xxlJobLogReport.setRunningCount(0); + xxlJobLogReport.setSucCount(0); + xxlJobLogReport.setFailCount(0); + + Map triggerCountMap = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLogReport(todayFrom, todayTo); + if (triggerCountMap!=null && triggerCountMap.size()>0) { + int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0; + int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0; + int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0; + int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; + + xxlJobLogReport.setRunningCount(triggerDayCountRunning); + xxlJobLogReport.setSucCount(triggerDayCountSuc); + xxlJobLogReport.setFailCount(triggerDayCountFail); + } + + // do refresh + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().update(xxlJobLogReport); + if (ret < 1) { + XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().save(xxlJobLogReport); + } + } + + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e); + } + } + + // 2、log-clean: switch open & once each day + if (XxlJobAdminConfig.getAdminConfig().getLogretentiondays()>0 + && System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000) { + + // expire-time + Calendar expiredDay = Calendar.getInstance(); + expiredDay.add(Calendar.DAY_OF_MONTH, -1 * XxlJobAdminConfig.getAdminConfig().getLogretentiondays()); + expiredDay.set(Calendar.HOUR_OF_DAY, 0); + expiredDay.set(Calendar.MINUTE, 0); + expiredDay.set(Calendar.SECOND, 0); + expiredDay.set(Calendar.MILLISECOND, 0); + Date clearBeforeTime = expiredDay.getTime(); + + // clean expired log + List logIds = null; + do { + logIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findClearLogIds(0, 0, clearBeforeTime, 0, 1000); + if (logIds!=null && logIds.size()>0) { + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().clearLog(logIds); + } + } while (logIds!=null && logIds.size()>0); + + // update clean time + lastCleanLogTime = System.currentTimeMillis(); + } + + try { + TimeUnit.MINUTES.sleep(1); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, job log report thread stop"); + + } + }); + logrThread.setDaemon(true); + logrThread.setName("xxl-job, admin JobLogReportHelper"); + logrThread.start(); + } + + public void toStop(){ + toStop = true; + // interrupt and wait + logrThread.interrupt(); + try { + logrThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryHelper.java new file mode 100644 index 0000000..37edfd9 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryHelper.java @@ -0,0 +1,204 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobRegistry; +import com.xxl.job.core.biz.model.RegistryParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.RegistryConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.concurrent.*; + +/** + * job registry instance + * @author xuxueli 2016-10-02 19:10:24 + */ +public class JobRegistryHelper { + private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class); + + private static JobRegistryHelper instance = new JobRegistryHelper(); + public static JobRegistryHelper getInstance(){ + return instance; + } + + private ThreadPoolExecutor registryOrRemoveThreadPool = null; + private Thread registryMonitorThread; + private volatile boolean toStop = false; + + public void start(){ + + // for registry or remove + registryOrRemoveThreadPool = new ThreadPoolExecutor( + 2, + 10, + 30L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(2000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode()); + } + }, + new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + r.run(); + logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now)."); + } + }); + + // for monitor + registryMonitorThread = new Thread(new Runnable() { + @Override + public void run() { + while (!toStop) { + try { + // auto registry group + List groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0); + if (groupList!=null && !groupList.isEmpty()) { + + // remove dead address (admin/executor) + List ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date()); + if (ids!=null && ids.size()>0) { + XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids); + } + + // fresh online address (admin/executor) + HashMap> appAddressMap = new HashMap>(); + List list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); + if (list != null) { + for (XxlJobRegistry item: list) { + if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { + String appname = item.getRegistryKey(); + List registryList = appAddressMap.get(appname); + if (registryList == null) { + registryList = new ArrayList(); + } + + if (!registryList.contains(item.getRegistryValue())) { + registryList.add(item.getRegistryValue()); + } + appAddressMap.put(appname, registryList); + } + } + } + + // fresh group address + for (XxlJobGroup group: groupList) { + List registryList = appAddressMap.get(group.getAppname()); + String addressListStr = null; + if (registryList!=null && !registryList.isEmpty()) { + Collections.sort(registryList); + StringBuilder addressListSB = new StringBuilder(); + for (String item:registryList) { + addressListSB.append(item).append(","); + } + addressListStr = addressListSB.toString(); + addressListStr = addressListStr.substring(0, addressListStr.length()-1); + } + group.setAddressList(addressListStr); + group.setUpdateTime(new Date()); + + XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group); + } + } + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); + } + } + try { + TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT); + } catch (InterruptedException e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); + } + } + } + logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop"); + } + }); + registryMonitorThread.setDaemon(true); + registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread"); + registryMonitorThread.start(); + } + + public void toStop(){ + toStop = true; + + // stop registryOrRemoveThreadPool + registryOrRemoveThreadPool.shutdownNow(); + + // stop monitir (interrupt and wait) + registryMonitorThread.interrupt(); + try { + registryMonitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + + // ---------------------- helper ---------------------- + + public ReturnT registry(RegistryParam registryParam) { + + // valid + if (!StringUtils.hasText(registryParam.getRegistryGroup()) + || !StringUtils.hasText(registryParam.getRegistryKey()) + || !StringUtils.hasText(registryParam.getRegistryValue())) { + return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument."); + } + + // async execute + registryOrRemoveThreadPool.execute(new Runnable() { + @Override + public void run() { + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); + if (ret < 1) { + XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); + + // fresh + freshGroupRegistryInfo(registryParam); + } + } + }); + + return ReturnT.SUCCESS; + } + + public ReturnT registryRemove(RegistryParam registryParam) { + + // valid + if (!StringUtils.hasText(registryParam.getRegistryGroup()) + || !StringUtils.hasText(registryParam.getRegistryKey()) + || !StringUtils.hasText(registryParam.getRegistryValue())) { + return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument."); + } + + // async execute + registryOrRemoveThreadPool.execute(new Runnable() { + @Override + public void run() { + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue()); + if (ret > 0) { + // fresh + freshGroupRegistryInfo(registryParam); + } + } + }); + + return ReturnT.SUCCESS; + } + + private void freshGroupRegistryInfo(RegistryParam registryParam){ + // Under consideration, prevent affecting core tables + } + + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java new file mode 100644 index 0000000..831bcf6 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java @@ -0,0 +1,369 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.cron.CronExpression; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; +import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +/** + * @author xuxueli 2019-05-21 + */ +public class JobScheduleHelper { + private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class); + + private static JobScheduleHelper instance = new JobScheduleHelper(); + public static JobScheduleHelper getInstance(){ + return instance; + } + + public static final long PRE_READ_MS = 5000; // pre read + + private Thread scheduleThread; + private Thread ringThread; + private volatile boolean scheduleThreadToStop = false; + private volatile boolean ringThreadToStop = false; + private volatile static Map> ringData = new ConcurrentHashMap<>(); + + public void start(){ + + // schedule thread + scheduleThread = new Thread(new Runnable() { + @Override + public void run() { + + try { + TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis()%1000 ); + } catch (InterruptedException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + logger.info(">>>>>>>>> init xxl-job admin scheduler success."); + + // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20) + int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20; + + while (!scheduleThreadToStop) { + + // Scan Job + long start = System.currentTimeMillis(); + + Connection conn = null; + Boolean connAutoCommit = null; + PreparedStatement preparedStatement = null; + + boolean preReadSuc = true; + try { + + conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection(); + connAutoCommit = conn.getAutoCommit(); + conn.setAutoCommit(false); + + preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" ); + preparedStatement.execute(); + + // tx start + + // 1、pre read + long nowTime = System.currentTimeMillis(); + List scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount); + if (scheduleList!=null && scheduleList.size()>0) { + // 2、push time-ring + for (XxlJobInfo jobInfo: scheduleList) { + + // time-ring jump + if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) { + // 2.1、trigger-expire > 5s:pass && make next-trigger-time + logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId()); + + // 1、misfire match + MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING); + if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) { + // FIRE_ONCE_NOW 》 trigger + JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null); + logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); + } + + // 2、fresh next + refreshNextValidTime(jobInfo, new Date()); + + } else if (nowTime > jobInfo.getTriggerNextTime()) { + // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time + + // 1、trigger + JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null, null); + logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); + + // 2、fresh next + refreshNextValidTime(jobInfo, new Date()); + + // next-trigger-time in 5s, pre-read again + if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) { + + // 1、make ring second + int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); + + // 2、push time ring + pushTimeRing(ringSecond, jobInfo.getId()); + + // 3、fresh next + refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); + + } + + } else { + // 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time + + // 1、make ring second + int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); + + // 2、push time ring + pushTimeRing(ringSecond, jobInfo.getId()); + + // 3、fresh next + refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); + + } + + } + + // 3、update trigger info + for (XxlJobInfo jobInfo: scheduleList) { + XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo); + } + + } else { + preReadSuc = false; + } + + // tx stop + + + } catch (Exception e) { + if (!scheduleThreadToStop) { + logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e); + } + } finally { + + // commit + if (conn != null) { + try { + conn.commit(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + try { + conn.setAutoCommit(connAutoCommit); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + try { + conn.close(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + + // close PreparedStatement + if (null != preparedStatement) { + try { + preparedStatement.close(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + } + long cost = System.currentTimeMillis()-start; + + + // Wait seconds, align second + if (cost < 1000) { // scan-overtime, not wait + try { + // pre-read period: success > scan each second; fail > skip this period; + TimeUnit.MILLISECONDS.sleep((preReadSuc?1000:PRE_READ_MS) - System.currentTimeMillis()%1000); + } catch (InterruptedException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop"); + } + }); + scheduleThread.setDaemon(true); + scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread"); + scheduleThread.start(); + + + // ring thread + ringThread = new Thread(new Runnable() { + @Override + public void run() { + + while (!ringThreadToStop) { + + // align second + try { + TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000); + } catch (InterruptedException e) { + if (!ringThreadToStop) { + logger.error(e.getMessage(), e); + } + } + + try { + // second data + List ringItemData = new ArrayList<>(); + int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验一个刻度; + for (int i = 0; i < 2; i++) { + List tmpData = ringData.remove( (nowSecond+60-i)%60 ); + if (tmpData != null) { + ringItemData.addAll(tmpData); + } + } + + // ring trigger + logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) ); + if (ringItemData.size() > 0) { + // do trigger + for (int jobId: ringItemData) { + // do trigger + JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null, null); + } + // clear + ringItemData.clear(); + } + } catch (Exception e) { + if (!ringThreadToStop) { + logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e); + } + } + } + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop"); + } + }); + ringThread.setDaemon(true); + ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread"); + ringThread.start(); + } + + private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { + Date nextValidTime = generateNextValidTime(jobInfo, fromTime); + if (nextValidTime != null) { + jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime()); + jobInfo.setTriggerNextTime(nextValidTime.getTime()); + } else { + jobInfo.setTriggerStatus(0); + jobInfo.setTriggerLastTime(0); + jobInfo.setTriggerNextTime(0); + logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}", + jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf()); + } + } + + private void pushTimeRing(int ringSecond, int jobId){ + // push async ring + List ringItemData = ringData.get(ringSecond); + if (ringItemData == null) { + ringItemData = new ArrayList(); + ringData.put(ringSecond, ringItemData); + } + ringItemData.add(jobId); + + logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) ); + } + + public void toStop(){ + + // 1、stop schedule + scheduleThreadToStop = true; + try { + TimeUnit.SECONDS.sleep(1); // wait + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + if (scheduleThread.getState() != Thread.State.TERMINATED){ + // interrupt and wait + scheduleThread.interrupt(); + try { + scheduleThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + // if has ring data + boolean hasRingData = false; + if (!ringData.isEmpty()) { + for (int second : ringData.keySet()) { + List tmpData = ringData.get(second); + if (tmpData!=null && tmpData.size()>0) { + hasRingData = true; + break; + } + } + } + if (hasRingData) { + try { + TimeUnit.SECONDS.sleep(8); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + // stop ring (wait job-in-memory stop) + ringThreadToStop = true; + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + if (ringThread.getState() != Thread.State.TERMINATED){ + // interrupt and wait + ringThread.interrupt(); + try { + ringThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper stop"); + } + + + // ---------------------- tools ---------------------- + public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); + if (ScheduleTypeEnum.CRON == scheduleTypeEnum) { + Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime); + return nextValidTime; + } else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) { + return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 ); + } + return null; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java new file mode 100644 index 0000000..398713d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java @@ -0,0 +1,150 @@ +package com.xxl.job.admin.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.trigger.XxlJobTrigger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * job trigger thread pool helper + * + * @author xuxueli 2018-07-03 21:08:07 + */ +public class JobTriggerPoolHelper { + private static Logger logger = LoggerFactory.getLogger(JobTriggerPoolHelper.class); + + + // ---------------------- trigger pool ---------------------- + + // fast/slow thread pool + private ThreadPoolExecutor fastTriggerPool = null; + private ThreadPoolExecutor slowTriggerPool = null; + + public void start(){ + fastTriggerPool = new ThreadPoolExecutor( + 10, + XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(), + 60L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(1000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode()); + } + }); + + slowTriggerPool = new ThreadPoolExecutor( + 10, + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(), + 60L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(2000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode()); + } + }); + } + + + public void stop() { + //triggerPool.shutdown(); + fastTriggerPool.shutdownNow(); + slowTriggerPool.shutdownNow(); + logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success."); + } + + + // job timeout count + private volatile long minTim = System.currentTimeMillis()/60000; // ms > min + private volatile ConcurrentMap jobTimeoutCountMap = new ConcurrentHashMap<>(); + + + /** + * add trigger + */ + public void addTrigger(final int jobId, + final TriggerTypeEnum triggerType, + final int failRetryCount, + final String executorShardingParam, + final String executorParam, + final String addressList) { + + // choose thread pool + ThreadPoolExecutor triggerPool_ = fastTriggerPool; + AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId); + if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min + triggerPool_ = slowTriggerPool; + } + + // trigger + triggerPool_.execute(new Runnable() { + @Override + public void run() { + + long start = System.currentTimeMillis(); + + try { + // do trigger + XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + + // check timeout-count-map + long minTim_now = System.currentTimeMillis()/60000; + if (minTim != minTim_now) { + minTim = minTim_now; + jobTimeoutCountMap.clear(); + } + + // incr timeout-count-map + long cost = System.currentTimeMillis()-start; + if (cost > 500) { // ob-timeout threshold 500ms + AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1)); + if (timeoutCount != null) { + timeoutCount.incrementAndGet(); + } + } + + } + + } + }); + } + + + + // ---------------------- helper ---------------------- + + private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper(); + + public static void toStart() { + helper.start(); + } + public static void toStop() { + helper.stop(); + } + + /** + * @param jobId + * @param triggerType + * @param failRetryCount + * >=0: use this param + * <0: use param from job info config + * @param executorShardingParam + * @param executorParam + * null: use job param + * not null: cover job param + */ + public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) { + helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/TriggerTypeEnum.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/TriggerTypeEnum.java new file mode 100644 index 0000000..446c90e --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/TriggerTypeEnum.java @@ -0,0 +1,27 @@ +package com.xxl.job.admin.core.trigger; + +import com.xxl.job.admin.core.util.I18nUtil; + +/** + * trigger type enum + * + * @author xuxueli 2018-09-16 04:56:41 + */ +public enum TriggerTypeEnum { + + MANUAL(I18nUtil.getString("jobconf_trigger_type_manual")), + CRON(I18nUtil.getString("jobconf_trigger_type_cron")), + RETRY(I18nUtil.getString("jobconf_trigger_type_retry")), + PARENT(I18nUtil.getString("jobconf_trigger_type_parent")), + API(I18nUtil.getString("jobconf_trigger_type_api")), + MISFIRE(I18nUtil.getString("jobconf_trigger_type_misfire")); + + private TriggerTypeEnum(String title){ + this.title = title; + } + private String title; + public String getTitle() { + return title; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java new file mode 100644 index 0000000..748befc --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java @@ -0,0 +1,226 @@ +package com.xxl.job.admin.core.trigger; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; +import com.xxl.job.admin.core.scheduler.XxlJobScheduler; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.ExecutorBiz; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.biz.model.TriggerParam; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.util.IpUtil; +import com.xxl.job.core.util.ThrowableUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; + +/** + * xxl-job trigger + * Created by xuxueli on 17/7/13. + */ +public class XxlJobTrigger { + private static Logger logger = LoggerFactory.getLogger(XxlJobTrigger.class); + + /** + * trigger job + * + * @param jobId + * @param triggerType + * @param failRetryCount + * >=0: use this param + * <0: use param from job info config + * @param executorShardingParam + * @param executorParam + * null: use job param + * not null: cover job param + * @param addressList + * null: use executor addressList + * not null: cover + */ + public static void trigger(int jobId, + TriggerTypeEnum triggerType, + int failRetryCount, + String executorShardingParam, + String executorParam, + String addressList) { + + // load data + XxlJobInfo jobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(jobId); + if (jobInfo == null) { + logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId); + return; + } + if (executorParam != null) { + jobInfo.setExecutorParam(executorParam); + } + int finalFailRetryCount = failRetryCount>=0?failRetryCount:jobInfo.getExecutorFailRetryCount(); + XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(jobInfo.getJobGroup()); + + // cover addressList + if (addressList!=null && addressList.trim().length()>0) { + group.setAddressType(1); + group.setAddressList(addressList.trim()); + } + + // sharding param + int[] shardingParam = null; + if (executorShardingParam!=null){ + String[] shardingArr = executorShardingParam.split("/"); + if (shardingArr.length==2 && isNumeric(shardingArr[0]) && isNumeric(shardingArr[1])) { + shardingParam = new int[2]; + shardingParam[0] = Integer.valueOf(shardingArr[0]); + shardingParam[1] = Integer.valueOf(shardingArr[1]); + } + } + if (ExecutorRouteStrategyEnum.SHARDING_BROADCAST==ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) + && group.getRegistryList()!=null && !group.getRegistryList().isEmpty() + && shardingParam==null) { + for (int i = 0; i < group.getRegistryList().size(); i++) { + processTrigger(group, jobInfo, finalFailRetryCount, triggerType, i, group.getRegistryList().size()); + } + } else { + if (shardingParam == null) { + shardingParam = new int[]{0, 1}; + } + processTrigger(group, jobInfo, finalFailRetryCount, triggerType, shardingParam[0], shardingParam[1]); + } + + } + + private static boolean isNumeric(String str){ + try { + int result = Integer.valueOf(str); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * @param group job group, registry list may be empty + * @param jobInfo + * @param finalFailRetryCount + * @param triggerType + * @param index sharding index + * @param total sharding index + */ + private static void processTrigger(XxlJobGroup group, XxlJobInfo jobInfo, int finalFailRetryCount, TriggerTypeEnum triggerType, int index, int total){ + + // param + ExecutorBlockStrategyEnum blockStrategy = ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), ExecutorBlockStrategyEnum.SERIAL_EXECUTION); // block strategy + ExecutorRouteStrategyEnum executorRouteStrategyEnum = ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null); // route strategy + String shardingParam = (ExecutorRouteStrategyEnum.SHARDING_BROADCAST==executorRouteStrategyEnum)?String.valueOf(index).concat("/").concat(String.valueOf(total)):null; + + // 1、save log-id + XxlJobLog jobLog = new XxlJobLog(); + jobLog.setJobGroup(jobInfo.getJobGroup()); + jobLog.setJobId(jobInfo.getId()); + jobLog.setTriggerTime(new Date()); + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().save(jobLog); + logger.debug(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId()); + + // 2、init trigger-param + TriggerParam triggerParam = new TriggerParam(); + triggerParam.setJobId(jobInfo.getId()); + triggerParam.setExecutorHandler(jobInfo.getExecutorHandler()); + triggerParam.setExecutorParams(jobInfo.getExecutorParam()); + triggerParam.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy()); + triggerParam.setExecutorTimeout(jobInfo.getExecutorTimeout()); + triggerParam.setLogId(jobLog.getId()); + triggerParam.setLogDateTime(jobLog.getTriggerTime().getTime()); + triggerParam.setGlueType(jobInfo.getGlueType()); + triggerParam.setGlueSource(jobInfo.getGlueSource()); + triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime()); + triggerParam.setBroadcastIndex(index); + triggerParam.setBroadcastTotal(total); + + // 3、init address + String address = null; + ReturnT routeAddressResult = null; + if (group.getRegistryList()!=null && !group.getRegistryList().isEmpty()) { + if (ExecutorRouteStrategyEnum.SHARDING_BROADCAST == executorRouteStrategyEnum) { + if (index < group.getRegistryList().size()) { + address = group.getRegistryList().get(index); + } else { + address = group.getRegistryList().get(0); + } + } else { + routeAddressResult = executorRouteStrategyEnum.getRouter().route(triggerParam, group.getRegistryList()); + if (routeAddressResult.getCode() == ReturnT.SUCCESS_CODE) { + address = routeAddressResult.getContent(); + } + } + } else { + routeAddressResult = new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobconf_trigger_address_empty")); + } + + // 4、trigger remote executor + ReturnT triggerResult = null; + if (address != null) { + triggerResult = runExecutor(triggerParam, address); + } else { + triggerResult = new ReturnT(ReturnT.FAIL_CODE, null); + } + + // 5、collection trigger info + StringBuffer triggerMsgSb = new StringBuffer(); + triggerMsgSb.append(I18nUtil.getString("jobconf_trigger_type")).append(":").append(triggerType.getTitle()); + triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_admin_adress")).append(":").append(IpUtil.getIp()); + triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_exe_regtype")).append(":") + .append( (group.getAddressType() == 0)?I18nUtil.getString("jobgroup_field_addressType_0"):I18nUtil.getString("jobgroup_field_addressType_1") ); + triggerMsgSb.append("
").append(I18nUtil.getString("jobconf_trigger_exe_regaddress")).append(":").append(group.getRegistryList()); + triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorRouteStrategy")).append(":").append(executorRouteStrategyEnum.getTitle()); + if (shardingParam != null) { + triggerMsgSb.append("("+shardingParam+")"); + } + triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorBlockStrategy")).append(":").append(blockStrategy.getTitle()); + triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_timeout")).append(":").append(jobInfo.getExecutorTimeout()); + triggerMsgSb.append("
").append(I18nUtil.getString("jobinfo_field_executorFailRetryCount")).append(":").append(finalFailRetryCount); + + triggerMsgSb.append("

>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_run") +"<<<<<<<<<<<
") + .append((routeAddressResult!=null&&routeAddressResult.getMsg()!=null)?routeAddressResult.getMsg()+"

":"").append(triggerResult.getMsg()!=null?triggerResult.getMsg():""); + + // 6、save log trigger-info + jobLog.setExecutorAddress(address); + jobLog.setExecutorHandler(jobInfo.getExecutorHandler()); + jobLog.setExecutorParam(jobInfo.getExecutorParam()); + jobLog.setExecutorShardingParam(shardingParam); + jobLog.setExecutorFailRetryCount(finalFailRetryCount); + //jobLog.setTriggerTime(); + jobLog.setTriggerCode(triggerResult.getCode()); + jobLog.setTriggerMsg(triggerMsgSb.toString()); + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(jobLog); + + logger.debug(">>>>>>>>>>> xxl-job trigger end, jobId:{}", jobLog.getId()); + } + + /** + * run executor + * @param triggerParam + * @param address + * @return + */ + public static ReturnT runExecutor(TriggerParam triggerParam, String address){ + ReturnT runResult = null; + try { + ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); + runResult = executorBiz.run(triggerParam); + } catch (Exception e) { + logger.error(">>>>>>>>>>> xxl-job trigger error, please check if the executor[{}] is running.", address, e); + runResult = new ReturnT(ReturnT.FAIL_CODE, ThrowableUtil.toString(e)); + } + + StringBuffer runResultSB = new StringBuffer(I18nUtil.getString("jobconf_trigger_run") + ":"); + runResultSB.append("
address:").append(address); + runResultSB.append("
code:").append(runResult.getCode()); + runResultSB.append("
msg:").append(runResult.getMsg()); + + runResult.setMsg(runResultSB.toString()); + return runResult; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/CookieUtil.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/CookieUtil.java new file mode 100644 index 0000000..a1523aa --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/CookieUtil.java @@ -0,0 +1,98 @@ +package com.xxl.job.admin.core.util; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Cookie.Util + * + * @author xuxueli 2015-12-12 18:01:06 + */ +public class CookieUtil { + + // 默认缓存时间,单位/秒, 2H + private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE; + // 保存路径,根路径 + private static final String COOKIE_PATH = "/"; + + /** + * 保存 + * + * @param response + * @param key + * @param value + * @param ifRemember + */ + public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) { + int age = ifRemember?COOKIE_MAX_AGE:-1; + set(response, key, value, null, COOKIE_PATH, age, true); + } + + /** + * 保存 + * + * @param response + * @param key + * @param value + * @param maxAge + */ + private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) { + Cookie cookie = new Cookie(key, value); + if (domain != null) { + cookie.setDomain(domain); + } + cookie.setPath(path); + cookie.setMaxAge(maxAge); + cookie.setHttpOnly(isHttpOnly); + response.addCookie(cookie); + } + + /** + * 查询value + * + * @param request + * @param key + * @return + */ + public static String getValue(HttpServletRequest request, String key) { + Cookie cookie = get(request, key); + if (cookie != null) { + return cookie.getValue(); + } + return null; + } + + /** + * 查询Cookie + * + * @param request + * @param key + */ + private static Cookie get(HttpServletRequest request, String key) { + Cookie[] arr_cookie = request.getCookies(); + if (arr_cookie != null && arr_cookie.length > 0) { + for (Cookie cookie : arr_cookie) { + if (cookie.getName().equals(key)) { + return cookie; + } + } + } + return null; + } + + /** + * 删除Cookie + * + * @param request + * @param response + * @param key + */ + public static void remove(HttpServletRequest request, HttpServletResponse response, String key) { + Cookie cookie = get(request, key); + if (cookie != null) { + set(response, key, "", null, COOKIE_PATH, 0, true); + } + } + +} \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/FtlUtil.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/FtlUtil.java new file mode 100644 index 0000000..e90af43 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/FtlUtil.java @@ -0,0 +1,31 @@ +package com.xxl.job.admin.core.util; + +import freemarker.ext.beans.BeansWrapper; +import freemarker.ext.beans.BeansWrapperBuilder; +import freemarker.template.Configuration; +import freemarker.template.TemplateHashModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * ftl util + * + * @author xuxueli 2018-01-17 20:37:48 + */ +public class FtlUtil { + private static Logger logger = LoggerFactory.getLogger(FtlUtil.class); + + private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); //BeansWrapper.getDefaultInstance(); + + public static TemplateHashModel generateStaticModel(String packageName) { + try { + TemplateHashModel staticModels = wrapper.getStaticModels(); + TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName); + return fileStatics; + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/I18nUtil.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/I18nUtil.java new file mode 100644 index 0000000..772a96e --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/I18nUtil.java @@ -0,0 +1,79 @@ +package com.xxl.job.admin.core.util; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertiesLoaderUtils; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * i18n util + * + * @author xuxueli 2018-01-17 20:39:06 + */ +public class I18nUtil { + private static Logger logger = LoggerFactory.getLogger(I18nUtil.class); + + private static Properties prop = null; + public static Properties loadI18nProp(){ + if (prop != null) { + return prop; + } + try { + // build i18n prop + String i18n = XxlJobAdminConfig.getAdminConfig().getI18n(); + String i18nFile = MessageFormat.format("i18n/message_{0}.properties", i18n); + + // load prop + Resource resource = new ClassPathResource(i18nFile); + EncodedResource encodedResource = new EncodedResource(resource,"UTF-8"); + prop = PropertiesLoaderUtils.loadProperties(encodedResource); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return prop; + } + + /** + * get val of i18n key + * + * @param key + * @return + */ + public static String getString(String key) { + return loadI18nProp().getProperty(key); + } + + /** + * get mult val of i18n mult key, as json + * + * @param keys + * @return + */ + public static String getMultString(String... keys) { + Map map = new HashMap(); + + Properties prop = loadI18nProp(); + if (keys!=null && keys.length>0) { + for (String key: keys) { + map.put(key, prop.getProperty(key)); + } + } else { + for (String key: prop.stringPropertyNames()) { + map.put(key, prop.getProperty(key)); + } + } + + String json = JacksonUtil.writeValueAsString(map); + return json; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JacksonUtil.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JacksonUtil.java new file mode 100644 index 0000000..4f4ea3c --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JacksonUtil.java @@ -0,0 +1,92 @@ +package com.xxl.job.admin.core.util; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * Jackson util + * + * 1、obj need private and set/get; + * 2、do not support inner class; + * + * @author xuxueli 2015-9-25 18:02:56 + */ +public class JacksonUtil { + private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class); + + private final static ObjectMapper objectMapper = new ObjectMapper(); + public static ObjectMapper getInstance() { + return objectMapper; + } + + /** + * bean、array、List、Map --> json + * + * @param obj + * @return json string + * @throws Exception + */ + public static String writeValueAsString(Object obj) { + try { + return getInstance().writeValueAsString(obj); + } catch (JsonGenerationException e) { + logger.error(e.getMessage(), e); + } catch (JsonMappingException e) { + logger.error(e.getMessage(), e); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * string --> bean、Map、List(array) + * + * @param jsonStr + * @param clazz + * @return obj + * @throws Exception + */ + public static T readValue(String jsonStr, Class clazz) { + try { + return getInstance().readValue(jsonStr, clazz); + } catch (JsonParseException e) { + logger.error(e.getMessage(), e); + } catch (JsonMappingException e) { + logger.error(e.getMessage(), e); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return null; + } + + /** + * string --> List... + * + * @param jsonStr + * @param parametrized + * @param parameterClasses + * @param + * @return + */ + public static T readValue(String jsonStr, Class parametrized, Class... parameterClasses) { + try { + JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses); + return getInstance().readValue(jsonStr, javaType); + } catch (JsonParseException e) { + logger.error(e.getMessage(), e); + } catch (JsonMappingException e) { + logger.error(e.getMessage(), e); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return null; + } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/LocalCacheUtil.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/LocalCacheUtil.java new file mode 100644 index 0000000..fbab061 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/LocalCacheUtil.java @@ -0,0 +1,133 @@ +package com.xxl.job.admin.core.util; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * local cache tool + * + * @author xuxueli 2018-01-22 21:37:34 + */ +public class LocalCacheUtil { + + private static ConcurrentMap cacheRepository = new ConcurrentHashMap(); // 类型建议用抽象父类,兼容性更好; + private static class LocalCacheData{ + private String key; + private Object val; + private long timeoutTime; + + public LocalCacheData() { + } + + public LocalCacheData(String key, Object val, long timeoutTime) { + this.key = key; + this.val = val; + this.timeoutTime = timeoutTime; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getVal() { + return val; + } + + public void setVal(Object val) { + this.val = val; + } + + public long getTimeoutTime() { + return timeoutTime; + } + + public void setTimeoutTime(long timeoutTime) { + this.timeoutTime = timeoutTime; + } + } + + + /** + * set cache + * + * @param key + * @param val + * @param cacheTime + * @return + */ + public static boolean set(String key, Object val, long cacheTime){ + + // clean timeout cache, before set new cache (avoid cache too much) + cleanTimeoutCache(); + + // set new cache + if (key==null || key.trim().length()==0) { + return false; + } + if (val == null) { + remove(key); + } + if (cacheTime <= 0) { + remove(key); + } + long timeoutTime = System.currentTimeMillis() + cacheTime; + LocalCacheData localCacheData = new LocalCacheData(key, val, timeoutTime); + cacheRepository.put(localCacheData.getKey(), localCacheData); + return true; + } + + /** + * remove cache + * + * @param key + * @return + */ + public static boolean remove(String key){ + if (key==null || key.trim().length()==0) { + return false; + } + cacheRepository.remove(key); + return true; + } + + /** + * get cache + * + * @param key + * @return + */ + public static Object get(String key){ + if (key==null || key.trim().length()==0) { + return null; + } + LocalCacheData localCacheData = cacheRepository.get(key); + if (localCacheData!=null && System.currentTimeMillis()=localCacheData.getTimeoutTime()) { + cacheRepository.remove(key); + } + } + } + return true; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java new file mode 100644 index 0000000..9051500 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java @@ -0,0 +1,38 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobGroup; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * Created by xuxueli on 16/9/30. + */ +@Mapper +public interface XxlJobGroupDao { + + public List findAll(); + + public List findByAddressType(@Param("addressType") int addressType); + + public int save(XxlJobGroup xxlJobGroup); + + public int update(XxlJobGroup xxlJobGroup); + + public int remove(@Param("id") int id); + + public XxlJobGroup load(@Param("id") int id); + + public List pageList(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("appname") String appname, + @Param("title") String title); + + public int pageListCount(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("appname") String appname, + @Param("title") String title); + + XxlJobGroup findByName(@Param("appname") String appname); +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java new file mode 100644 index 0000000..43c7920 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java @@ -0,0 +1,53 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + +/** + * job info + * + * @author xuxueli 2016-1-12 18:03:45 + */ +@Mapper +public interface XxlJobInfoDao { + + public List pageList(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("jobGroup") int jobGroup, + @Param("triggerStatus") int triggerStatus, + @Param("jobDesc") String jobDesc, + @Param("executorHandler") String executorHandler, + @Param("author") String author); + + public int pageListCount(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("jobGroup") int jobGroup, + @Param("triggerStatus") int triggerStatus, + @Param("jobDesc") String jobDesc, + @Param("executorHandler") String executorHandler, + @Param("author") String author); + + public int save(XxlJobInfo info); + + public XxlJobInfo loadById(@Param("id") int id); + + public int update(XxlJobInfo xxlJobInfo); + + public int delete(@Param("id") long id); + + public List getJobsByGroup(@Param("jobGroup") int jobGroup); + + public int findAllCount(); + + public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize); + + public int scheduleUpdate(XxlJobInfo xxlJobInfo); + + int deleteByObjectId(@Param("objectId") String objectId); + + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogDao.java new file mode 100644 index 0000000..62fa3b4 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogDao.java @@ -0,0 +1,62 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobLog; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * job log + * @author xuxueli 2016-1-12 18:03:06 + */ +@Mapper +public interface XxlJobLogDao { + + // exist jobId not use jobGroup, not exist use jobGroup + public List pageList(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("jobGroup") int jobGroup, + @Param("jobId") int jobId, + @Param("triggerTimeStart") Date triggerTimeStart, + @Param("triggerTimeEnd") Date triggerTimeEnd, + @Param("logStatus") int logStatus); + public int pageListCount(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("jobGroup") int jobGroup, + @Param("jobId") int jobId, + @Param("triggerTimeStart") Date triggerTimeStart, + @Param("triggerTimeEnd") Date triggerTimeEnd, + @Param("logStatus") int logStatus); + + public XxlJobLog load(@Param("id") long id); + + public long save(XxlJobLog xxlJobLog); + + public int updateTriggerInfo(XxlJobLog xxlJobLog); + + public int updateHandleInfo(XxlJobLog xxlJobLog); + + public int delete(@Param("jobId") int jobId); + + public Map findLogReport(@Param("from") Date from, + @Param("to") Date to); + + public List findClearLogIds(@Param("jobGroup") int jobGroup, + @Param("jobId") int jobId, + @Param("clearBeforeTime") Date clearBeforeTime, + @Param("clearBeforeNum") int clearBeforeNum, + @Param("pagesize") int pagesize); + public int clearLog(@Param("logIds") List logIds); + + public List findFailJobLogIds(@Param("pagesize") int pagesize); + + public int updateAlarmStatus(@Param("logId") long logId, + @Param("oldAlarmStatus") int oldAlarmStatus, + @Param("newAlarmStatus") int newAlarmStatus); + + public List findLostJobIds(@Param("losedTime") Date losedTime); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogGlueDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogGlueDao.java new file mode 100644 index 0000000..3028aed --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogGlueDao.java @@ -0,0 +1,24 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobLogGlue; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * job log for glue + * @author xuxueli 2016-5-19 18:04:56 + */ +@Mapper +public interface XxlJobLogGlueDao { + + public int save(XxlJobLogGlue xxlJobLogGlue); + + public List findByJobId(@Param("jobId") int jobId); + + public int removeOld(@Param("jobId") int jobId, @Param("limit") int limit); + + public int deleteByJobId(@Param("jobId") int jobId); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogReportDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogReportDao.java new file mode 100644 index 0000000..f4b3dc8 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogReportDao.java @@ -0,0 +1,26 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobLogReport; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * job log + * @author xuxueli 2019-11-22 + */ +@Mapper +public interface XxlJobLogReportDao { + + public int save(XxlJobLogReport xxlJobLogReport); + + public int update(XxlJobLogReport xxlJobLogReport); + + public List queryLogReport(@Param("triggerDayFrom") Date triggerDayFrom, + @Param("triggerDayTo") Date triggerDayTo); + + public XxlJobLogReport queryLogReportTotal(); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java new file mode 100644 index 0000000..1005c46 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java @@ -0,0 +1,38 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobRegistry; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; + +/** + * Created by xuxueli on 16/9/30. + */ +@Mapper +public interface XxlJobRegistryDao { + + public List findDead(@Param("timeout") int timeout, + @Param("nowTime") Date nowTime); + + public int removeDead(@Param("ids") List ids); + + public List findAll(@Param("timeout") int timeout, + @Param("nowTime") Date nowTime); + + public int registryUpdate(@Param("registryGroup") String registryGroup, + @Param("registryKey") String registryKey, + @Param("registryValue") String registryValue, + @Param("updateTime") Date updateTime); + + public int registrySave(@Param("registryGroup") String registryGroup, + @Param("registryKey") String registryKey, + @Param("registryValue") String registryValue, + @Param("updateTime") Date updateTime); + + public int registryDelete(@Param("registryGroup") String registryGroup, + @Param("registryKey") String registryKey, + @Param("registryValue") String registryValue); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobUserDao.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobUserDao.java new file mode 100644 index 0000000..e840494 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobUserDao.java @@ -0,0 +1,31 @@ +package com.xxl.job.admin.dao; + +import com.xxl.job.admin.core.model.XxlJobUser; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * @author xuxueli 2019-05-04 16:44:59 + */ +@Mapper +public interface XxlJobUserDao { + + public List pageList(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("username") String username, + @Param("role") int role); + public int pageListCount(@Param("offset") int offset, + @Param("pagesize") int pagesize, + @Param("username") String username, + @Param("role") int role); + + public XxlJobUser loadByUserName(@Param("username") String username); + + public int save(XxlJobUser xxlJobUser); + + public int update(XxlJobUser xxlJobUser); + + public int delete(@Param("id") int id); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/LoginService.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/LoginService.java new file mode 100644 index 0000000..e1cf2e4 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/LoginService.java @@ -0,0 +1,107 @@ +package com.xxl.job.admin.service; + +import com.xxl.job.admin.core.model.XxlJobUser; +import com.xxl.job.admin.core.util.CookieUtil; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.core.util.JacksonUtil; +import com.xxl.job.admin.dao.XxlJobUserDao; +import com.xxl.job.core.biz.model.ReturnT; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.DigestUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.BigInteger; + +/** + * @author xuxueli 2019-05-04 22:13:264 + */ +@Configuration +public class LoginService { + + public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY"; + + @Resource + private XxlJobUserDao xxlJobUserDao; + + + private String makeToken(XxlJobUser xxlJobUser){ + String tokenJson = JacksonUtil.writeValueAsString(xxlJobUser); + String tokenHex = new BigInteger(tokenJson.getBytes()).toString(16); + return tokenHex; + } + private XxlJobUser parseToken(String tokenHex){ + XxlJobUser xxlJobUser = null; + if (tokenHex != null) { + String tokenJson = new String(new BigInteger(tokenHex, 16).toByteArray()); // username_password(md5) + xxlJobUser = JacksonUtil.readValue(tokenJson, XxlJobUser.class); + } + return xxlJobUser; + } + + + public ReturnT login(HttpServletRequest request, HttpServletResponse response, String username, String password, boolean ifRemember){ + + // param + if (username==null || username.trim().length()==0 || password==null || password.trim().length()==0){ + return new ReturnT(500, I18nUtil.getString("login_param_empty")); + } + + // valid passowrd + XxlJobUser xxlJobUser = xxlJobUserDao.loadByUserName(username); + if (xxlJobUser == null) { + return new ReturnT(500, I18nUtil.getString("login_param_unvalid")); + } + String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes()); + if (!passwordMd5.equals(xxlJobUser.getPassword())) { + return new ReturnT(500, I18nUtil.getString("login_param_unvalid")); + } + + String loginToken = makeToken(xxlJobUser); + + // do login + CookieUtil.set(response, LOGIN_IDENTITY_KEY, loginToken, ifRemember); + return ReturnT.SUCCESS; + } + + /** + * logout + * + * @param request + * @param response + */ + public ReturnT logout(HttpServletRequest request, HttpServletResponse response){ + CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY); + return ReturnT.SUCCESS; + } + + /** + * logout + * + * @param request + * @return + */ + public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response){ + String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY); + if (cookieToken != null) { + XxlJobUser cookieUser = null; + try { + cookieUser = parseToken(cookieToken); + } catch (Exception e) { + logout(request, response); + } + if (cookieUser != null) { + XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername()); + if (dbUser != null) { + if (cookieUser.getPassword().equals(dbUser.getPassword())) { + return dbUser; + } + } + } + } + return null; + } + + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java new file mode 100644 index 0000000..d40a2c4 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java @@ -0,0 +1,88 @@ +package com.xxl.job.admin.service; + + +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.core.biz.model.ReturnT; + +import java.util.Date; +import java.util.Map; + +/** + * core job action for xxl-job + * + * @author xuxueli 2016-5-28 15:30:33 + */ +public interface XxlJobService { + + /** + * page list + * + * @param start + * @param length + * @param jobGroup + * @param jobDesc + * @param executorHandler + * @param author + * @return + */ + public Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author); + + /** + * add job + * + * @param jobInfo + * @return + */ + public ReturnT add(XxlJobInfo jobInfo); + + /** + * update job + * + * @param jobInfo + * @return + */ + public ReturnT update(XxlJobInfo jobInfo); + + /** + * remove job + * * + * @param id + * @return + */ + public ReturnT remove(int id); + + /** + * start job + * + * @param id + * @return + */ + public ReturnT start(int id); + + /** + * stop job + * + * @param id + * @return + */ + public ReturnT stop(int id); + + /** + * dashboard info + * + * @return + */ + public Map dashboardInfo(); + + /** + * chart info + * + * @param startDate + * @param endDate + * @return + */ + public ReturnT> chartInfo(Date startDate, Date endDate); + + ReturnT deleteByObjectId(String objectId); + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java new file mode 100644 index 0000000..3c01e94 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AdminBizImpl.java @@ -0,0 +1,35 @@ +package com.xxl.job.admin.service.impl; + +import com.xxl.job.admin.core.thread.JobCompleteHelper; +import com.xxl.job.admin.core.thread.JobRegistryHelper; +import com.xxl.job.core.biz.AdminBiz; +import com.xxl.job.core.biz.model.HandleCallbackParam; +import com.xxl.job.core.biz.model.RegistryParam; +import com.xxl.job.core.biz.model.ReturnT; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author xuxueli 2017-07-27 21:54:20 + */ +@Service +public class AdminBizImpl implements AdminBiz { + + + @Override + public ReturnT callback(List callbackParamList) { + return JobCompleteHelper.getInstance().callback(callbackParamList); + } + + @Override + public ReturnT registry(RegistryParam registryParam) { + return JobRegistryHelper.getInstance().registry(registryParam); + } + + @Override + public ReturnT registryRemove(RegistryParam registryParam) { + return JobRegistryHelper.getInstance().registryRemove(registryParam); + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java new file mode 100644 index 0000000..7a52c07 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java @@ -0,0 +1,441 @@ +package com.xxl.job.admin.service.impl; + +import com.xxl.job.admin.core.cron.CronExpression; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLogReport; +import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; +import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; +import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum; +import com.xxl.job.admin.core.thread.JobScheduleHelper; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.*; +import com.xxl.job.admin.service.XxlJobService; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.glue.GlueTypeEnum; +import com.xxl.job.core.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.MessageFormat; +import java.util.*; + +/** + * core job action for xxl-job + * + * @author xuxueli 2016-5-28 15:30:33 + */ +@Service +public class XxlJobServiceImpl implements XxlJobService { + private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class); + + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobInfoDao xxlJobInfoDao; + @Resource + public XxlJobLogDao xxlJobLogDao; + @Resource + private XxlJobLogGlueDao xxlJobLogGlueDao; + @Resource + private XxlJobLogReportDao xxlJobLogReportDao; + + @Override + public Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { + + // page list + List list = xxlJobInfoDao.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + + @Override + public ReturnT add(XxlJobInfo jobInfo) { + + // valid base + XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); + if (group == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose") + I18nUtil.getString("jobinfo_field_jobgroup"))); + } + if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc"))); + } + if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author"))); + } + + // valid trigger + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); + if (scheduleTypeEnum == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + if (scheduleTypeEnum == ScheduleTypeEnum.CRON) { + if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) { + return new ReturnT(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid")); + } + } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) { + if (jobInfo.getScheduleConf() == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type"))); + } + try { + int fixSecond = Integer.valueOf(jobInfo.getScheduleConf()); + if (fixSecond < 1) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + } catch (Exception e) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + } + + // valid job + if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype") + I18nUtil.getString("system_unvalid"))); + } + if (GlueTypeEnum.BEAN == GlueTypeEnum.match(jobInfo.getGlueType()) && (jobInfo.getExecutorHandler() == null || jobInfo.getExecutorHandler().trim().length() == 0)) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + "JobHandler")); + } + // 》fix "\r" in shell + if (GlueTypeEnum.GLUE_SHELL == GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource() != null) { + jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); + } + + // valid advanced + if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid"))); + } + if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid"))); + } + if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid"))); + } + + // 》ChildJobId valid + if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) { + String[] childJobIds = jobInfo.getChildJobId().split(","); + for (String childJobIdItem : childJobIds) { + if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) { + XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem)); + if (childJobInfo == null) { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem)); + } + } else { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem)); + } + } + + // join , avoid "xxx,," + String temp = ""; + for (String item : childJobIds) { + temp += item + ","; + } + temp = temp.substring(0, temp.length() - 1); + + jobInfo.setChildJobId(temp); + } + + // add in db + jobInfo.setAddTime(new Date()); + jobInfo.setUpdateTime(new Date()); + jobInfo.setGlueUpdatetime(new Date()); + xxlJobInfoDao.save(jobInfo); + if (jobInfo.getId() < 1) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add") + I18nUtil.getString("system_fail"))); + } + + return new ReturnT(String.valueOf(jobInfo.getId())); + } + + private boolean isNumeric(String str) { + try { + int result = Integer.valueOf(str); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + @Override + public ReturnT update(XxlJobInfo jobInfo) { + + // valid base + if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_jobdesc"))); + } + if (jobInfo.getAuthor() == null || jobInfo.getAuthor().trim().length() == 0) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobinfo_field_author"))); + } + + // valid trigger + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); + if (scheduleTypeEnum == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + if (scheduleTypeEnum == ScheduleTypeEnum.CRON) { + if (jobInfo.getScheduleConf() == null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) { + return new ReturnT(ReturnT.FAIL_CODE, "Cron" + I18nUtil.getString("system_unvalid")); + } + } else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) { + if (jobInfo.getScheduleConf() == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + try { + int fixSecond = Integer.valueOf(jobInfo.getScheduleConf()); + if (fixSecond < 1) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + } catch (Exception e) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + } + + // valid advanced + if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy") + I18nUtil.getString("system_unvalid"))); + } + if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy") + I18nUtil.getString("system_unvalid"))); + } + if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy") + I18nUtil.getString("system_unvalid"))); + } + + // 》ChildJobId valid + if (jobInfo.getChildJobId() != null && jobInfo.getChildJobId().trim().length() > 0) { + String[] childJobIds = jobInfo.getChildJobId().split(","); + for (String childJobIdItem : childJobIds) { + if (childJobIdItem != null && childJobIdItem.trim().length() > 0 && isNumeric(childJobIdItem)) { + XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.parseInt(childJobIdItem)); + if (childJobInfo == null) { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_not_found")), childJobIdItem)); + } + } else { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})" + I18nUtil.getString("system_unvalid")), childJobIdItem)); + } + } + + // join , avoid "xxx,," + String temp = ""; + for (String item : childJobIds) { + temp += item + ","; + } + temp = temp.substring(0, temp.length() - 1); + + jobInfo.setChildJobId(temp); + } + + // group valid + XxlJobGroup jobGroup = xxlJobGroupDao.load(jobInfo.getJobGroup()); + if (jobGroup == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_jobgroup") + I18nUtil.getString("system_unvalid"))); + } + + // stage job info + XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); + if (exists_jobInfo == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id") + I18nUtil.getString("system_not_found"))); + } + + // next trigger time (5s后生效,避开预读周期) + long nextTriggerTime = exists_jobInfo.getTriggerNextTime(); + boolean scheduleDataNotChanged = jobInfo.getScheduleType().equals(exists_jobInfo.getScheduleType()) && jobInfo.getScheduleConf().equals(exists_jobInfo.getScheduleConf()); + if (exists_jobInfo.getTriggerStatus() == 1 && !scheduleDataNotChanged) { + try { + Date nextValidTime = JobScheduleHelper.generateNextValidTime(jobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); + if (nextValidTime == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + nextTriggerTime = nextValidTime.getTime(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + } + + exists_jobInfo.setJobGroup(jobInfo.getJobGroup()); + exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); + exists_jobInfo.setAuthor(jobInfo.getAuthor()); + exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); + exists_jobInfo.setScheduleType(jobInfo.getScheduleType()); + exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf()); + exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy()); + exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy()); + exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler()); + exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam()); + exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy()); + exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout()); + exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount()); + exists_jobInfo.setChildJobId(jobInfo.getChildJobId()); + exists_jobInfo.setTriggerNextTime(nextTriggerTime); + + exists_jobInfo.setUpdateTime(new Date()); + xxlJobInfoDao.update(exists_jobInfo); + + + return ReturnT.SUCCESS; + } + + @Override + public ReturnT remove(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + if (xxlJobInfo == null) { + return ReturnT.SUCCESS; + } + + xxlJobInfoDao.delete(id); + xxlJobLogDao.delete(id); + xxlJobLogGlueDao.deleteByJobId(id); + return ReturnT.SUCCESS; + } + + @Override + public ReturnT start(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + + // valid + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE); + if (ScheduleTypeEnum.NONE == scheduleTypeEnum) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start"))); + } + + // next trigger time (5s后生效,避开预读周期) + long nextTriggerTime = 0; + try { + Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); + if (nextValidTime == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + nextTriggerTime = nextValidTime.getTime(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid"))); + } + + xxlJobInfo.setTriggerStatus(1); + xxlJobInfo.setTriggerLastTime(0); + xxlJobInfo.setTriggerNextTime(nextTriggerTime); + + xxlJobInfo.setUpdateTime(new Date()); + xxlJobInfoDao.update(xxlJobInfo); + return ReturnT.SUCCESS; + } + + @Override + public ReturnT stop(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + + xxlJobInfo.setTriggerStatus(0); + xxlJobInfo.setTriggerLastTime(0); + xxlJobInfo.setTriggerNextTime(0); + + xxlJobInfo.setUpdateTime(new Date()); + xxlJobInfoDao.update(xxlJobInfo); + return ReturnT.SUCCESS; + } + + @Override + public Map dashboardInfo() { + + int jobInfoCount = xxlJobInfoDao.findAllCount(); + int jobLogCount = 0; + int jobLogSuccessCount = 0; + XxlJobLogReport xxlJobLogReport = xxlJobLogReportDao.queryLogReportTotal(); + if (xxlJobLogReport != null) { + jobLogCount = xxlJobLogReport.getRunningCount() + xxlJobLogReport.getSucCount() + xxlJobLogReport.getFailCount(); + jobLogSuccessCount = xxlJobLogReport.getSucCount(); + } + + // executor count + Set executorAddressSet = new HashSet(); + List groupList = xxlJobGroupDao.findAll(); + + if (groupList != null && !groupList.isEmpty()) { + for (XxlJobGroup group : groupList) { + if (group.getRegistryList() != null && !group.getRegistryList().isEmpty()) { + executorAddressSet.addAll(group.getRegistryList()); + } + } + } + + int executorCount = executorAddressSet.size(); + + Map dashboardMap = new HashMap(); + dashboardMap.put("jobInfoCount", jobInfoCount); + dashboardMap.put("jobLogCount", jobLogCount); + dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount); + dashboardMap.put("executorCount", executorCount); + return dashboardMap; + } + + @Override + public ReturnT> chartInfo(Date startDate, Date endDate) { + + // process + List triggerDayList = new ArrayList(); + List triggerDayCountRunningList = new ArrayList(); + List triggerDayCountSucList = new ArrayList(); + List triggerDayCountFailList = new ArrayList(); + int triggerCountRunningTotal = 0; + int triggerCountSucTotal = 0; + int triggerCountFailTotal = 0; + + List logReportList = xxlJobLogReportDao.queryLogReport(startDate, endDate); + + if (logReportList != null && logReportList.size() > 0) { + for (XxlJobLogReport item : logReportList) { + String day = DateUtil.formatDate(item.getTriggerDay()); + int triggerDayCountRunning = item.getRunningCount(); + int triggerDayCountSuc = item.getSucCount(); + int triggerDayCountFail = item.getFailCount(); + + triggerDayList.add(day); + triggerDayCountRunningList.add(triggerDayCountRunning); + triggerDayCountSucList.add(triggerDayCountSuc); + triggerDayCountFailList.add(triggerDayCountFail); + + triggerCountRunningTotal += triggerDayCountRunning; + triggerCountSucTotal += triggerDayCountSuc; + triggerCountFailTotal += triggerDayCountFail; + } + } else { + for (int i = -6; i <= 0; i++) { + triggerDayList.add(DateUtil.formatDate(DateUtil.addDays(new Date(), i))); + triggerDayCountRunningList.add(0); + triggerDayCountSucList.add(0); + triggerDayCountFailList.add(0); + } + } + + Map result = new HashMap(); + result.put("triggerDayList", triggerDayList); + result.put("triggerDayCountRunningList", triggerDayCountRunningList); + result.put("triggerDayCountSucList", triggerDayCountSucList); + result.put("triggerDayCountFailList", triggerDayCountFailList); + + result.put("triggerCountRunningTotal", triggerCountRunningTotal); + result.put("triggerCountSucTotal", triggerCountSucTotal); + result.put("triggerCountFailTotal", triggerCountFailTotal); + + return new ReturnT>(result); + } + + @Override + public ReturnT deleteByObjectId(String objectId) { + xxlJobInfoDao.deleteByObjectId(objectId); + return ReturnT.SUCCESS; + } + +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/bootstrap.yml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..c2bf87d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/bootstrap.yml @@ -0,0 +1,39 @@ +server: + port: 8200 + +spring: + application: + name: xxl-job-${spring.profiles.active} # 服务名 + main: + allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 + allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务 + data: + redis: + repositories: + enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 + profiles: + active: dev + cloud: + nacos: + discovery: + server-addr: localhost:9000 # 配置服务注册nacos地址 + namespace: ${spring.profiles.active} # 配置命名空间 + service: ${spring.application.name} # 配置服务名 + config: + # 指定nacos server的地址 + server-addr: localhost:9000 + # 配置文件后缀 + file-extension: yml + # 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等 + namespace: ${spring.profiles.active} # 配置命名空间 + # 支持多个共享 Data Id 的配置,优先级小于ext-config,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh + ext-config: + - data-id: skyeye-common.yml # 配置文件名-Data Id + group: DEFAULT_GROUP # 默认为DEFAULT_GROUP + refresh: false # 是否动态刷新,默认为false + +# 配置打印sql到控制台 +#logging: +# level: +# com.xxl.job.admin.dao: debug + diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_en.properties b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_en.properties new file mode 100644 index 0000000..8e7d835 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_en.properties @@ -0,0 +1,276 @@ +admin_name=Scheduling Center +admin_name_full=Distributed Task Scheduling Platform XXL-JOB +admin_version=2.3.0 +admin_i18n=en + +## system +system_tips=System message +system_ok=Confirm +system_close=Close +system_save=Save +system_cancel=Cancel +system_search=Search +system_status=Status +system_opt=Operate +system_please_input=please input +system_please_choose=please choose +system_success=success +system_fail=fail +system_add_suc=add success +system_add_fail=add fail +system_update_suc=update success +system_update_fail=update fail +system_all=All +system_api_error=net error +system_show=Show +system_empty=Empty +system_opt_suc=operate success +system_opt_fail=operate fail +system_opt_edit=Edit +system_opt_del=Delete +system_opt_copy=Copy +system_unvalid=illegal +system_not_found=not exist +system_nav=Navigation +system_digits=digits +system_lengh_limit=Length limit +system_permission_limit=Permission limit +system_welcome=Welcome + +## daterangepicker +daterangepicker_ranges_recent_hour=recent one hour +daterangepicker_ranges_today=today +daterangepicker_ranges_yesterday=yesterday +daterangepicker_ranges_this_month=this month +daterangepicker_ranges_last_month=last month +daterangepicker_ranges_recent_week=recent one week +daterangepicker_ranges_recent_month=recent one month +daterangepicker_custom_name=custom +daterangepicker_custom_starttime=start time +daterangepicker_custom_endtime=end time +daterangepicker_custom_daysofweek=Sun,Mon,Tue,Wed,Thu,Fri,Sat +daterangepicker_custom_monthnames=Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec + +## dataTable +dataTable_sProcessing=processing... +dataTable_sLengthMenu= _MENU_ records per page +dataTable_sZeroRecords=No matching results +dataTable_sInfo=page _PAGE_ ( Total _PAGES_ pages,_TOTAL_ records ) +dataTable_sInfoEmpty=No Record +dataTable_sInfoFiltered=(Filtered by _MAX_ results) +dataTable_sSearch=Search +dataTable_sEmptyTable=Table data is empty +dataTable_sLoadingRecords=Loading... +dataTable_sFirst=FIRST PAGE +dataTable_sPrevious=Previous Page +dataTable_sNext=Next Page +dataTable_sLast=LAST PAGE +dataTable_sSortAscending=: Rank this column in ascending order +dataTable_sSortDescending=: Rank this column in descending order + +## login +login_btn=Login +login_remember_me=Remember Me +login_username_placeholder=Please enter username +login_password_placeholder=Please enter password +login_username_empty=Please enter username +login_username_lt_4=Username length should not be less than 4 +login_password_empty=Please enter password +login_password_lt_4=Password length should not be less than 4 +login_success=Login success +login_fail=Login fail +login_param_empty=Username or password is empty +login_param_unvalid=Username or password error + +## logout +logout_btn=Logout +logout_confirm=Confirm logout? +logout_success=Logout success +logout_fail=Logout fail + +## change pwd +change_pwd=Change password +change_pwd_suc_to_logout=Change password successful, about to log out login +change_pwd_field_newpwd=new password + +## dashboard +job_dashboard_name=Run report +job_dashboard_job_num=Job number +job_dashboard_job_num_tip=The number of tasks running in the scheduling center +job_dashboard_trigger_num=trigger number +job_dashboard_trigger_num_tip=The number of trigger record scheduled by the scheduling center +job_dashboard_jobgroup_num=Executor number +job_dashboard_jobgroup_num_tip=The number of online executor machines perceived by the scheduling center +job_dashboard_report=Scheduling report +job_dashboard_report_loaddata_fail=Scheduling report load data error +job_dashboard_date_report=Date distribution +job_dashboard_rate_report=Percentage distribution + +## job info +jobinfo_name=Job Manage +jobinfo_job=Job +jobinfo_field_add=Add Job +jobinfo_field_update=Edit Job +jobinfo_field_id=Job ID +jobinfo_field_jobgroup=Executor +jobinfo_field_jobdesc=Job description +jobinfo_field_timeout=Job timeout period +jobinfo_field_gluetype=GLUE Type +jobinfo_field_executorparam=Param +jobinfo_field_author=Author +jobinfo_field_alarmemail=Alarm email +jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated +jobinfo_field_executorRouteStrategy=Route Strategy +jobinfo_field_childJobId=Child Job ID +jobinfo_field_childJobId_placeholder=Please enter the Child job ID, if there are more than one comma separated +jobinfo_field_executorBlockStrategy=Block Strategy +jobinfo_field_executorFailRetryCount=Fail Retry Count +jobinfo_field_executorFailRetryCount_placeholder=Fail Retry Count. effect if greater than zero +jobinfo_script_location=Script location +jobinfo_shard_index=Shard index +jobinfo_shard_total=Shard total +jobinfo_opt_stop=Stop +jobinfo_opt_start=Start +jobinfo_opt_log=Query Log +jobinfo_opt_run=Run Once +jobinfo_opt_run_tips=Please input the address for this trigger. Null will be obtained from the executor +jobinfo_opt_registryinfo=Registry Info +jobinfo_opt_next_time=Next trigger time +jobinfo_glue_remark=Resource Remark +jobinfo_glue_remark_limit=Resource Remark length is limited to 4~100 +jobinfo_glue_rollback=Version Backtrack +jobinfo_glue_jobid_unvalid=Job ID is illegal +jobinfo_glue_gluetype_unvalid=The job is not GLUE Type +jobinfo_field_executorTimeout_placeholder=Job Timeout period,in seconds. effect if greater than zero +schedule_type=Schedule Type +schedule_type_none=None +schedule_type_cron=Cron +schedule_type_fix_rate=Fix rate +schedule_type_fix_delay=Fix delay +schedule_type_none_limit_start=The current schedule type disables startup +misfire_strategy=Misfire strategy +misfire_strategy_do_nothing=Do nothing +misfire_strategy_fire_once_now=Fire once now +jobinfo_conf_base=Base configuration +jobinfo_conf_schedule=Schedule configuration +jobinfo_conf_job=Job configuration +jobinfo_conf_advanced=Advanced configuration + +## job log +joblog_name=Trigger Log +joblog_status=Status +joblog_status_all=All +joblog_status_suc=Success +joblog_status_fail=Fail +joblog_status_running=Running +joblog_field_triggerTime=Trigger Time +joblog_field_triggerCode=Trigger Result +joblog_field_triggerMsg=Trigger Msg +joblog_field_handleTime=Handle Time +joblog_field_handleCode=Handle Result +joblog_field_handleMsg=Trigger Msg +joblog_field_executorAddress=Executor Address +joblog_clean=Clean +joblog_clean_log=Clean Log +joblog_clean_type=Clean Type +joblog_clean_type_1=Clean up log data a month ago +joblog_clean_type_2=Clean up log data three month ago +joblog_clean_type_3=Clean up log data six month ago +joblog_clean_type_4=Clean up log data a year ago +joblog_clean_type_5=Clean up log data a thousand record ago +joblog_clean_type_6=Clean up log data ten thousand record ago +joblog_clean_type_7=Clean up log data thirty thousand record ago +joblog_clean_type_8=Clean up log data hundred thousand record ago +joblog_clean_type_9=Clean up all log data +joblog_clean_type_unvalid=Clean type is illegal +joblog_handleCode_200=Success +joblog_handleCode_500=Fail +joblog_handleCode_502=Timeout +joblog_kill_log=Kill Job +joblog_kill_log_limit=Trigger Fail, can not kill job +joblog_kill_log_byman=Manual operation, kill job +joblog_lost_fail=Job result lost, marked as failure +joblog_rolling_log=Rolling log +joblog_rolling_log_refresh=Refresh +joblog_rolling_log_triggerfail=The job trigger fail, can not view the rolling log +joblog_rolling_log_failoften=The request for the Rolling log is terminated, the number of failed requests exceeds the limit, Reload the log on the refresh page +joblog_logid_unvalid=Log ID is illegal + +## job group +jobgroup_name=Executor Manage +jobgroup_list=Executor List +jobgroup_add=Add Executor +jobgroup_edit=Edit Executor +jobgroup_del=Delete Executor +jobgroup_field_title=Title +jobgroup_field_addressType=Registry Type +jobgroup_field_addressType_0=Automatic registration +jobgroup_field_addressType_1=Manual registration +jobgroup_field_addressType_limit=Manually registration type, the machine address must not be empty +jobgroup_field_registryList=machine address +jobgroup_field_registryList_unvalid=registry machine address is illegal +jobgroup_field_registryList_placeholder=Please enter the machine address, if there are more than one comma separated +jobgroup_field_appname_limit=Limit the beginning of a lowercase letter, consists of lowercase letters、number and hyphen. +jobgroup_field_appname_length=AppName length is limited to 4~64 +jobgroup_field_title_length=Title length is limited to 4~12 +jobgroup_field_order_digits=Please enter a positive integer +jobgroup_field_orderrange=Order is limited to 1~1000 +jobgroup_del_limit_0=Refuse to delete, the executor is being used +jobgroup_del_limit_1=Refuses to delete, the system retains at least one executor +jobgroup_empty=There is no valid executor. Please contact the administrator + +## job conf +jobconf_block_SERIAL_EXECUTION=Serial execution +jobconf_block_DISCARD_LATER=Discard Later +jobconf_block_COVER_EARLY=Cover Early +jobconf_route_first=First +jobconf_route_last=Last +jobconf_route_round=Round +jobconf_route_random=Random +jobconf_route_consistenthash=Consistent Hash +jobconf_route_lfu=Least Frequently Used +jobconf_route_lru=Least Recently Used +jobconf_route_failover=Failover +jobconf_route_busyover=Busyover +jobconf_route_shard=Sharding Broadcast +jobconf_idleBeat=Idle check +jobconf_beat=Heartbeats +jobconf_monitor=Task Scheduling Center monitor alarm +jobconf_monitor_detail=monitor alarm details +jobconf_monitor_alarm_title=Alarm Type +jobconf_monitor_alarm_type=Trigger Fail +jobconf_monitor_alarm_content=Alarm Content +jobconf_trigger_admin_adress=Trigger machine address +jobconf_trigger_exe_regtype=Execotor-Registry Type +jobconf_trigger_exe_regaddress=Execotor-Registry Address +jobconf_trigger_address_empty=Trigger Fail:registry address is empty +jobconf_trigger_run=Trigger Job +jobconf_trigger_child_run=Trigger child job +jobconf_callback_child_msg1={0}/{1} [Job ID={2}], Trigger {3}, Trigger msg: {4}
+jobconf_callback_child_msg2={0}/{1} [Job ID={2}], Trigger Fail, Trigger msg: Job ID is illegal
+jobconf_trigger_type=Job trigger type +jobconf_trigger_type_cron=Cron trigger +jobconf_trigger_type_manual=Manual trigger +jobconf_trigger_type_parent=Parent job trigger +jobconf_trigger_type_api=Api trigger +jobconf_trigger_type_retry=Fail retry trigger +jobconf_trigger_type_misfire=Misfire compensation trigger + +## user +user_manage=User Manage +user_username=Username +user_password=Password +user_role=Role +user_role_admin=Admin User +user_role_normal=Normal User +user_permission=Permission +user_add=Add User +user_update=Edit User +user_username_repeat=Username Repeat +user_username_valid=Restrictions start with a lowercase letter and consist of lowercase letters and Numbers +user_password_update_placeholder=Please input password, empty means not update +user_update_loginuser_limit=Operation of current login account is not allowed + +## help +job_help=Tutorial +job_help_document=Official Document diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties new file mode 100644 index 0000000..00ca50e --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties @@ -0,0 +1,276 @@ +admin_name=任务调度中心 +admin_name_full=分布式任务调度平台XXL-JOB +admin_version=2.3.0 +admin_i18n= + +## system +system_tips=系统提示 +system_ok=确定 +system_close=关闭 +system_save=保存 +system_cancel=取消 +system_search=搜索 +system_status=状态 +system_opt=操作 +system_please_input=请输入 +system_please_choose=请选择 +system_success=成功 +system_fail=失败 +system_add_suc=新增成功 +system_add_fail=新增失败 +system_update_suc=更新成功 +system_update_fail=更新失败 +system_all=全部 +system_api_error=接口异常 +system_show=查看 +system_empty=无 +system_opt_suc=操作成功 +system_opt_fail=操作失败 +system_opt_edit=编辑 +system_opt_del=删除 +system_opt_copy=复制 +system_unvalid=非法 +system_not_found=不存在 +system_nav=导航 +system_digits=整数 +system_lengh_limit=长度限制 +system_permission_limit=权限拦截 +system_welcome=欢迎 + +## daterangepicker +daterangepicker_ranges_recent_hour=最近一小时 +daterangepicker_ranges_today=今日 +daterangepicker_ranges_yesterday=昨日 +daterangepicker_ranges_this_month=本月 +daterangepicker_ranges_last_month=上个月 +daterangepicker_ranges_recent_week=最近一周 +daterangepicker_ranges_recent_month=最近一月 +daterangepicker_custom_name=自定义 +daterangepicker_custom_starttime=起始时间 +daterangepicker_custom_endtime=结束时间 +daterangepicker_custom_daysofweek=日,一,二,三,四,五,六 +daterangepicker_custom_monthnames=一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月 + +## dataTable +dataTable_sProcessing=处理中... +dataTable_sLengthMenu=每页 _MENU_ 条记录 +dataTable_sZeroRecords=没有匹配结果 +dataTable_sInfo=第 _PAGE_ 页 ( 总共 _PAGES_ 页,_TOTAL_ 条记录 ) +dataTable_sInfoEmpty=无记录 +dataTable_sInfoFiltered=(由 _MAX_ 项结果过滤) +dataTable_sSearch=搜索 +dataTable_sEmptyTable=表中数据为空 +dataTable_sLoadingRecords=载入中... +dataTable_sFirst=首页 +dataTable_sPrevious=上页 +dataTable_sNext=下页 +dataTable_sLast=末页 +dataTable_sSortAscending=: 以升序排列此列 +dataTable_sSortDescending=: 以降序排列此列 + +## login +login_btn=登录 +login_remember_me=记住密码 +login_username_placeholder=请输入登录账号 +login_password_placeholder=请输入登录密码 +login_username_empty=请输入登录账号 +login_username_lt_4=登录账号不应低于4位 +login_password_empty=请输入登录密码 +login_password_lt_4=登录密码不应低于4位 +login_success=登录成功 +login_fail=登录失败 +login_param_empty=账号或密码为空 +login_param_unvalid=账号或密码错误 + +## logout +logout_btn=注销 +logout_confirm=确认注销登录? +logout_success=注销成功 +logout_fail=注销失败 + +## change pwd +change_pwd=修改密码 +change_pwd_suc_to_logout=修改密码成功,即将注销登陆 +change_pwd_field_newpwd=新密码 + +## dashboard +job_dashboard_name=运行报表 +job_dashboard_job_num=任务数量 +job_dashboard_job_num_tip=调度中心运行的任务数量 +job_dashboard_trigger_num=调度次数 +job_dashboard_trigger_num_tip=调度中心触发的调度次数 +job_dashboard_jobgroup_num=执行器数量 +job_dashboard_jobgroup_num_tip=调度中心在线的执行器机器数量 +job_dashboard_report=调度报表 +job_dashboard_report_loaddata_fail=调度报表数据加载异常 +job_dashboard_date_report=日期分布图 +job_dashboard_rate_report=成功比例图 + +## job info +jobinfo_name=任务管理 +jobinfo_job=任务 +jobinfo_field_add=新增 +jobinfo_field_update=更新任务 +jobinfo_field_id=任务ID +jobinfo_field_jobgroup=执行器 +jobinfo_field_jobdesc=任务描述 +jobinfo_field_gluetype=运行模式 +jobinfo_field_executorparam=任务参数 +jobinfo_field_author=负责人 +jobinfo_field_timeout=任务超时时间 +jobinfo_field_alarmemail=报警邮件 +jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔 +jobinfo_field_executorRouteStrategy=路由策略 +jobinfo_field_childJobId=子任务ID +jobinfo_field_childJobId_placeholder=请输入子任务的任务ID,如存在多个则逗号分隔 +jobinfo_field_executorBlockStrategy=阻塞处理策略 +jobinfo_field_executorFailRetryCount=失败重试次数 +jobinfo_field_executorFailRetryCount_placeholder=失败重试次数,大于零时生效 +jobinfo_script_location=脚本位置 +jobinfo_shard_index=分片序号 +jobinfo_shard_total=分片总数 +jobinfo_opt_stop=停止 +jobinfo_opt_start=启动 +jobinfo_opt_log=查询日志 +jobinfo_opt_run=执行一次 +jobinfo_opt_run_tips=请输入本次执行的机器地址,为空则从执行器获取 +jobinfo_opt_registryinfo=注册节点 +jobinfo_opt_next_time=下次执行时间 +jobinfo_glue_remark=源码备注 +jobinfo_glue_remark_limit=源码备注长度限制为4~100 +jobinfo_glue_rollback=版本回溯 +jobinfo_glue_jobid_unvalid=任务ID非法 +jobinfo_glue_gluetype_unvalid=该任务非GLUE模式 +jobinfo_field_executorTimeout_placeholder=任务超时时间,单位秒,大于零时生效 +schedule_type=调度类型 +schedule_type_none=无 +schedule_type_cron=CRON +schedule_type_fix_rate=固定速度 +schedule_type_fix_delay=固定延迟 +schedule_type_none_limit_start=当前调度类型禁止启动 +misfire_strategy=调度过期策略 +misfire_strategy_do_nothing=忽略 +misfire_strategy_fire_once_now=立即执行一次 +jobinfo_conf_base=基础配置 +jobinfo_conf_schedule=调度配置 +jobinfo_conf_job=任务配置 +jobinfo_conf_advanced=高级配置 + +## job log +joblog_name=调度日志 +joblog_status=状态 +joblog_status_all=全部 +joblog_status_suc=成功 +joblog_status_fail=失败 +joblog_status_running=进行中 +joblog_field_triggerTime=调度时间 +joblog_field_triggerCode=调度结果 +joblog_field_triggerMsg=调度备注 +joblog_field_handleTime=执行时间 +joblog_field_handleCode=执行结果 +joblog_field_handleMsg=执行备注 +joblog_field_executorAddress=执行器地址 +joblog_clean=清理 +joblog_clean_log=日志清理 +joblog_clean_type=清理方式 +joblog_clean_type_1=清理一个月之前日志数据 +joblog_clean_type_2=清理三个月之前日志数据 +joblog_clean_type_3=清理六个月之前日志数据 +joblog_clean_type_4=清理一年之前日志数据 +joblog_clean_type_5=清理一千条以前日志数据 +joblog_clean_type_6=清理一万条以前日志数据 +joblog_clean_type_7=清理三万条以前日志数据 +joblog_clean_type_8=清理十万条以前日志数据 +joblog_clean_type_9=清理所有日志数据 +joblog_clean_type_unvalid=清理类型参数异常 +joblog_handleCode_200=成功 +joblog_handleCode_500=失败 +joblog_handleCode_502=失败(超时) +joblog_kill_log=终止任务 +joblog_kill_log_limit=调度失败,无法终止日志 +joblog_kill_log_byman=人为操作,主动终止 +joblog_lost_fail=任务结果丢失,标记失败 +joblog_rolling_log=执行日志 +joblog_rolling_log_refresh=刷新 +joblog_rolling_log_triggerfail=任务发起调度失败,无法查看执行日志 +joblog_rolling_log_failoften=终止请求Rolling日志,请求失败次数超上限,可刷新页面重新加载日志 +joblog_logid_unvalid=日志ID非法 + +## job group +jobgroup_name=执行器管理 +jobgroup_list=执行器列表 +jobgroup_add=新增执行器 +jobgroup_edit=编辑执行器 +jobgroup_del=删除执行器 +jobgroup_field_title=名称 +jobgroup_field_addressType=注册方式 +jobgroup_field_addressType_0=自动注册 +jobgroup_field_addressType_1=手动录入 +jobgroup_field_addressType_limit=手动录入注册方式,机器地址不可为空 +jobgroup_field_registryList=机器地址 +jobgroup_field_registryList_unvalid=机器地址格式非法 +jobgroup_field_registryList_placeholder=请输入执行器地址列表,多地址逗号分隔 +jobgroup_field_appname_limit=限制以小写字母开头,由小写字母、数字和中划线组成 +jobgroup_field_appname_length=AppName长度限制为4~64 +jobgroup_field_title_length=名称长度限制为4~12 +jobgroup_field_order_digits=请输入整数 +jobgroup_field_orderrange=取值范围为1~1000 +jobgroup_del_limit_0=拒绝删除,该执行器使用中 +jobgroup_del_limit_1=拒绝删除, 系统至少保留一个执行器 +jobgroup_empty=不存在有效执行器,请联系管理员 + +## job conf +jobconf_block_SERIAL_EXECUTION=单机串行 +jobconf_block_DISCARD_LATER=丢弃后续调度 +jobconf_block_COVER_EARLY=覆盖之前调度 +jobconf_route_first=第一个 +jobconf_route_last=最后一个 +jobconf_route_round=轮询 +jobconf_route_random=随机 +jobconf_route_consistenthash=一致性HASH +jobconf_route_lfu=最不经常使用 +jobconf_route_lru=最近最久未使用 +jobconf_route_failover=故障转移 +jobconf_route_busyover=忙碌转移 +jobconf_route_shard=分片广播 +jobconf_idleBeat=空闲检测 +jobconf_beat=心跳检测 +jobconf_monitor=任务调度中心监控报警 +jobconf_monitor_detail=监控告警明细 +jobconf_monitor_alarm_title=告警类型 +jobconf_monitor_alarm_type=调度失败 +jobconf_monitor_alarm_content=告警内容 +jobconf_trigger_admin_adress=调度机器 +jobconf_trigger_exe_regtype=执行器-注册方式 +jobconf_trigger_exe_regaddress=执行器-地址列表 +jobconf_trigger_address_empty=调度失败:执行器地址为空 +jobconf_trigger_run=触发调度 +jobconf_trigger_child_run=触发子任务 +jobconf_callback_child_msg1={0}/{1} [任务ID={2}], 触发{3}, 触发备注: {4}
+jobconf_callback_child_msg2={0}/{1} [任务ID={2}], 触发失败, 触发备注: 任务ID格式错误
+jobconf_trigger_type=任务触发类型 +jobconf_trigger_type_cron=Cron触发 +jobconf_trigger_type_manual=手动触发 +jobconf_trigger_type_parent=父任务触发 +jobconf_trigger_type_api=API触发 +jobconf_trigger_type_retry=失败重试触发 +jobconf_trigger_type_misfire=调度过期补偿 + +## user +user_manage=用户管理 +user_username=账号 +user_password=密码 +user_role=角色 +user_role_admin=管理员 +user_role_normal=普通用户 +user_permission=权限 +user_add=新增用户 +user_update=更新用户 +user_username_repeat=账号重复 +user_username_valid=限制以小写字母开头,由小写字母、数字组成 +user_password_update_placeholder=请输入新密码,为空则不更新密码 +user_update_loginuser_limit=禁止操作当前登录账号 + +## help +job_help=使用教程 +job_help_document=官方文档 \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties new file mode 100644 index 0000000..90bfc1a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties @@ -0,0 +1,276 @@ +admin_name=任務調度中心 +admin_name_full=分布式任務調度平臺XXL-JOB +admin_version=2.3.0 +admin_i18n= + +## system +system_tips=系統提示 +system_ok=確定 +system_close=關閉 +system_save=儲存 +system_cancel=取消 +system_search=搜尋 +system_status=狀態 +system_opt=操作 +system_please_input=請輸入 +system_please_choose=请選擇 +system_success=成功 +system_fail=失敗 +system_add_suc=新增成功 +system_add_fail=新增失敗 +system_update_suc=更新成功 +system_update_fail=更新失敗 +system_all=全部 +system_api_error=API錯誤 +system_show=查看 +system_empty=無 +system_opt_suc=操作成功 +system_opt_fail=操作失敗 +system_opt_edit=編輯 +system_opt_del=刪除 +system_opt_copy=復制 +system_unvalid=非法 +system_not_found=不存在 +system_nav=導航 +system_digits=整數 +system_lengh_limit=長度限制 +system_permission_limit=權限控管 +system_welcome=歡迎 + +## daterangepicker +daterangepicker_ranges_recent_hour=最近一小時 +daterangepicker_ranges_today=今日 +daterangepicker_ranges_yesterday=昨日 +daterangepicker_ranges_this_month=本月 +daterangepicker_ranges_last_month=上個月 +daterangepicker_ranges_recent_week=最近一周 +daterangepicker_ranges_recent_month=最近一月 +daterangepicker_custom_name=自定義 +daterangepicker_custom_starttime=起始時間 +daterangepicker_custom_endtime=結束時間 +daterangepicker_custom_daysofweek=日,一,二,三,四,五,六 +daterangepicker_custom_monthnames=一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月 + +## dataTable +dataTable_sProcessing=處理中... +dataTable_sLengthMenu=每頁 _MENU_ 條記錄 +dataTable_sZeroRecords=沒有相符合記錄 +dataTable_sInfo=第 _PAGE_ 頁 ( 總共 _PAGES_ 頁,_TOTAL_ 條記錄 ) +dataTable_sInfoEmpty=無記錄 +dataTable_sInfoFiltered=(由 _MAX_ 項結果過濾) +dataTable_sSearch=搜尋 +dataTable_sEmptyTable=表中資料為空 +dataTable_sLoadingRecords=載入中... +dataTable_sFirst=首頁 +dataTable_sPrevious=上頁 +dataTable_sNext=下頁 +dataTable_sLast=末頁 +dataTable_sSortAscending=: 以升幂排序此列 +dataTable_sSortDescending=: 以降幂排序此列 + +## login +login_btn=登入 +login_remember_me=記住密碼 +login_username_placeholder=請輸入登入帳號 +login_password_placeholder=請輸入登入密碼 +login_username_empty=請輸入登入帳號 +login_username_lt_4=登入帳號不應低於4位數 +login_password_empty=請輸入登入密碼 +login_password_lt_4=登入密碼不應低於4位數 +login_success=登入成功 +login_fail=登入失敗 +login_param_empty=帳號或密碼為空值 +login_param_unvalid=帳號或密碼錯誤 + +## logout +logout_btn=登出 +logout_confirm=確認登出? +logout_success=登出成功 +logout_fail=登出失敗 + +## change pwd +change_pwd=修改密碼 +change_pwd_suc_to_logout=修改密碼成功,即將登出 +change_pwd_field_newpwd=新密碼 + +## dashboard +job_dashboard_name=運行報表 +job_dashboard_job_num=任務數量 +job_dashboard_job_num_tip=調度中心運行的任務數量 +job_dashboard_trigger_num=調度次數 +job_dashboard_trigger_num_tip=調度中心觸發的調度次數 +job_dashboard_jobgroup_num=執行器數量 +job_dashboard_jobgroup_num_tip=調度中心在線的執行器機器數量 +job_dashboard_report=調度報表 +job_dashboard_report_loaddata_fail=調度報表資料加載異常 +job_dashboard_date_report=日期分布圖 +job_dashboard_rate_report=成功比例圖 + +## job info +jobinfo_name=任務管理 +jobinfo_job=任務 +jobinfo_field_add=新增 +jobinfo_field_update=更新任務 +jobinfo_field_id=任務ID +jobinfo_field_jobgroup=執行器 +jobinfo_field_jobdesc=任務描述 +jobinfo_field_gluetype=運行模式 +jobinfo_field_executorparam=任務參數 +jobinfo_field_author=負責人 +jobinfo_field_timeout=任務超時秒數 +jobinfo_field_alarmemail=告警郵件 +jobinfo_field_alarmemail_placeholder=輸入多個告警郵件地址,請以逗號分隔 +jobinfo_field_executorRouteStrategy=路由策略 +jobinfo_field_childJobId=子任務ID +jobinfo_field_childJobId_placeholder=輸入子任務ID,如有多個請以逗號分隔 +jobinfo_field_executorBlockStrategy=阻塞處理策略 +jobinfo_field_executorFailRetryCount=失敗重試次數 +jobinfo_field_executorFailRetryCount_placeholder=失敗重試次數,大於零時生效 +jobinfo_script_location=腳本位置 +jobinfo_shard_index=分片序號 +jobinfo_shard_total=分片總數 +jobinfo_opt_stop=停止 +jobinfo_opt_start=啟動 +jobinfo_opt_log=查詢日誌 +jobinfo_opt_run=執行一次 +jobinfo_opt_run_tips=請輸入本次執行的機器地址,為空則從執行器獲取 +jobinfo_opt_registryinfo=注冊節點 +jobinfo_opt_next_time=下次執行時間 +jobinfo_glue_remark=源碼備註 +jobinfo_glue_remark_limit=源碼備註長度限制為4~100 +jobinfo_glue_rollback=版本回復 +jobinfo_glue_jobid_unvalid=任務ID非法 +jobinfo_glue_gluetype_unvalid=該任務非GLUE模式 +jobinfo_field_executorTimeout_placeholder=任務超時時間,單位秒,大於零時生效 +schedule_type=調度類型 +schedule_type_none=無 +schedule_type_cron=CRON +schedule_type_fix_rate=固定速度 +schedule_type_fix_delay=固定延遲 +schedule_type_none_limit_start=當前調度類型禁止啟動 +misfire_strategy=調度過期策略 +misfire_strategy_do_nothing=忽略 +misfire_strategy_fire_once_now=立即執行壹次 +jobinfo_conf_base=基礎配置 +jobinfo_conf_schedule=調度配置 +jobinfo_conf_job=任務配置 +jobinfo_conf_advanced=高級配置 + +## job log +joblog_name=調度日誌 +joblog_status=狀態 +joblog_status_all=全部 +joblog_status_suc=成功 +joblog_status_fail=失敗 +joblog_status_running=進行中 +joblog_field_triggerTime=調度時間 +joblog_field_triggerCode=調度結果 +joblog_field_triggerMsg=調度備註 +joblog_field_handleTime=執行時間 +joblog_field_handleCode=執行结果 +joblog_field_handleMsg=執行備註 +joblog_field_executorAddress=執行器地址 +joblog_clean=清理 +joblog_clean_log=日誌清理 +joblog_clean_type=清理方式 +joblog_clean_type_1=清理一個月之前日誌資料 +joblog_clean_type_2=清理三個月之前日誌資料 +joblog_clean_type_3=清理六個月之前日誌資料 +joblog_clean_type_4=清理一年之前日誌資料 +joblog_clean_type_5=清理一千條以前日誌資料 +joblog_clean_type_6=清理一萬條以前日誌資料 +joblog_clean_type_7=清理三萬條以前日誌資料 +joblog_clean_type_8=清理十萬條以前日誌資料 +joblog_clean_type_9=清理所有日誌資料 +joblog_clean_type_unvalid=清理類型參数異常 +joblog_handleCode_200=成功 +joblog_handleCode_500=失敗 +joblog_handleCode_502=失敗(超時) +joblog_kill_log=终止任務 +joblog_kill_log_limit=調度失敗,無法终止日誌 +joblog_kill_log_byman=人為操作,主動終止 +joblog_lost_fail=任務結果丟失,標記失敗 +joblog_rolling_log=執行日誌 +joblog_rolling_log_refresh=更新 +joblog_rolling_log_triggerfail=任務發起調度失敗,無法查看執行日誌 +joblog_rolling_log_failoften=終止請求Rolling日誌,請求失敗次數超上限,可刷新頁面重新加載日誌 +joblog_logid_unvalid=日誌ID非法 + +## job group +jobgroup_name=執行器管理 +jobgroup_list=執行器列表 +jobgroup_add=新增執行器 +jobgroup_edit=編輯執行器 +jobgroup_del=刪除執行器 +jobgroup_field_title=名稱 +jobgroup_field_addressType=注冊方式 +jobgroup_field_addressType_0=自動注冊 +jobgroup_field_addressType_1=手動登錄 +jobgroup_field_addressType_limit=手動登錄注冊方式,機器地址不可為空 +jobgroup_field_registryList=機器地址 +jobgroup_field_registryList_unvalid=機器地址格式非法 +jobgroup_field_registryList_placeholder=請輸入執行器地址列表,多個地址請以逗號分隔 +jobgroup_field_appname_limit=限制以小寫字母開頭,由小寫字母、數字和中划線組成 +jobgroup_field_appname_length=AppName長度限制為4~64 +jobgroup_field_title_length=名稱長度限制為4~12 +jobgroup_field_order_digits=請輸入整數 +jobgroup_field_orderrange=取值範圍為1~1000 +jobgroup_del_limit_0=拒絕刪除,該執行器使用中 +jobgroup_del_limit_1=拒絕删除,系统至少保留一個執行器 +jobgroup_empty=不存在有效執行器,請聯絡系統管理員 + +## job conf +jobconf_block_SERIAL_EXECUTION=單機串行 +jobconf_block_DISCARD_LATER=丢棄后續調度 +jobconf_block_COVER_EARLY=覆蓋之前調度 +jobconf_route_first=第一個 +jobconf_route_last=最後一個 +jobconf_route_round=輪詢 +jobconf_route_random=隨機 +jobconf_route_consistenthash=一致性HASH +jobconf_route_lfu=最不經常使用 +jobconf_route_lru=最近最久未使用 +jobconf_route_failover=故障轉移 +jobconf_route_busyover=忙碌轉移 +jobconf_route_shard=分片廣播 +jobconf_idleBeat=空閒檢測 +jobconf_beat=心跳檢測 +jobconf_monitor=任務調度中心監控告警 +jobconf_monitor_detail=監控告警明细 +jobconf_monitor_alarm_title=告警類型 +jobconf_monitor_alarm_type=調度失敗 +jobconf_monitor_alarm_content=告警内容 +jobconf_trigger_admin_adress=調度機器 +jobconf_trigger_exe_regtype=執行器-注冊方式 +jobconf_trigger_exe_regaddress=執行器-地址列表 +jobconf_trigger_address_empty=調度失敗:執行器地址為空 +jobconf_trigger_run=觸發調度 +jobconf_trigger_child_run=觸發子任務 +jobconf_callback_child_msg1={0}/{1} [任務ID={2}], 觸發{3}, 觸發備註: {4}
+jobconf_callback_child_msg2={0}/{1} [任務ID={2}], 觸發失败, 觸發備註: 任務ID格式錯誤
+jobconf_trigger_type=任務觸發類型 +jobconf_trigger_type_cron=Cron觸發 +jobconf_trigger_type_manual=手動觸發 +jobconf_trigger_type_parent=父任務觸發 +jobconf_trigger_type_api=API觸發 +jobconf_trigger_type_retry=失敗重試觸發 +jobconf_trigger_type_misfire=調度過期補償 + +## user +user_manage=用户管理 +user_username=帳號 +user_password=密碼 +user_role=角色 +user_role_admin=管理員 +user_role_normal=普通用戶 +user_permission=權限 +user_add=新增用戶 +user_update=更新用戶 +user_username_repeat=帳號重複 +user_username_valid=限制以小寫字母開頭,由小寫字母、數字組成 +user_password_update_placeholder=請輸入新密碼,為空則不更新密碼 +user_update_loginuser_limit=禁止操作當前登入帳號 + +## help +job_help=使用教程 +job_help_document=官方文件 \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/logback.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..d4b08c2 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/logback.xml @@ -0,0 +1,29 @@ + + + + logback + + + + + %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n + + + + + ${log.path} + + ${log.path}.%d{yyyy-MM-dd}.zip + + + %date %level [%thread] %logger{36} [%file : %line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml new file mode 100644 index 0000000..3b8dc59 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + t.id, + t.app_name, + t.title, + t.address_type, + t.address_list, + t.update_time + + + + + + + + INSERT INTO xxl_job_group (`app_name`, `title`, `address_type`, `address_list`, `update_time`) + values (#{appname}, #{title}, #{addressType}, #{addressList}, #{updateTime}); + + + + UPDATE xxl_job_group + SET `app_name` = #{appname}, + `title` = #{title}, + `address_type` = #{addressType}, + `address_list` = #{addressList}, + `update_time` = #{updateTime} + WHERE id = #{id} + + + + DELETE + FROM xxl_job_group + WHERE id = #{id} + + + + + + + + + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml new file mode 100644 index 0000000..8b4d43d --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t.id, + t.job_group, + t.job_desc, + t.add_time, + t.update_time, + t.author, + t.alarm_email, + t.schedule_type, + t.schedule_conf, + t.misfire_strategy, + t.executor_route_strategy, + t.executor_handler, + t.executor_param, + t.executor_block_strategy, + t.executor_timeout, + t.executor_fail_retry_count, + t.glue_type, + t.glue_source, + t.glue_remark, + t.glue_updatetime, + t.child_jobid, + t.trigger_status, + t.trigger_last_time, + t.trigger_next_time + + + + + + + + INSERT INTO xxl_job_info ( + job_group, + job_desc, + add_time, + update_time, + author, + alarm_email, + schedule_type, + schedule_conf, + misfire_strategy, + executor_route_strategy, + executor_handler, + executor_param, + executor_block_strategy, + executor_timeout, + executor_fail_retry_count, + glue_type, + glue_source, + glue_remark, + glue_updatetime, + child_jobid, + trigger_status, + trigger_last_time, + trigger_next_time, + object_id + ) VALUES ( + #{jobGroup}, + #{jobDesc}, + #{addTime}, + #{updateTime}, + #{author}, + #{alarmEmail}, + #{scheduleType}, + #{scheduleConf}, + #{misfireStrategy}, + #{executorRouteStrategy}, + #{executorHandler}, + #{executorParam}, + #{executorBlockStrategy}, + #{executorTimeout}, + #{executorFailRetryCount}, + #{glueType}, + #{glueSource}, + #{glueRemark}, + #{glueUpdatetime}, + #{childJobId}, + #{triggerStatus}, + #{triggerLastTime}, + #{triggerNextTime}, + #{objectId} + ); + + + + + + UPDATE xxl_job_info + SET + job_group = #{jobGroup}, + job_desc = #{jobDesc}, + update_time = #{updateTime}, + author = #{author}, + alarm_email = #{alarmEmail}, + schedule_type = #{scheduleType}, + schedule_conf = #{scheduleConf}, + misfire_strategy = #{misfireStrategy}, + executor_route_strategy = #{executorRouteStrategy}, + executor_handler = #{executorHandler}, + executor_param = #{executorParam}, + executor_block_strategy = #{executorBlockStrategy}, + executor_timeout = ${executorTimeout}, + executor_fail_retry_count = ${executorFailRetryCount}, + glue_type = #{glueType}, + glue_source = #{glueSource}, + glue_remark = #{glueRemark}, + glue_updatetime = #{glueUpdatetime}, + child_jobid = #{childJobId}, + trigger_status = #{triggerStatus}, + trigger_last_time = #{triggerLastTime}, + trigger_next_time = #{triggerNextTime} + WHERE id = #{id} + + + + DELETE + FROM xxl_job_info + WHERE id = #{id} + + + + + + + + + + + UPDATE xxl_job_info + SET + trigger_last_time = #{triggerLastTime}, + trigger_next_time = #{triggerNextTime}, + trigger_status = #{triggerStatus} + WHERE id = #{id} + + + + DELETE + FROM xxl_job_info + WHERE object_id = #{objectId} + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml new file mode 100644 index 0000000..699277c --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + t.id, + t.job_id, + t.glue_type, + t.glue_source, + t.glue_remark, + t.add_time, + t.update_time + + + + INSERT INTO xxl_job_logglue ( + `job_id`, + `glue_type`, + `glue_source`, + `glue_remark`, + `add_time`, + `update_time` + ) VALUES ( + #{jobId}, + #{glueType}, + #{glueSource}, + #{glueRemark}, + #{addTime}, + #{updateTime} + ); + + + + + + + DELETE FROM xxl_job_logglue + WHERE id NOT in( + SELECT id FROM( + SELECT id FROM xxl_job_logglue + WHERE `job_id` = #{jobId} + ORDER BY update_time desc + LIMIT 0, #{limit} + ) t1 + ) AND `job_id` = #{jobId} + + + + DELETE FROM xxl_job_logglue + WHERE `job_id` = #{jobId} + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml new file mode 100644 index 0000000..4155f17 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t.id, + t.job_group, + t.job_id, + t.executor_address, + t.executor_handler, + t.executor_param, + t.executor_sharding_param, + t.executor_fail_retry_count, + t.trigger_time, + t.trigger_code, + t.trigger_msg, + t.handle_time, + t.handle_code, + t.handle_msg, + t.alarm_status + + + + + + + + + + + INSERT INTO xxl_job_log ( + `job_group`, + `job_id`, + `trigger_time`, + `trigger_code`, + `handle_code` + ) VALUES ( + #{jobGroup}, + #{jobId}, + #{triggerTime}, + #{triggerCode}, + #{handleCode} + ); + + + + + UPDATE xxl_job_log + SET + `trigger_time`= #{triggerTime}, + `trigger_code`= #{triggerCode}, + `trigger_msg`= #{triggerMsg}, + `executor_address`= #{executorAddress}, + `executor_handler`=#{executorHandler}, + `executor_param`= #{executorParam}, + `executor_sharding_param`= #{executorShardingParam}, + `executor_fail_retry_count`= #{executorFailRetryCount} + WHERE `id`= #{id} + + + + UPDATE xxl_job_log + SET + `handle_time`= #{handleTime}, + `handle_code`= #{handleCode}, + `handle_msg`= #{handleMsg} + WHERE `id`= #{id} + + + + delete from xxl_job_log + WHERE job_id = #{jobId} + + + + + + + + + + delete from xxl_job_log + WHERE id in + + #{item} + + + + + + + UPDATE xxl_job_log + SET + `alarm_status` = #{newAlarmStatus} + WHERE `id`= #{logId} AND `alarm_status` = #{oldAlarmStatus} + + + + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogReportMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogReportMapper.xml new file mode 100644 index 0000000..579d5f3 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogReportMapper.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + t.id, + t.trigger_day, + t.running_count, + t.suc_count, + t.fail_count + + + + INSERT INTO xxl_job_log_report ( + `trigger_day`, + `running_count`, + `suc_count`, + `fail_count` + ) VALUES ( + #{triggerDay}, + #{runningCount}, + #{sucCount}, + #{failCount} + ); + + + + + UPDATE xxl_job_log_report + SET `running_count` = #{runningCount}, + `suc_count` = #{sucCount}, + `fail_count` = #{failCount} + WHERE `trigger_day` = #{triggerDay} + + + + + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobRegistryMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobRegistryMapper.xml new file mode 100644 index 0000000..4cae667 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobRegistryMapper.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + t.id, + t.registry_group, + t.registry_key, + t.registry_value, + t.update_time + + + + + + DELETE FROM xxl_job_registry + WHERE id in + + #{item} + + + + + + + UPDATE xxl_job_registry + SET `update_time` = #{updateTime} + WHERE `registry_group` = #{registryGroup} + AND `registry_key` = #{registryKey} + AND `registry_value` = #{registryValue} + + + + INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`) + VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime}) + + + + DELETE FROM xxl_job_registry + WHERE registry_group = #{registryGroup} + AND registry_key = #{registryKey} + AND registry_value = #{registryValue} + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml new file mode 100644 index 0000000..9e09b4a --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + t.id, + t.username, + t.password, + t.role, + t.permission + + + + + + + + + + INSERT INTO xxl_job_user ( + username, + password, + role, + permission + ) VALUES ( + #{username}, + #{password}, + #{role}, + #{permission} + ); + + + + UPDATE xxl_job_user + SET + + password = #{password}, + + role = #{role}, + permission = #{permission} + WHERE id = #{id} + + + + DELETE + FROM xxl_job_user + WHERE id = #{id} + + + \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/css/ionicons.min.css b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/css/ionicons.min.css new file mode 100644 index 0000000..baba9e9 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/css/ionicons.min.css @@ -0,0 +1,11 @@ +@charset "UTF-8";/*! + Ionicons, v2.0.0 + Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ + https://twitter.com/benjsperry https://twitter.com/ionicframework + MIT License: https://github.com/driftyco/ionicons + + Android-style icons originally built by Google’s + Material Design Icons: https://github.com/google/material-design-icons + used under CC BY http://creativecommons.org/licenses/by/4.0/ + Modified icons to fit ionicon’s grid from original. +*/@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot?v=2.0.0");src:url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"),url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"),url("../fonts/ionicons.woff?v=2.0.0") format("woff"),url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg");font-weight:normal;font-style:normal}.ion,.ionicons,.ion-alert:before,.ion-alert-circled:before,.ion-android-add:before,.ion-android-add-circle:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done:before,.ion-android-done-all:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite:before,.ion-android-favorite-outline:before,.ion-android-film:before,.ion-android-folder:before,.ion-android-folder-open:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone:before,.ion-android-microphone-off:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person:before,.ion-android-person-add:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove:before,.ion-android-remove-circle:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share:before,.ion-android-share-alt:before,.ion-android-star:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace:before,.ion-backspace-outline:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox:before,.ion-chatbox-working:before,.ion-chatboxes:before,.ion-chatbubble:before,.ion-chatbubble-working:before,.ion-chatbubbles:before,.ion-checkmark:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close:before,.ion-close-circled:before,.ion-close-round:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code:before,.ion-code-download:before,.ion-code-working:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document:before,.ion-document-text:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email:before,.ion-email-unread:before,.ion-erlenmeyer-flask:before,.ion-erlenmeyer-flask-bubbles:before,.ion-eye:before,.ion-eye-disabled:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash:before,.ion-flash-off:before,.ion-folder:before,.ion-fork:before,.ion-fork-repo:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy:before,.ion-happy-outline:before,.ion-headphone:before,.ion-heart:before,.ion-heart-broken:before,.ion-help:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information:before,.ion-information-circled:before,.ion-ionic:before,.ion-ios-alarm:before,.ion-ios-alarm-outline:before,.ion-ios-albums:before,.ion-ios-albums-outline:before,.ion-ios-americanfootball:before,.ion-ios-americanfootball-outline:before,.ion-ios-analytics:before,.ion-ios-analytics-outline:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at:before,.ion-ios-at-outline:before,.ion-ios-barcode:before,.ion-ios-barcode-outline:before,.ion-ios-baseball:before,.ion-ios-baseball-outline:before,.ion-ios-basketball:before,.ion-ios-basketball-outline:before,.ion-ios-bell:before,.ion-ios-bell-outline:before,.ion-ios-body:before,.ion-ios-body-outline:before,.ion-ios-bolt:before,.ion-ios-bolt-outline:before,.ion-ios-book:before,.ion-ios-book-outline:before,.ion-ios-bookmarks:before,.ion-ios-bookmarks-outline:before,.ion-ios-box:before,.ion-ios-box-outline:before,.ion-ios-briefcase:before,.ion-ios-briefcase-outline:before,.ion-ios-browsers:before,.ion-ios-browsers-outline:before,.ion-ios-calculator:before,.ion-ios-calculator-outline:before,.ion-ios-calendar:before,.ion-ios-calendar-outline:before,.ion-ios-camera:before,.ion-ios-camera-outline:before,.ion-ios-cart:before,.ion-ios-cart-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatbubble:before,.ion-ios-chatbubble-outline:before,.ion-ios-checkmark:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock:before,.ion-ios-clock-outline:before,.ion-ios-close:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-cloud:before,.ion-ios-cloud-download:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloudy:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-outline:before,.ion-ios-cog:before,.ion-ios-cog-outline:before,.ion-ios-color-filter:before,.ion-ios-color-filter-outline:before,.ion-ios-color-wand:before,.ion-ios-color-wand-outline:before,.ion-ios-compose:before,.ion-ios-compose-outline:before,.ion-ios-contact:before,.ion-ios-contact-outline:before,.ion-ios-copy:before,.ion-ios-copy-outline:before,.ion-ios-crop:before,.ion-ios-crop-strong:before,.ion-ios-download:before,.ion-ios-download-outline:before,.ion-ios-drag:before,.ion-ios-email:before,.ion-ios-email-outline:before,.ion-ios-eye:before,.ion-ios-eye-outline:before,.ion-ios-fastforward:before,.ion-ios-fastforward-outline:before,.ion-ios-filing:before,.ion-ios-filing-outline:before,.ion-ios-film:before,.ion-ios-film-outline:before,.ion-ios-flag:before,.ion-ios-flag-outline:before,.ion-ios-flame:before,.ion-ios-flame-outline:before,.ion-ios-flask:before,.ion-ios-flask-outline:before,.ion-ios-flower:before,.ion-ios-flower-outline:before,.ion-ios-folder:before,.ion-ios-folder-outline:before,.ion-ios-football:before,.ion-ios-football-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-b:before,.ion-ios-game-controller-b-outline:before,.ion-ios-gear:before,.ion-ios-gear-outline:before,.ion-ios-glasses:before,.ion-ios-glasses-outline:before,.ion-ios-grid-view:before,.ion-ios-grid-view-outline:before,.ion-ios-heart:before,.ion-ios-heart-outline:before,.ion-ios-help:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-home:before,.ion-ios-home-outline:before,.ion-ios-infinite:before,.ion-ios-infinite-outline:before,.ion-ios-information:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-ionic-outline:before,.ion-ios-keypad:before,.ion-ios-keypad-outline:before,.ion-ios-lightbulb:before,.ion-ios-lightbulb-outline:before,.ion-ios-list:before,.ion-ios-list-outline:before,.ion-ios-location:before,.ion-ios-location-outline:before,.ion-ios-locked:before,.ion-ios-locked-outline:before,.ion-ios-loop:before,.ion-ios-loop-strong:before,.ion-ios-medical:before,.ion-ios-medical-outline:before,.ion-ios-medkit:before,.ion-ios-medkit-outline:before,.ion-ios-mic:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-minus:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-monitor:before,.ion-ios-monitor-outline:before,.ion-ios-moon:before,.ion-ios-moon-outline:before,.ion-ios-more:before,.ion-ios-more-outline:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate:before,.ion-ios-navigate-outline:before,.ion-ios-nutrition:before,.ion-ios-nutrition-outline:before,.ion-ios-paper:before,.ion-ios-paper-outline:before,.ion-ios-paperplane:before,.ion-ios-paperplane-outline:before,.ion-ios-partlysunny:before,.ion-ios-partlysunny-outline:before,.ion-ios-pause:before,.ion-ios-pause-outline:before,.ion-ios-paw:before,.ion-ios-paw-outline:before,.ion-ios-people:before,.ion-ios-people-outline:before,.ion-ios-person:before,.ion-ios-person-outline:before,.ion-ios-personadd:before,.ion-ios-personadd-outline:before,.ion-ios-photos:before,.ion-ios-photos-outline:before,.ion-ios-pie:before,.ion-ios-pie-outline:before,.ion-ios-pint:before,.ion-ios-pint-outline:before,.ion-ios-play:before,.ion-ios-play-outline:before,.ion-ios-plus:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetags:before,.ion-ios-pricetags-outline:before,.ion-ios-printer:before,.ion-ios-printer-outline:before,.ion-ios-pulse:before,.ion-ios-pulse-strong:before,.ion-ios-rainy:before,.ion-ios-rainy-outline:before,.ion-ios-recording:before,.ion-ios-recording-outline:before,.ion-ios-redo:before,.ion-ios-redo-outline:before,.ion-ios-refresh:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-reload:before,.ion-ios-reverse-camera:before,.ion-ios-reverse-camera-outline:before,.ion-ios-rewind:before,.ion-ios-rewind-outline:before,.ion-ios-rose:before,.ion-ios-rose-outline:before,.ion-ios-search:before,.ion-ios-search-strong:before,.ion-ios-settings:before,.ion-ios-settings-strong:before,.ion-ios-shuffle:before,.ion-ios-shuffle-strong:before,.ion-ios-skipbackward:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipforward:before,.ion-ios-skipforward-outline:before,.ion-ios-snowy:before,.ion-ios-speedometer:before,.ion-ios-speedometer-outline:before,.ion-ios-star:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-stopwatch:before,.ion-ios-stopwatch-outline:before,.ion-ios-sunny:before,.ion-ios-sunny-outline:before,.ion-ios-telephone:before,.ion-ios-telephone-outline:before,.ion-ios-tennisball:before,.ion-ios-tennisball-outline:before,.ion-ios-thunderstorm:before,.ion-ios-thunderstorm-outline:before,.ion-ios-time:before,.ion-ios-time-outline:before,.ion-ios-timer:before,.ion-ios-timer-outline:before,.ion-ios-toggle:before,.ion-ios-toggle-outline:before,.ion-ios-trash:before,.ion-ios-trash-outline:before,.ion-ios-undo:before,.ion-ios-undo-outline:before,.ion-ios-unlocked:before,.ion-ios-unlocked-outline:before,.ion-ios-upload:before,.ion-ios-upload-outline:before,.ion-ios-videocam:before,.ion-ios-videocam-outline:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass:before,.ion-ios-wineglass-outline:before,.ion-ios-world:before,.ion-ios-world-outline:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon:before,.ion-navicon-round:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person:before,.ion-person-add:before,.ion-person-stalker:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply:before,.ion-reply-all:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad:before,.ion-sad-outline:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android:before,.ion-social-android-outline:before,.ion-social-angular:before,.ion-social-angular-outline:before,.ion-social-apple:before,.ion-social-apple-outline:before,.ion-social-bitcoin:before,.ion-social-bitcoin-outline:before,.ion-social-buffer:before,.ion-social-buffer-outline:before,.ion-social-chrome:before,.ion-social-chrome-outline:before,.ion-social-codepen:before,.ion-social-codepen-outline:before,.ion-social-css3:before,.ion-social-css3-outline:before,.ion-social-designernews:before,.ion-social-designernews-outline:before,.ion-social-dribbble:before,.ion-social-dribbble-outline:before,.ion-social-dropbox:before,.ion-social-dropbox-outline:before,.ion-social-euro:before,.ion-social-euro-outline:before,.ion-social-facebook:before,.ion-social-facebook-outline:before,.ion-social-foursquare:before,.ion-social-foursquare-outline:before,.ion-social-freebsd-devil:before,.ion-social-github:before,.ion-social-github-outline:before,.ion-social-google:before,.ion-social-google-outline:before,.ion-social-googleplus:before,.ion-social-googleplus-outline:before,.ion-social-hackernews:before,.ion-social-hackernews-outline:before,.ion-social-html5:before,.ion-social-html5-outline:before,.ion-social-instagram:before,.ion-social-instagram-outline:before,.ion-social-javascript:before,.ion-social-javascript-outline:before,.ion-social-linkedin:before,.ion-social-linkedin-outline:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest:before,.ion-social-pinterest-outline:before,.ion-social-python:before,.ion-social-reddit:before,.ion-social-reddit-outline:before,.ion-social-rss:before,.ion-social-rss-outline:before,.ion-social-sass:before,.ion-social-skype:before,.ion-social-skype-outline:before,.ion-social-snapchat:before,.ion-social-snapchat-outline:before,.ion-social-tumblr:before,.ion-social-tumblr-outline:before,.ion-social-tux:before,.ion-social-twitch:before,.ion-social-twitch-outline:before,.ion-social-twitter:before,.ion-social-twitter-outline:before,.ion-social-usd:before,.ion-social-usd-outline:before,.ion-social-vimeo:before,.ion-social-vimeo-outline:before,.ion-social-whatsapp:before,.ion-social-whatsapp-outline:before,.ion-social-windows:before,.ion-social-windows-outline:before,.ion-social-wordpress:before,.ion-social-wordpress-outline:before,.ion-social-yahoo:before,.ion-social-yahoo-outline:before,.ion-social-yen:before,.ion-social-yen-outline:before,.ion-social-youtube:before,.ion-social-youtube-outline:before,.ion-soup-can:before,.ion-soup-can-outline:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle:before,.ion-toggle-filled:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt:before,.ion-tshirt-outline:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.eot b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.eot new file mode 100644 index 0000000..92a3f20 Binary files /dev/null and b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.eot differ diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.svg b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.svg new file mode 100644 index 0000000..49fc8f3 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.svg @@ -0,0 +1,2230 @@ + + + + + +Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014 + By Adam Bradley +Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.ttf b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.ttf new file mode 100644 index 0000000..c4e4632 Binary files /dev/null and b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.ttf differ diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.woff b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.woff new file mode 100644 index 0000000..5f3a14e Binary files /dev/null and b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.woff differ diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/pace.min.js b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/pace.min.js new file mode 100644 index 0000000..234f9b3 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/pace.min.js @@ -0,0 +1,2 @@ +/*! pace 1.0.2 */ +(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X=[].slice,Y={}.hasOwnProperty,Z=function(a,b){function c(){this.constructor=a}for(var d in b)Y.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},$=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};for(u={catchupTime:100,initialRate:.03,minTime:250,ghostTime:100,maxProgressPerFrame:20,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},C=function(){var a;return null!=(a="undefined"!=typeof performance&&null!==performance&&"function"==typeof performance.now?performance.now():void 0)?a:+new Date},E=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame,null==E&&(E=function(a){return setTimeout(a,50)},t=function(a){return clearTimeout(a)}),G=function(a){var b,c;return b=C(),(c=function(){var d;return d=C()-b,d>=33?(b=C(),a(d,function(){return E(c)})):setTimeout(c,33-d)})()},F=function(){var a,b,c;return c=arguments[0],b=arguments[1],a=3<=arguments.length?X.call(arguments,2):[],"function"==typeof c[b]?c[b].apply(c,a):c[b]},v=function(){var a,b,c,d,e,f,g;for(b=arguments[0],d=2<=arguments.length?X.call(arguments,1):[],f=0,g=d.length;g>f;f++)if(c=d[f])for(a in c)Y.call(c,a)&&(e=c[a],null!=b[a]&&"object"==typeof b[a]&&null!=e&&"object"==typeof e?v(b[a],e):b[a]=e);return b},q=function(a){var b,c,d,e,f;for(c=b=0,e=0,f=a.length;f>e;e++)d=a[e],c+=Math.abs(d),b++;return c/b},x=function(a,b){var c,d,e;if(null==a&&(a="options"),null==b&&(b=!0),e=document.querySelector("[data-pace-"+a+"]")){if(c=e.getAttribute("data-pace-"+a),!b)return c;try{return JSON.parse(c)}catch(f){return d=f,"undefined"!=typeof console&&null!==console?console.error("Error parsing inline pace options",d):void 0}}},g=function(){function a(){}return a.prototype.on=function(a,b,c,d){var e;return null==d&&(d=!1),null==this.bindings&&(this.bindings={}),null==(e=this.bindings)[a]&&(e[a]=[]),this.bindings[a].push({handler:b,ctx:c,once:d})},a.prototype.once=function(a,b,c){return this.on(a,b,c,!0)},a.prototype.off=function(a,b){var c,d,e;if(null!=(null!=(d=this.bindings)?d[a]:void 0)){if(null==b)return delete this.bindings[a];for(c=0,e=[];cQ;Q++)K=U[Q],D[K]===!0&&(D[K]=u[K]);i=function(a){function b(){return V=b.__super__.constructor.apply(this,arguments)}return Z(b,a),b}(Error),b=function(){function a(){this.progress=0}return a.prototype.getElement=function(){var a;if(null==this.el){if(a=document.querySelector(D.target),!a)throw new i;this.el=document.createElement("div"),this.el.className="pace pace-active",document.body.className=document.body.className.replace(/pace-done/g,""),document.body.className+=" pace-running",this.el.innerHTML='
\n
\n
\n
',null!=a.firstChild?a.insertBefore(this.el,a.firstChild):a.appendChild(this.el)}return this.el},a.prototype.finish=function(){var a;return a=this.getElement(),a.className=a.className.replace("pace-active",""),a.className+=" pace-inactive",document.body.className=document.body.className.replace("pace-running",""),document.body.className+=" pace-done"},a.prototype.update=function(a){return this.progress=a,this.render()},a.prototype.destroy=function(){try{this.getElement().parentNode.removeChild(this.getElement())}catch(a){i=a}return this.el=void 0},a.prototype.render=function(){var a,b,c,d,e,f,g;if(null==document.querySelector(D.target))return!1;for(a=this.getElement(),d="translate3d("+this.progress+"%, 0, 0)",g=["webkitTransform","msTransform","transform"],e=0,f=g.length;f>e;e++)b=g[e],a.children[0].style[b]=d;return(!this.lastRenderedProgress||this.lastRenderedProgress|0!==this.progress|0)&&(a.children[0].setAttribute("data-progress-text",""+(0|this.progress)+"%"),this.progress>=100?c="99":(c=this.progress<10?"0":"",c+=0|this.progress),a.children[0].setAttribute("data-progress",""+c)),this.lastRenderedProgress=this.progress},a.prototype.done=function(){return this.progress>=100},a}(),h=function(){function a(){this.bindings={}}return a.prototype.trigger=function(a,b){var c,d,e,f,g;if(null!=this.bindings[a]){for(f=this.bindings[a],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.call(this,b));return g}},a.prototype.on=function(a,b){var c;return null==(c=this.bindings)[a]&&(c[a]=[]),this.bindings[a].push(b)},a}(),P=window.XMLHttpRequest,O=window.XDomainRequest,N=window.WebSocket,w=function(a,b){var c,d,e;e=[];for(d in b.prototype)try{e.push(null==a[d]&&"function"!=typeof b[d]?"function"==typeof Object.defineProperty?Object.defineProperty(a,d,{get:function(){return b.prototype[d]},configurable:!0,enumerable:!0}):a[d]=b.prototype[d]:void 0)}catch(f){c=f}return e},A=[],j.ignore=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("ignore"),c=b.apply(null,a),A.shift(),c},j.track=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("track"),c=b.apply(null,a),A.shift(),c},J=function(a){var b;if(null==a&&(a="GET"),"track"===A[0])return"force";if(!A.length&&D.ajax){if("socket"===a&&D.ajax.trackWebSockets)return!0;if(b=a.toUpperCase(),$.call(D.ajax.trackMethods,b)>=0)return!0}return!1},k=function(a){function b(){var a,c=this;b.__super__.constructor.apply(this,arguments),a=function(a){var b;return b=a.open,a.open=function(d,e){return J(d)&&c.trigger("request",{type:d,url:e,request:a}),b.apply(a,arguments)}},window.XMLHttpRequest=function(b){var c;return c=new P(b),a(c),c};try{w(window.XMLHttpRequest,P)}catch(d){}if(null!=O){window.XDomainRequest=function(){var b;return b=new O,a(b),b};try{w(window.XDomainRequest,O)}catch(d){}}if(null!=N&&D.ajax.trackWebSockets){window.WebSocket=function(a,b){var d;return d=null!=b?new N(a,b):new N(a),J("socket")&&c.trigger("request",{type:"socket",url:a,protocols:b,request:d}),d};try{w(window.WebSocket,N)}catch(d){}}}return Z(b,a),b}(h),R=null,y=function(){return null==R&&(R=new k),R},I=function(a){var b,c,d,e;for(e=D.ajax.ignoreURLs,c=0,d=e.length;d>c;c++)if(b=e[c],"string"==typeof b){if(-1!==a.indexOf(b))return!0}else if(b.test(a))return!0;return!1},y().on("request",function(b){var c,d,e,f,g;return f=b.type,e=b.request,g=b.url,I(g)?void 0:j.running||D.restartOnRequestAfter===!1&&"force"!==J(f)?void 0:(d=arguments,c=D.restartOnRequestAfter||0,"boolean"==typeof c&&(c=0),setTimeout(function(){var b,c,g,h,i,k;if(b="socket"===f?e.readyState<2:0<(h=e.readyState)&&4>h){for(j.restart(),i=j.sources,k=[],c=0,g=i.length;g>c;c++){if(K=i[c],K instanceof a){K.watch.apply(K,d);break}k.push(void 0)}return k}},c))}),a=function(){function a(){var a=this;this.elements=[],y().on("request",function(){return a.watch.apply(a,arguments)})}return a.prototype.watch=function(a){var b,c,d,e;return d=a.type,b=a.request,e=a.url,I(e)?void 0:(c="socket"===d?new n(b):new o(b),this.elements.push(c))},a}(),o=function(){function a(a){var b,c,d,e,f,g,h=this;if(this.progress=0,null!=window.ProgressEvent)for(c=null,a.addEventListener("progress",function(a){return h.progress=a.lengthComputable?100*a.loaded/a.total:h.progress+(100-h.progress)/2},!1),g=["load","abort","timeout","error"],d=0,e=g.length;e>d;d++)b=g[d],a.addEventListener(b,function(){return h.progress=100},!1);else f=a.onreadystatechange,a.onreadystatechange=function(){var b;return 0===(b=a.readyState)||4===b?h.progress=100:3===a.readyState&&(h.progress=50),"function"==typeof f?f.apply(null,arguments):void 0}}return a}(),n=function(){function a(a){var b,c,d,e,f=this;for(this.progress=0,e=["error","open"],c=0,d=e.length;d>c;c++)b=e[c],a.addEventListener(b,function(){return f.progress=100},!1)}return a}(),d=function(){function a(a){var b,c,d,f;for(null==a&&(a={}),this.elements=[],null==a.selectors&&(a.selectors=[]),f=a.selectors,c=0,d=f.length;d>c;c++)b=f[c],this.elements.push(new e(b))}return a}(),e=function(){function a(a){this.selector=a,this.progress=0,this.check()}return a.prototype.check=function(){var a=this;return document.querySelector(this.selector)?this.done():setTimeout(function(){return a.check()},D.elements.checkInterval)},a.prototype.done=function(){return this.progress=100},a}(),c=function(){function a(){var a,b,c=this;this.progress=null!=(b=this.states[document.readyState])?b:100,a=document.onreadystatechange,document.onreadystatechange=function(){return null!=c.states[document.readyState]&&(c.progress=c.states[document.readyState]),"function"==typeof a?a.apply(null,arguments):void 0}}return a.prototype.states={loading:0,interactive:50,complete:100},a}(),f=function(){function a(){var a,b,c,d,e,f=this;this.progress=0,a=0,e=[],d=0,c=C(),b=setInterval(function(){var g;return g=C()-c-50,c=C(),e.push(g),e.length>D.eventLag.sampleCount&&e.shift(),a=q(e),++d>=D.eventLag.minSamples&&a=100&&(this.done=!0),b===this.last?this.sinceLastUpdate+=a:(this.sinceLastUpdate&&(this.rate=(b-this.last)/this.sinceLastUpdate),this.catchup=(b-this.progress)/D.catchupTime,this.sinceLastUpdate=0,this.last=b),b>this.progress&&(this.progress+=this.catchup*a),c=1-Math.pow(this.progress/100,D.easeFactor),this.progress+=c*this.rate*a,this.progress=Math.min(this.lastProgress+D.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},a}(),L=null,H=null,r=null,M=null,p=null,s=null,j.running=!1,z=function(){return D.restartOnPushState?j.restart():void 0},null!=window.history.pushState&&(T=window.history.pushState,window.history.pushState=function(){return z(),T.apply(window.history,arguments)}),null!=window.history.replaceState&&(W=window.history.replaceState,window.history.replaceState=function(){return z(),W.apply(window.history,arguments)}),l={ajax:a,elements:d,document:c,eventLag:f},(B=function(){var a,c,d,e,f,g,h,i;for(j.sources=L=[],g=["ajax","elements","document","eventLag"],c=0,e=g.length;e>c;c++)a=g[c],D[a]!==!1&&L.push(new l[a](D[a]));for(i=null!=(h=D.extraSources)?h:[],d=0,f=i.length;f>d;d++)K=i[d],L.push(new K(D));return j.bar=r=new b,H=[],M=new m})(),j.stop=function(){return j.trigger("stop"),j.running=!1,r.destroy(),s=!0,null!=p&&("function"==typeof t&&t(p),p=null),B()},j.restart=function(){return j.trigger("restart"),j.stop(),j.start()},j.go=function(){var a;return j.running=!0,r.render(),a=C(),s=!1,p=G(function(b,c){var d,e,f,g,h,i,k,l,n,o,p,q,t,u,v,w;for(l=100-r.progress,e=p=0,f=!0,i=q=0,u=L.length;u>q;i=++q)for(K=L[i],o=null!=H[i]?H[i]:H[i]=[],h=null!=(w=K.elements)?w:[K],k=t=0,v=h.length;v>t;k=++t)g=h[k],n=null!=o[k]?o[k]:o[k]=new m(g),f&=n.done,n.done||(e++,p+=n.tick(b));return d=p/e,r.update(M.tick(b,d)),r.done()||f||s?(r.update(100),j.trigger("done"),setTimeout(function(){return r.finish(),j.running=!1,j.trigger("hide")},Math.max(D.ghostTime,Math.max(D.minTime-(C()-a),0)))):c()})},j.start=function(a){v(D,a),j.running=!0;try{r.render()}catch(b){i=b}return document.querySelector(".pace")?(j.trigger("start"),j.go()):setTimeout(j.start,50)},"function"==typeof define&&define.amd?define(["pace"],function(){return j}):"object"==typeof exports?module.exports=j:D.startOnPageLoad&&j.start()}).call(this); \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/themes/blue/pace-theme-flash.css b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/themes/blue/pace-theme-flash.css new file mode 100644 index 0000000..d9bca46 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/PACE/themes/blue/pace-theme-flash.css @@ -0,0 +1,77 @@ +/* This is a compiled file, you should be editing the file in the templates directory */ +.pace { + -webkit-pointer-events: none; + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pace-inactive { + display: none; +} + +.pace .pace-progress { + background: #2299dd; + position: fixed; + z-index: 2000; + top: 0; + right: 100%; + width: 100%; + height: 2px; +} + +.pace .pace-progress-inner { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #2299dd, 0 0 5px #2299dd; + opacity: 1.0; + -webkit-transform: rotate(3deg) translate(0px, -4px); + -moz-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + -o-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +.pace .pace-activity { + display: block; + position: fixed; + z-index: 2000; + top: 15px; + right: 15px; + width: 14px; + height: 14px; + border: solid 2px transparent; + border-top-color: #2299dd; + border-left-color: #2299dd; + border-radius: 10px; + -webkit-animation: pace-spinner 400ms linear infinite; + -moz-animation: pace-spinner 400ms linear infinite; + -ms-animation: pace-spinner 400ms linear infinite; + -o-animation: pace-spinner 400ms linear infinite; + animation: pace-spinner 400ms linear infinite; +} + +@-webkit-keyframes pace-spinner { + 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } +} +@-moz-keyframes pace-spinner { + 0% { -moz-transform: rotate(0deg); transform: rotate(0deg); } + 100% { -moz-transform: rotate(360deg); transform: rotate(360deg); } +} +@-o-keyframes pace-spinner { + 0% { -o-transform: rotate(0deg); transform: rotate(0deg); } + 100% { -o-transform: rotate(360deg); transform: rotate(360deg); } +} +@-ms-keyframes pace-spinner { + 0% { -ms-transform: rotate(0deg); transform: rotate(0deg); } + 100% { -ms-transform: rotate(360deg); transform: rotate(360deg); } +} +@keyframes pace-spinner { + 0% { transform: rotate(0deg); transform: rotate(0deg); } + 100% { transform: rotate(360deg); transform: rotate(360deg); } +} diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.css b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.css new file mode 100644 index 0000000..86f4b77 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.css @@ -0,0 +1,269 @@ +.daterangepicker { + position: absolute; + color: inherit; + background-color: #fff; + border-radius: 4px; + width: 278px; + padding: 4px; + margin-top: 1px; + top: 100px; + left: 20px; + /* Calendars */ } + .daterangepicker:before, .daterangepicker:after { + position: absolute; + display: inline-block; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; } + .daterangepicker:before { + top: -7px; + border-right: 7px solid transparent; + border-left: 7px solid transparent; + border-bottom: 7px solid #ccc; } + .daterangepicker:after { + top: -6px; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; } + .daterangepicker.opensleft:before { + right: 9px; } + .daterangepicker.opensleft:after { + right: 10px; } + .daterangepicker.openscenter:before { + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; } + .daterangepicker.openscenter:after { + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; } + .daterangepicker.opensright:before { + left: 9px; } + .daterangepicker.opensright:after { + left: 10px; } + .daterangepicker.dropup { + margin-top: -5px; } + .daterangepicker.dropup:before { + top: initial; + bottom: -7px; + border-bottom: initial; + border-top: 7px solid #ccc; } + .daterangepicker.dropup:after { + top: initial; + bottom: -6px; + border-bottom: initial; + border-top: 6px solid #fff; } + .daterangepicker.dropdown-menu { + max-width: none; + z-index: 3001; } + .daterangepicker.single .ranges, .daterangepicker.single .calendar { + float: none; } + .daterangepicker.show-calendar .calendar { + display: block; } + .daterangepicker .calendar { + display: none; + max-width: 270px; + margin: 4px; } + .daterangepicker .calendar.single .calendar-table { + border: none; } + .daterangepicker .calendar th, .daterangepicker .calendar td { + white-space: nowrap; + text-align: center; + min-width: 32px; } + .daterangepicker .calendar-table { + border: 1px solid #fff; + padding: 4px; + border-radius: 4px; + background-color: #fff; } + .daterangepicker table { + width: 100%; + margin: 0; } + .daterangepicker td, .daterangepicker th { + text-align: center; + width: 20px; + height: 20px; + border-radius: 4px; + border: 1px solid transparent; + white-space: nowrap; + cursor: pointer; } + .daterangepicker td.available:hover, .daterangepicker th.available:hover { + background-color: #eee; + border-color: transparent; + color: inherit; } + .daterangepicker td.week, .daterangepicker th.week { + font-size: 80%; + color: #ccc; } + .daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { + background-color: #fff; + border-color: transparent; + color: #999; } + .daterangepicker td.in-range { + background-color: #ebf4f8; + border-color: transparent; + color: #000; + border-radius: 0; } + .daterangepicker td.start-date { + border-radius: 4px 0 0 4px; } + .daterangepicker td.end-date { + border-radius: 0 4px 4px 0; } + .daterangepicker td.start-date.end-date { + border-radius: 4px; } + .daterangepicker td.active, .daterangepicker td.active:hover { + background-color: #357ebd; + border-color: transparent; + color: #fff; } + .daterangepicker th.month { + width: auto; } + .daterangepicker td.disabled, .daterangepicker option.disabled { + color: #999; + cursor: not-allowed; + text-decoration: line-through; } + .daterangepicker select.monthselect, .daterangepicker select.yearselect { + font-size: 12px; + padding: 1px; + height: auto; + margin: 0; + cursor: default; } + .daterangepicker select.monthselect { + margin-right: 2%; + width: 56%; } + .daterangepicker select.yearselect { + width: 40%; } + .daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { + width: 50px; + margin-bottom: 0; } + .daterangepicker .input-mini { + border: 1px solid #ccc; + border-radius: 4px; + color: #555; + height: 30px; + line-height: 30px; + display: block; + vertical-align: middle; + margin: 0 0 5px 0; + padding: 0 6px 0 28px; + width: 100%; } + .daterangepicker .input-mini.active { + border: 1px solid #08c; + border-radius: 4px; } + .daterangepicker .daterangepicker_input { + position: relative; } + .daterangepicker .daterangepicker_input i { + position: absolute; + left: 8px; + top: 8px; } + .daterangepicker.rtl .input-mini { + padding-right: 28px; + padding-left: 6px; } + .daterangepicker.rtl .daterangepicker_input i { + left: auto; + right: 8px; } + .daterangepicker .calendar-time { + text-align: center; + margin: 5px auto; + line-height: 30px; + position: relative; + padding-left: 28px; } + .daterangepicker .calendar-time select.disabled { + color: #ccc; + cursor: not-allowed; } + +.ranges { + font-size: 11px; + float: none; + margin: 4px; + text-align: left; } + .ranges ul { + list-style: none; + margin: 0 auto; + padding: 0; + width: 100%; } + .ranges li { + font-size: 13px; + background-color: #f5f5f5; + border: 1px solid #f5f5f5; + border-radius: 4px; + color: #08c; + padding: 3px 12px; + margin-bottom: 8px; + cursor: pointer; } + .ranges li:hover { + background-color: #08c; + border: 1px solid #08c; + color: #fff; } + .ranges li.active { + background-color: #08c; + border: 1px solid #08c; + color: #fff; } + +/* Larger Screen Styling */ +@media (min-width: 564px) { + .daterangepicker { + width: auto; } + .daterangepicker .ranges ul { + width: 160px; } + .daterangepicker.single .ranges ul { + width: 100%; } + .daterangepicker.single .calendar.left { + clear: none; } + .daterangepicker.single.ltr .ranges, .daterangepicker.single.ltr .calendar { + float: left; } + .daterangepicker.single.rtl .ranges, .daterangepicker.single.rtl .calendar { + float: right; } + .daterangepicker.ltr { + direction: ltr; + text-align: left; } + .daterangepicker.ltr .calendar.left { + clear: left; + margin-right: 0; } + .daterangepicker.ltr .calendar.left .calendar-table { + border-right: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; } + .daterangepicker.ltr .calendar.right { + margin-left: 0; } + .daterangepicker.ltr .calendar.right .calendar-table { + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; } + .daterangepicker.ltr .left .daterangepicker_input { + padding-right: 12px; } + .daterangepicker.ltr .calendar.left .calendar-table { + padding-right: 12px; } + .daterangepicker.ltr .ranges, .daterangepicker.ltr .calendar { + float: left; } + .daterangepicker.rtl { + direction: rtl; + text-align: right; } + .daterangepicker.rtl .calendar.left { + clear: right; + margin-left: 0; } + .daterangepicker.rtl .calendar.left .calendar-table { + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; } + .daterangepicker.rtl .calendar.right { + margin-right: 0; } + .daterangepicker.rtl .calendar.right .calendar-table { + border-right: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; } + .daterangepicker.rtl .left .daterangepicker_input { + padding-left: 12px; } + .daterangepicker.rtl .calendar.left .calendar-table { + padding-left: 12px; } + .daterangepicker.rtl .ranges, .daterangepicker.rtl .calendar { + text-align: right; + float: right; } } +@media (min-width: 730px) { + .daterangepicker .ranges { + width: auto; } + .daterangepicker.ltr .ranges { + float: left; } + .daterangepicker.rtl .ranges { + float: right; } + .daterangepicker .calendar.left { + clear: none !important; } } diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.js b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.js new file mode 100644 index 0000000..079cde6 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap-daterangepicker/daterangepicker.js @@ -0,0 +1,1653 @@ +/** +* @version: 2.1.27 +* @author: Dan Grossman http://www.dangrossman.info/ +* @copyright: Copyright (c) 2012-2017 Dan Grossman. All rights reserved. +* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php +* @website: http://www.daterangepicker.com/ +*/ +// Follow the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Make globaly available as well + define(['moment', 'jquery'], function (moment, jquery) { + if (!jquery.fn) jquery.fn = {}; // webpack server rendering + return factory(moment, jquery); + }); + } else if (typeof module === 'object' && module.exports) { + // Node / Browserify + //isomorphic issue + var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined; + if (!jQuery) { + jQuery = require('jquery'); + if (!jQuery.fn) jQuery.fn = {}; + } + var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment'); + module.exports = factory(moment, jQuery); + } else { + // Browser globals + root.daterangepicker = factory(root.moment, root.jQuery); + } +}(this, function(moment, $) { + var DateRangePicker = function(element, options, cb) { + + //default settings for options + this.parentEl = 'body'; + this.element = $(element); + this.startDate = moment().startOf('day'); + this.endDate = moment().endOf('day'); + this.minDate = false; + this.maxDate = false; + this.dateLimit = false; + this.autoApply = false; + this.singleDatePicker = false; + this.showDropdowns = false; + this.showWeekNumbers = false; + this.showISOWeekNumbers = false; + this.showCustomRangeLabel = true; + this.timePicker = false; + this.timePicker24Hour = false; + this.timePickerIncrement = 1; + this.timePickerSeconds = false; + this.linkedCalendars = true; + this.autoUpdateInput = true; + this.alwaysShowCalendars = false; + this.ranges = {}; + + this.opens = 'right'; + if (this.element.hasClass('pull-right')) + this.opens = 'left'; + + this.drops = 'down'; + if (this.element.hasClass('dropup')) + this.drops = 'up'; + + this.buttonClasses = 'btn btn-sm'; + this.applyClass = 'btn-success'; + this.cancelClass = 'btn-default'; + + this.locale = { + direction: 'ltr', + format: moment.localeData().longDateFormat('L'), + separator: ' - ', + applyLabel: 'Apply', + cancelLabel: 'Cancel', + weekLabel: 'W', + customRangeLabel: 'Custom Range', + daysOfWeek: moment.weekdaysMin(), + monthNames: moment.monthsShort(), + firstDay: moment.localeData().firstDayOfWeek() + }; + + this.callback = function() { }; + + //some state information + this.isShowing = false; + this.leftCalendar = {}; + this.rightCalendar = {}; + + //custom options from user + if (typeof options !== 'object' || options === null) + options = {}; + + //allow setting options with data attributes + //data-api options will be overwritten with custom javascript options + options = $.extend(this.element.data(), options); + + //html template for the picker UI + if (typeof options.template !== 'string' && !(options.template instanceof $)) + options.template = ''; + + this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl); + this.container = $(options.template).appendTo(this.parentEl); + + // + // handle all the possible options overriding defaults + // + + if (typeof options.locale === 'object') { + + if (typeof options.locale.direction === 'string') + this.locale.direction = options.locale.direction; + + if (typeof options.locale.format === 'string') + this.locale.format = options.locale.format; + + if (typeof options.locale.separator === 'string') + this.locale.separator = options.locale.separator; + + if (typeof options.locale.daysOfWeek === 'object') + this.locale.daysOfWeek = options.locale.daysOfWeek.slice(); + + if (typeof options.locale.monthNames === 'object') + this.locale.monthNames = options.locale.monthNames.slice(); + + if (typeof options.locale.firstDay === 'number') + this.locale.firstDay = options.locale.firstDay; + + if (typeof options.locale.applyLabel === 'string') + this.locale.applyLabel = options.locale.applyLabel; + + if (typeof options.locale.cancelLabel === 'string') + this.locale.cancelLabel = options.locale.cancelLabel; + + if (typeof options.locale.weekLabel === 'string') + this.locale.weekLabel = options.locale.weekLabel; + + if (typeof options.locale.customRangeLabel === 'string'){ + //Support unicode chars in the custom range name. + var elem = document.createElement('textarea'); + elem.innerHTML = options.locale.customRangeLabel; + var rangeHtml = elem.value; + this.locale.customRangeLabel = rangeHtml; + } + } + this.container.addClass(this.locale.direction); + + if (typeof options.startDate === 'string') + this.startDate = moment(options.startDate, this.locale.format); + + if (typeof options.endDate === 'string') + this.endDate = moment(options.endDate, this.locale.format); + + if (typeof options.minDate === 'string') + this.minDate = moment(options.minDate, this.locale.format); + + if (typeof options.maxDate === 'string') + this.maxDate = moment(options.maxDate, this.locale.format); + + if (typeof options.startDate === 'object') + this.startDate = moment(options.startDate); + + if (typeof options.endDate === 'object') + this.endDate = moment(options.endDate); + + if (typeof options.minDate === 'object') + this.minDate = moment(options.minDate); + + if (typeof options.maxDate === 'object') + this.maxDate = moment(options.maxDate); + + // sanity check for bad options + if (this.minDate && this.startDate.isBefore(this.minDate)) + this.startDate = this.minDate.clone(); + + // sanity check for bad options + if (this.maxDate && this.endDate.isAfter(this.maxDate)) + this.endDate = this.maxDate.clone(); + + if (typeof options.applyClass === 'string') + this.applyClass = options.applyClass; + + if (typeof options.cancelClass === 'string') + this.cancelClass = options.cancelClass; + + if (typeof options.dateLimit === 'object') + this.dateLimit = options.dateLimit; + + if (typeof options.opens === 'string') + this.opens = options.opens; + + if (typeof options.drops === 'string') + this.drops = options.drops; + + if (typeof options.showWeekNumbers === 'boolean') + this.showWeekNumbers = options.showWeekNumbers; + + if (typeof options.showISOWeekNumbers === 'boolean') + this.showISOWeekNumbers = options.showISOWeekNumbers; + + if (typeof options.buttonClasses === 'string') + this.buttonClasses = options.buttonClasses; + + if (typeof options.buttonClasses === 'object') + this.buttonClasses = options.buttonClasses.join(' '); + + if (typeof options.showDropdowns === 'boolean') + this.showDropdowns = options.showDropdowns; + + if (typeof options.showCustomRangeLabel === 'boolean') + this.showCustomRangeLabel = options.showCustomRangeLabel; + + if (typeof options.singleDatePicker === 'boolean') { + this.singleDatePicker = options.singleDatePicker; + if (this.singleDatePicker) + this.endDate = this.startDate.clone(); + } + + if (typeof options.timePicker === 'boolean') + this.timePicker = options.timePicker; + + if (typeof options.timePickerSeconds === 'boolean') + this.timePickerSeconds = options.timePickerSeconds; + + if (typeof options.timePickerIncrement === 'number') + this.timePickerIncrement = options.timePickerIncrement; + + if (typeof options.timePicker24Hour === 'boolean') + this.timePicker24Hour = options.timePicker24Hour; + + if (typeof options.autoApply === 'boolean') + this.autoApply = options.autoApply; + + if (typeof options.autoUpdateInput === 'boolean') + this.autoUpdateInput = options.autoUpdateInput; + + if (typeof options.linkedCalendars === 'boolean') + this.linkedCalendars = options.linkedCalendars; + + if (typeof options.isInvalidDate === 'function') + this.isInvalidDate = options.isInvalidDate; + + if (typeof options.isCustomDate === 'function') + this.isCustomDate = options.isCustomDate; + + if (typeof options.alwaysShowCalendars === 'boolean') + this.alwaysShowCalendars = options.alwaysShowCalendars; + + // update day names order to firstDay + if (this.locale.firstDay != 0) { + var iterator = this.locale.firstDay; + while (iterator > 0) { + this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); + iterator--; + } + } + + var start, end, range; + + //if no start/end dates set, check if an input element contains initial values + if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') { + if ($(this.element).is('input[type=text]')) { + var val = $(this.element).val(), + split = val.split(this.locale.separator); + + start = end = null; + + if (split.length == 2) { + start = moment(split[0], this.locale.format); + end = moment(split[1], this.locale.format); + } else if (this.singleDatePicker && val !== "") { + start = moment(val, this.locale.format); + end = moment(val, this.locale.format); + } + if (start !== null && end !== null) { + this.setStartDate(start); + this.setEndDate(end); + } + } + } + + if (typeof options.ranges === 'object') { + for (range in options.ranges) { + + if (typeof options.ranges[range][0] === 'string') + start = moment(options.ranges[range][0], this.locale.format); + else + start = moment(options.ranges[range][0]); + + if (typeof options.ranges[range][1] === 'string') + end = moment(options.ranges[range][1], this.locale.format); + else + end = moment(options.ranges[range][1]); + + // If the start or end date exceed those allowed by the minDate or dateLimit + // options, shorten the range to the allowable period. + if (this.minDate && start.isBefore(this.minDate)) + start = this.minDate.clone(); + + var maxDate = this.maxDate; + if (this.dateLimit && maxDate && start.clone().add(this.dateLimit).isAfter(maxDate)) + maxDate = start.clone().add(this.dateLimit); + if (maxDate && end.isAfter(maxDate)) + end = maxDate.clone(); + + // If the end of the range is before the minimum or the start of the range is + // after the maximum, don't display this range option at all. + if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day')) + || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day'))) + continue; + + //Support unicode chars in the range names. + var elem = document.createElement('textarea'); + elem.innerHTML = range; + var rangeHtml = elem.value; + + this.ranges[rangeHtml] = [start, end]; + } + + var list = '
    '; + for (range in this.ranges) { + list += '
  • ' + range + '
  • '; + } + if (this.showCustomRangeLabel) { + list += '
  • ' + this.locale.customRangeLabel + '
  • '; + } + list += '
'; + this.container.find('.ranges').prepend(list); + } + + if (typeof cb === 'function') { + this.callback = cb; + } + + if (!this.timePicker) { + this.startDate = this.startDate.startOf('day'); + this.endDate = this.endDate.endOf('day'); + this.container.find('.calendar-time').hide(); + } + + //can't be used together for now + if (this.timePicker && this.autoApply) + this.autoApply = false; + + if (this.autoApply && typeof options.ranges !== 'object') { + this.container.find('.ranges').hide(); + } else if (this.autoApply) { + this.container.find('.applyBtn, .cancelBtn').addClass('hide'); + } + + if (this.singleDatePicker) { + this.container.addClass('single'); + this.container.find('.calendar.left').addClass('single'); + this.container.find('.calendar.left').show(); + this.container.find('.calendar.right').hide(); + this.container.find('.daterangepicker_input input, .daterangepicker_input > i').hide(); + if (this.timePicker) { + this.container.find('.ranges ul').hide(); + } else { + this.container.find('.ranges').hide(); + } + } + + if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) { + this.container.addClass('show-calendar'); + } + + this.container.addClass('opens' + this.opens); + + //swap the position of the predefined ranges if opens right + if (typeof options.ranges !== 'undefined' && this.opens == 'right') { + this.container.find('.ranges').prependTo( this.container.find('.calendar.left').parent() ); + } + + //apply CSS classes and labels to buttons + this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses); + if (this.applyClass.length) + this.container.find('.applyBtn').addClass(this.applyClass); + if (this.cancelClass.length) + this.container.find('.cancelBtn').addClass(this.cancelClass); + this.container.find('.applyBtn').html(this.locale.applyLabel); + this.container.find('.cancelBtn').html(this.locale.cancelLabel); + + // + // event listeners + // + + this.container.find('.calendar') + .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this)) + .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this)) + .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this)) + .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)) + .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this)) + .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this)) + .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this)) + .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)) + .on('click.daterangepicker', '.daterangepicker_input input', $.proxy(this.showCalendars, this)) + .on('focus.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsFocused, this)) + .on('blur.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsBlurred, this)) + .on('change.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this)) + .on('keydown.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsKeydown, this)); + + this.container.find('.ranges') + .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)) + .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)) + .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)) + .on('mouseenter.daterangepicker', 'li', $.proxy(this.hoverRange, this)) + .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this)); + + if (this.element.is('input') || this.element.is('button')) { + this.element.on({ + 'click.daterangepicker': $.proxy(this.show, this), + 'focus.daterangepicker': $.proxy(this.show, this), + 'keyup.daterangepicker': $.proxy(this.elementChanged, this), + 'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility + }); + } else { + this.element.on('click.daterangepicker', $.proxy(this.toggle, this)); + this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this)); + } + + // + // if attached to a text input, set the initial value + // + + if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) { + this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format)); + this.element.trigger('change'); + } else if (this.element.is('input') && this.autoUpdateInput) { + this.element.val(this.startDate.format(this.locale.format)); + this.element.trigger('change'); + } + + }; + + DateRangePicker.prototype = { + + constructor: DateRangePicker, + + setStartDate: function(startDate) { + if (typeof startDate === 'string') + this.startDate = moment(startDate, this.locale.format); + + if (typeof startDate === 'object') + this.startDate = moment(startDate); + + if (!this.timePicker) + this.startDate = this.startDate.startOf('day'); + + if (this.timePicker && this.timePickerIncrement) + this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); + + if (this.minDate && this.startDate.isBefore(this.minDate)) { + this.startDate = this.minDate.clone(); + if (this.timePicker && this.timePickerIncrement) + this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); + } + + if (this.maxDate && this.startDate.isAfter(this.maxDate)) { + this.startDate = this.maxDate.clone(); + if (this.timePicker && this.timePickerIncrement) + this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); + } + + if (!this.isShowing) + this.updateElement(); + + this.updateMonthsInView(); + }, + + setEndDate: function(endDate) { + if (typeof endDate === 'string') + this.endDate = moment(endDate, this.locale.format); + + if (typeof endDate === 'object') + this.endDate = moment(endDate); + + if (!this.timePicker) + this.endDate = this.endDate.add(1,'d').startOf('day').subtract(1,'second'); + + if (this.timePicker && this.timePickerIncrement) + this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); + + if (this.endDate.isBefore(this.startDate)) + this.endDate = this.startDate.clone(); + + if (this.maxDate && this.endDate.isAfter(this.maxDate)) + this.endDate = this.maxDate.clone(); + + if (this.dateLimit && this.startDate.clone().add(this.dateLimit).isBefore(this.endDate)) + this.endDate = this.startDate.clone().add(this.dateLimit); + + this.previousRightTime = this.endDate.clone(); + + if (!this.isShowing) + this.updateElement(); + + this.updateMonthsInView(); + }, + + isInvalidDate: function() { + return false; + }, + + isCustomDate: function() { + return false; + }, + + updateView: function() { + if (this.timePicker) { + this.renderTimePicker('left'); + this.renderTimePicker('right'); + if (!this.endDate) { + this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled'); + } else { + this.container.find('.right .calendar-time select').removeAttr('disabled').removeClass('disabled'); + } + } + if (this.endDate) { + this.container.find('input[name="daterangepicker_end"]').removeClass('active'); + this.container.find('input[name="daterangepicker_start"]').addClass('active'); + } else { + this.container.find('input[name="daterangepicker_end"]').addClass('active'); + this.container.find('input[name="daterangepicker_start"]').removeClass('active'); + } + this.updateMonthsInView(); + this.updateCalendars(); + this.updateFormInputs(); + }, + + updateMonthsInView: function() { + if (this.endDate) { + + //if both dates are visible already, do nothing + if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month && + (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) + && + (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) + ) { + return; + } + + this.leftCalendar.month = this.startDate.clone().date(2); + if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) { + this.rightCalendar.month = this.endDate.clone().date(2); + } else { + this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); + } + + } else { + if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) { + this.leftCalendar.month = this.startDate.clone().date(2); + this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); + } + } + if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) { + this.rightCalendar.month = this.maxDate.clone().date(2); + this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month'); + } + }, + + updateCalendars: function() { + + if (this.timePicker) { + var hour, minute, second; + if (this.endDate) { + hour = parseInt(this.container.find('.left .hourselect').val(), 10); + minute = parseInt(this.container.find('.left .minuteselect').val(), 10); + second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; + if (!this.timePicker24Hour) { + var ampm = this.container.find('.left .ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + } else { + hour = parseInt(this.container.find('.right .hourselect').val(), 10); + minute = parseInt(this.container.find('.right .minuteselect').val(), 10); + second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; + if (!this.timePicker24Hour) { + var ampm = this.container.find('.right .ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + } + this.leftCalendar.month.hour(hour).minute(minute).second(second); + this.rightCalendar.month.hour(hour).minute(minute).second(second); + } + + this.renderCalendar('left'); + this.renderCalendar('right'); + + //highlight any predefined range matching the current start and end dates + this.container.find('.ranges li').removeClass('active'); + if (this.endDate == null) return; + + this.calculateChosenLabel(); + }, + + renderCalendar: function(side) { + + // + // Build the matrix of dates that will populate the calendar + // + + var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar; + var month = calendar.month.month(); + var year = calendar.month.year(); + var hour = calendar.month.hour(); + var minute = calendar.month.minute(); + var second = calendar.month.second(); + var daysInMonth = moment([year, month]).daysInMonth(); + var firstDay = moment([year, month, 1]); + var lastDay = moment([year, month, daysInMonth]); + var lastMonth = moment(firstDay).subtract(1, 'month').month(); + var lastYear = moment(firstDay).subtract(1, 'month').year(); + var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth(); + var dayOfWeek = firstDay.day(); + + //initialize a 6 rows x 7 columns array for the calendar + var calendar = []; + calendar.firstDay = firstDay; + calendar.lastDay = lastDay; + + for (var i = 0; i < 6; i++) { + calendar[i] = []; + } + + //populate the calendar with date objects + var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; + if (startDay > daysInLastMonth) + startDay -= 7; + + if (dayOfWeek == this.locale.firstDay) + startDay = daysInLastMonth - 6; + + var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]); + + var col, row; + for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) { + if (i > 0 && col % 7 === 0) { + col = 0; + row++; + } + calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second); + curDate.hour(12); + + if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') { + calendar[row][col] = this.minDate.clone(); + } + + if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') { + calendar[row][col] = this.maxDate.clone(); + } + + } + + //make the calendar object available to hoverDate/clickDate + if (side == 'left') { + this.leftCalendar.calendar = calendar; + } else { + this.rightCalendar.calendar = calendar; + } + + // + // Display the calendar + // + + var minDate = side == 'left' ? this.minDate : this.startDate; + var maxDate = this.maxDate; + var selected = side == 'left' ? this.startDate : this.endDate; + var arrow = this.locale.direction == 'ltr' ? {left: 'chevron-left', right: 'chevron-right'} : {left: 'chevron-right', right: 'chevron-left'}; + + var html = ''; + html += ''; + html += ''; + + // add empty cell for week number + if (this.showWeekNumbers || this.showISOWeekNumbers) + html += ''; + + if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) { + html += ''; + } else { + html += ''; + } + + var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY"); + + if (this.showDropdowns) { + var currentMonth = calendar[1][1].month(); + var currentYear = calendar[1][1].year(); + var maxYear = (maxDate && maxDate.year()) || (currentYear + 5); + var minYear = (minDate && minDate.year()) || (currentYear - 50); + var inMinYear = currentYear == minYear; + var inMaxYear = currentYear == maxYear; + + var monthHtml = '"; + + var yearHtml = ''; + + dateHtml = monthHtml + yearHtml; + } + + html += ''; + if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) { + html += ''; + } else { + html += ''; + } + + html += ''; + html += ''; + + // add week number label + if (this.showWeekNumbers || this.showISOWeekNumbers) + html += ''; + + $.each(this.locale.daysOfWeek, function(index, dayOfWeek) { + html += ''; + }); + + html += ''; + html += ''; + html += ''; + + //adjust maxDate to reflect the dateLimit setting in order to + //grey out end dates beyond the dateLimit + if (this.endDate == null && this.dateLimit) { + var maxLimit = this.startDate.clone().add(this.dateLimit).endOf('day'); + if (!maxDate || maxLimit.isBefore(maxDate)) { + maxDate = maxLimit; + } + } + + for (var row = 0; row < 6; row++) { + html += ''; + + // add week number + if (this.showWeekNumbers) + html += ''; + else if (this.showISOWeekNumbers) + html += ''; + + for (var col = 0; col < 7; col++) { + + var classes = []; + + //highlight today's date + if (calendar[row][col].isSame(new Date(), "day")) + classes.push('today'); + + //highlight weekends + if (calendar[row][col].isoWeekday() > 5) + classes.push('weekend'); + + //grey out the dates in other months displayed at beginning and end of this calendar + if (calendar[row][col].month() != calendar[1][1].month()) + classes.push('off'); + + //don't allow selection of dates before the minimum date + if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day')) + classes.push('off', 'disabled'); + + //don't allow selection of dates after the maximum date + if (maxDate && calendar[row][col].isAfter(maxDate, 'day')) + classes.push('off', 'disabled'); + + //don't allow selection of date if a custom function decides it's invalid + if (this.isInvalidDate(calendar[row][col])) + classes.push('off', 'disabled'); + + //highlight the currently selected start date + if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) + classes.push('active', 'start-date'); + + //highlight the currently selected end date + if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) + classes.push('active', 'end-date'); + + //highlight dates in-between the selected dates + if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate) + classes.push('in-range'); + + //apply custom classes for this date + var isCustom = this.isCustomDate(calendar[row][col]); + if (isCustom !== false) { + if (typeof isCustom === 'string') + classes.push(isCustom); + else + Array.prototype.push.apply(classes, isCustom); + } + + var cname = '', disabled = false; + for (var i = 0; i < classes.length; i++) { + cname += classes[i] + ' '; + if (classes[i] == 'disabled') + disabled = true; + } + if (!disabled) + cname += 'available'; + + html += ''; + + } + html += ''; + } + + html += ''; + html += '
' + dateHtml + '
' + this.locale.weekLabel + '' + dayOfWeek + '
' + calendar[row][0].week() + '' + calendar[row][0].isoWeek() + '' + calendar[row][col].date() + '
'; + + this.container.find('.calendar.' + side + ' .calendar-table').html(html); + + }, + + renderTimePicker: function(side) { + + // Don't bother updating the time picker if it's currently disabled + // because an end date hasn't been clicked yet + if (side == 'right' && !this.endDate) return; + + var html, selected, minDate, maxDate = this.maxDate; + + if (this.dateLimit && (!this.maxDate || this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate))) + maxDate = this.startDate.clone().add(this.dateLimit); + + if (side == 'left') { + selected = this.startDate.clone(); + minDate = this.minDate; + } else if (side == 'right') { + selected = this.endDate.clone(); + minDate = this.startDate; + + //Preserve the time already selected + var timeSelector = this.container.find('.calendar.right .calendar-time div'); + if (timeSelector.html() != '') { + + selected.hour(timeSelector.find('.hourselect option:selected').val() || selected.hour()); + selected.minute(timeSelector.find('.minuteselect option:selected').val() || selected.minute()); + selected.second(timeSelector.find('.secondselect option:selected').val() || selected.second()); + + if (!this.timePicker24Hour) { + var ampm = timeSelector.find('.ampmselect option:selected').val(); + if (ampm === 'PM' && selected.hour() < 12) + selected.hour(selected.hour() + 12); + if (ampm === 'AM' && selected.hour() === 12) + selected.hour(0); + } + + } + + if (selected.isBefore(this.startDate)) + selected = this.startDate.clone(); + + if (maxDate && selected.isAfter(maxDate)) + selected = maxDate.clone(); + + } + + // + // hours + // + + html = ' '; + + // + // minutes + // + + html += ': '; + + // + // seconds + // + + if (this.timePickerSeconds) { + html += ': '; + } + + // + // AM/PM + // + + if (!this.timePicker24Hour) { + html += ''; + } + + this.container.find('.calendar.' + side + ' .calendar-time div').html(html); + + }, + + updateFormInputs: function() { + + //ignore mouse movements while an above-calendar text input has focus + if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) + return; + + this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.locale.format)); + if (this.endDate) + this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.locale.format)); + + if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) { + this.container.find('button.applyBtn').removeAttr('disabled'); + } else { + this.container.find('button.applyBtn').attr('disabled', 'disabled'); + } + + }, + + move: function() { + var parentOffset = { top: 0, left: 0 }, + containerTop; + var parentRightEdge = $(window).width(); + if (!this.parentEl.is('body')) { + parentOffset = { + top: this.parentEl.offset().top - this.parentEl.scrollTop(), + left: this.parentEl.offset().left - this.parentEl.scrollLeft() + }; + parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left; + } + + if (this.drops == 'up') + containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; + else + containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; + this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('dropup'); + + if (this.opens == 'left') { + this.container.css({ + top: containerTop, + right: parentRightEdge - this.element.offset().left - this.element.outerWidth(), + left: 'auto' + }); + if (this.container.offset().left < 0) { + this.container.css({ + right: 'auto', + left: 9 + }); + } + } else if (this.opens == 'center') { + this.container.css({ + top: containerTop, + left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 + - this.container.outerWidth() / 2, + right: 'auto' + }); + if (this.container.offset().left < 0) { + this.container.css({ + right: 'auto', + left: 9 + }); + } + } else { + this.container.css({ + top: containerTop, + left: this.element.offset().left - parentOffset.left, + right: 'auto' + }); + if (this.container.offset().left + this.container.outerWidth() > $(window).width()) { + this.container.css({ + left: 'auto', + right: 0 + }); + } + } + }, + + show: function(e) { + if (this.isShowing) return; + + // Create a click proxy that is private to this instance of datepicker, for unbinding + this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this); + + // Bind global datepicker mousedown for hiding and + $(document) + .on('mousedown.daterangepicker', this._outsideClickProxy) + // also support mobile devices + .on('touchend.daterangepicker', this._outsideClickProxy) + // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them + .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy) + // and also close when focus changes to outside the picker (eg. tabbing between controls) + .on('focusin.daterangepicker', this._outsideClickProxy); + + // Reposition the picker if the window is resized while it's open + $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this)); + + this.oldStartDate = this.startDate.clone(); + this.oldEndDate = this.endDate.clone(); + this.previousRightTime = this.endDate.clone(); + + this.updateView(); + this.container.show(); + this.move(); + this.element.trigger('show.daterangepicker', this); + this.isShowing = true; + }, + + hide: function(e) { + if (!this.isShowing) return; + + //incomplete date selection, revert to last values + if (!this.endDate) { + this.startDate = this.oldStartDate.clone(); + this.endDate = this.oldEndDate.clone(); + } + + //if a new date range was selected, invoke the user callback function + if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) + this.callback(this.startDate, this.endDate, this.chosenLabel); + + //if picker is attached to a text input, update it + this.updateElement(); + + $(document).off('.daterangepicker'); + $(window).off('.daterangepicker'); + this.container.hide(); + this.element.trigger('hide.daterangepicker', this); + this.isShowing = false; + }, + + toggle: function(e) { + if (this.isShowing) { + this.hide(); + } else { + this.show(); + } + }, + + outsideClick: function(e) { + var target = $(e.target); + // if the page is clicked anywhere except within the daterangerpicker/button + // itself then call this.hide() + if ( + // ie modal dialog fix + e.type == "focusin" || + target.closest(this.element).length || + target.closest(this.container).length || + target.closest('.calendar-table').length + ) return; + this.hide(); + this.element.trigger('outsideClick.daterangepicker', this); + }, + + showCalendars: function() { + this.container.addClass('show-calendar'); + this.move(); + this.element.trigger('showCalendar.daterangepicker', this); + }, + + hideCalendars: function() { + this.container.removeClass('show-calendar'); + this.element.trigger('hideCalendar.daterangepicker', this); + }, + + hoverRange: function(e) { + + //ignore mouse movements while an above-calendar text input has focus + if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) + return; + + var label = e.target.getAttribute('data-range-key'); + + if (label == this.locale.customRangeLabel) { + this.updateView(); + } else { + var dates = this.ranges[label]; + this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.locale.format)); + this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.locale.format)); + } + + }, + + clickRange: function(e) { + var label = e.target.getAttribute('data-range-key'); + this.chosenLabel = label; + if (label == this.locale.customRangeLabel) { + this.showCalendars(); + } else { + var dates = this.ranges[label]; + this.startDate = dates[0]; + this.endDate = dates[1]; + + if (!this.timePicker) { + this.startDate.startOf('day'); + this.endDate.endOf('day'); + } + + if (!this.alwaysShowCalendars) + this.hideCalendars(); + this.clickApply(); + } + }, + + clickPrev: function(e) { + var cal = $(e.target).parents('.calendar'); + if (cal.hasClass('left')) { + this.leftCalendar.month.subtract(1, 'month'); + if (this.linkedCalendars) + this.rightCalendar.month.subtract(1, 'month'); + } else { + this.rightCalendar.month.subtract(1, 'month'); + } + this.updateCalendars(); + }, + + clickNext: function(e) { + var cal = $(e.target).parents('.calendar'); + if (cal.hasClass('left')) { + this.leftCalendar.month.add(1, 'month'); + } else { + this.rightCalendar.month.add(1, 'month'); + if (this.linkedCalendars) + this.leftCalendar.month.add(1, 'month'); + } + this.updateCalendars(); + }, + + hoverDate: function(e) { + + //ignore mouse movements while an above-calendar text input has focus + //if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus")) + // return; + + //ignore dates that can't be selected + if (!$(e.target).hasClass('available')) return; + + //have the text inputs above calendars reflect the date being hovered over + var title = $(e.target).attr('data-title'); + var row = title.substr(1, 1); + var col = title.substr(3, 1); + var cal = $(e.target).parents('.calendar'); + var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; + + if (this.endDate && !this.container.find('input[name=daterangepicker_start]').is(":focus")) { + this.container.find('input[name=daterangepicker_start]').val(date.format(this.locale.format)); + } else if (!this.endDate && !this.container.find('input[name=daterangepicker_end]').is(":focus")) { + this.container.find('input[name=daterangepicker_end]').val(date.format(this.locale.format)); + } + + //highlight the dates between the start date and the date being hovered as a potential end date + var leftCalendar = this.leftCalendar; + var rightCalendar = this.rightCalendar; + var startDate = this.startDate; + if (!this.endDate) { + this.container.find('.calendar tbody td').each(function(index, el) { + + //skip week numbers, only look at dates + if ($(el).hasClass('week')) return; + + var title = $(el).attr('data-title'); + var row = title.substr(1, 1); + var col = title.substr(3, 1); + var cal = $(el).parents('.calendar'); + var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col]; + + if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) { + $(el).addClass('in-range'); + } else { + $(el).removeClass('in-range'); + } + + }); + } + + }, + + clickDate: function(e) { + + if (!$(e.target).hasClass('available')) return; + + var title = $(e.target).attr('data-title'); + var row = title.substr(1, 1); + var col = title.substr(3, 1); + var cal = $(e.target).parents('.calendar'); + var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; + + // + // this function needs to do a few things: + // * alternate between selecting a start and end date for the range, + // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date + // * if autoapply is enabled, and an end date was chosen, apply the selection + // * if single date picker mode, and time picker isn't enabled, apply the selection immediately + // * if one of the inputs above the calendars was focused, cancel that manual input + // + + if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start + if (this.timePicker) { + var hour = parseInt(this.container.find('.left .hourselect').val(), 10); + if (!this.timePicker24Hour) { + var ampm = this.container.find('.left .ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + var minute = parseInt(this.container.find('.left .minuteselect').val(), 10); + var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; + date = date.clone().hour(hour).minute(minute).second(second); + } + this.endDate = null; + this.setStartDate(date.clone()); + } else if (!this.endDate && date.isBefore(this.startDate)) { + //special case: clicking the same date for start/end, + //but the time of the end date is before the start date + this.setEndDate(this.startDate.clone()); + } else { // picking end + if (this.timePicker) { + var hour = parseInt(this.container.find('.right .hourselect').val(), 10); + if (!this.timePicker24Hour) { + var ampm = this.container.find('.right .ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + var minute = parseInt(this.container.find('.right .minuteselect').val(), 10); + var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; + date = date.clone().hour(hour).minute(minute).second(second); + } + this.setEndDate(date.clone()); + if (this.autoApply) { + this.calculateChosenLabel(); + this.clickApply(); + } + } + + if (this.singleDatePicker) { + this.setEndDate(this.startDate); + if (!this.timePicker) + this.clickApply(); + } + + this.updateView(); + + //This is to cancel the blur event handler if the mouse was in one of the inputs + e.stopPropagation(); + + }, + + calculateChosenLabel: function () { + var customRange = true; + var i = 0; + for (var range in this.ranges) { + if (this.timePicker) { + var format = this.timePickerSeconds ? "YYYY-MM-DD hh:mm:ss" : "YYYY-MM-DD hh:mm"; + //ignore times when comparing dates if time picker seconds is not enabled + if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) { + customRange = false; + this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html(); + break; + } + } else { + //ignore times when comparing dates if time picker is not enabled + if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) { + customRange = false; + this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').html(); + break; + } + } + i++; + } + if (customRange) { + if (this.showCustomRangeLabel) { + this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html(); + } else { + this.chosenLabel = null; + } + this.showCalendars(); + } + }, + + clickApply: function(e) { + this.hide(); + this.element.trigger('apply.daterangepicker', this); + }, + + clickCancel: function(e) { + this.startDate = this.oldStartDate; + this.endDate = this.oldEndDate; + this.hide(); + this.element.trigger('cancel.daterangepicker', this); + }, + + monthOrYearChanged: function(e) { + var isLeft = $(e.target).closest('.calendar').hasClass('left'), + leftOrRight = isLeft ? 'left' : 'right', + cal = this.container.find('.calendar.'+leftOrRight); + + // Month must be Number for new moment versions + var month = parseInt(cal.find('.monthselect').val(), 10); + var year = cal.find('.yearselect').val(); + + if (!isLeft) { + if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) { + month = this.startDate.month(); + year = this.startDate.year(); + } + } + + if (this.minDate) { + if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) { + month = this.minDate.month(); + year = this.minDate.year(); + } + } + + if (this.maxDate) { + if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) { + month = this.maxDate.month(); + year = this.maxDate.year(); + } + } + + if (isLeft) { + this.leftCalendar.month.month(month).year(year); + if (this.linkedCalendars) + this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month'); + } else { + this.rightCalendar.month.month(month).year(year); + if (this.linkedCalendars) + this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month'); + } + this.updateCalendars(); + }, + + timeChanged: function(e) { + + var cal = $(e.target).closest('.calendar'), + isLeft = cal.hasClass('left'); + + var hour = parseInt(cal.find('.hourselect').val(), 10); + var minute = parseInt(cal.find('.minuteselect').val(), 10); + var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0; + + if (!this.timePicker24Hour) { + var ampm = cal.find('.ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + + if (isLeft) { + var start = this.startDate.clone(); + start.hour(hour); + start.minute(minute); + start.second(second); + this.setStartDate(start); + if (this.singleDatePicker) { + this.endDate = this.startDate.clone(); + } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) { + this.setEndDate(start.clone()); + } + } else if (this.endDate) { + var end = this.endDate.clone(); + end.hour(hour); + end.minute(minute); + end.second(second); + this.setEndDate(end); + } + + //update the calendars so all clickable dates reflect the new time component + this.updateCalendars(); + + //update the form inputs above the calendars with the new time + this.updateFormInputs(); + + //re-render the time pickers because changing one selection can affect what's enabled in another + this.renderTimePicker('left'); + this.renderTimePicker('right'); + + }, + + formInputsChanged: function(e) { + var isRight = $(e.target).closest('.calendar').hasClass('right'); + var start = moment(this.container.find('input[name="daterangepicker_start"]').val(), this.locale.format); + var end = moment(this.container.find('input[name="daterangepicker_end"]').val(), this.locale.format); + + if (start.isValid() && end.isValid()) { + + if (isRight && end.isBefore(start)) + start = end.clone(); + + this.setStartDate(start); + this.setEndDate(end); + + if (isRight) { + this.container.find('input[name="daterangepicker_start"]').val(this.startDate.format(this.locale.format)); + } else { + this.container.find('input[name="daterangepicker_end"]').val(this.endDate.format(this.locale.format)); + } + + } + + this.updateView(); + }, + + formInputsFocused: function(e) { + + // Highlight the focused input + this.container.find('input[name="daterangepicker_start"], input[name="daterangepicker_end"]').removeClass('active'); + $(e.target).addClass('active'); + + // Set the state such that if the user goes back to using a mouse, + // the calendars are aware we're selecting the end of the range, not + // the start. This allows someone to edit the end of a date range without + // re-selecting the beginning, by clicking on the end date input then + // using the calendar. + var isRight = $(e.target).closest('.calendar').hasClass('right'); + if (isRight) { + this.endDate = null; + this.setStartDate(this.startDate.clone()); + this.updateView(); + } + + }, + + formInputsBlurred: function(e) { + + // this function has one purpose right now: if you tab from the first + // text input to the second in the UI, the endDate is nulled so that + // you can click another, but if you tab out without clicking anything + // or changing the input value, the old endDate should be retained + + if (!this.endDate) { + var val = this.container.find('input[name="daterangepicker_end"]').val(); + var end = moment(val, this.locale.format); + if (end.isValid()) { + this.setEndDate(end); + this.updateView(); + } + } + + }, + + formInputsKeydown: function(e) { + // This function ensures that if the 'enter' key was pressed in the input, then the calendars + // are updated with the startDate and endDate. + // This behaviour is automatic in Chrome/Firefox/Edge but not in IE 11 hence why this exists. + // Other browsers and versions of IE are untested and the behaviour is unknown. + if (e.keyCode === 13) { + // Prevent the calendar from being updated twice on Chrome/Firefox/Edge + e.preventDefault(); + this.formInputsChanged(e); + } + }, + + + elementChanged: function() { + if (!this.element.is('input')) return; + if (!this.element.val().length) return; + + var dateString = this.element.val().split(this.locale.separator), + start = null, + end = null; + + if (dateString.length === 2) { + start = moment(dateString[0], this.locale.format); + end = moment(dateString[1], this.locale.format); + } + + if (this.singleDatePicker || start === null || end === null) { + start = moment(this.element.val(), this.locale.format); + end = start; + } + + if (!start.isValid() || !end.isValid()) return; + + this.setStartDate(start); + this.setEndDate(end); + this.updateView(); + }, + + keydown: function(e) { + //hide on tab or enter + if ((e.keyCode === 9) || (e.keyCode === 13)) { + this.hide(); + } + + //hide on esc and prevent propagation + if (e.keyCode === 27) { + e.preventDefault(); + e.stopPropagation(); + + this.hide(); + } + }, + + updateElement: function() { + if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) { + this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format)); + this.element.trigger('change'); + } else if (this.element.is('input') && this.autoUpdateInput) { + this.element.val(this.startDate.format(this.locale.format)); + this.element.trigger('change'); + } + }, + + remove: function() { + this.container.remove(); + this.element.off('.daterangepicker'); + this.element.removeData(); + } + + }; + + $.fn.daterangepicker = function(options, callback) { + var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options); + this.each(function() { + var el = $(this); + if (el.data('daterangepicker')) + el.data('daterangepicker').remove(); + el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback)); + }); + return this; + }; + + return DateRangePicker; + +})); diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css new file mode 100644 index 0000000..5b96335 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:"Glyphicons Halflings";src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../fonts/glyphicons-halflings-regular.woff) format("woff"),url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:"Glyphicons Halflings";font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-right:-15px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css.map b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css.map new file mode 100644 index 0000000..0ae3de5 --- /dev/null +++ b/xxl-job-2.3.0/xxl-job-admin/src/main/resources/static/adminlte/bower_components/bootstrap/css/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","dist/css/bootstrap.css","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA;;;;AAKA,4ECKA,KACE,YAAA,WACA,qBAAA,KACA,yBAAA,KAOF,KACE,OAAA,EAaF,QCnBA,MACA,QACA,WACA,OACA,OACA,OACA,OACA,KACA,KACA,IACA,QACA,QDqBE,QAAA,MAQF,MCzBA,OACA,SACA,MD2BE,QAAA,aACA,eAAA,SAQF,sBACE,QAAA,KACA,OAAA,EAQF,SCrCA,SDuCE,QAAA,KAUF,EACE,iBAAA,YAQF,SCnDA,QDqDE,QAAA,EAWF,YACE,cAAA,KACA,gBAAA,UACA,wBAAA,UAAA,OAAA,qBAAA,UAAA,OAAA,gBAAA,UAAA,OAOF,EC/DA,ODiEE,YAAA,IAOF,IACE,WAAA,OAQF,GACE,UAAA,IACA,OAAA,MAAA,EAOF,KACE,WAAA,KACA,MAAA,KAOF,MACE,UAAA,IAOF,ICzFA,ID2FE,UAAA,IACA,YAAA,EACA,SAAA,SACA,eAAA,SAGF,IACE,IAAA,MAGF,IACE,OAAA,OAUF,IACE,OAAA,EAOF,eACE,SAAA,OAUF,OACE,OAAA,IAAA,KAOF,GACE,mBAAA,YAAA,gBAAA,YAAA,WAAA,YACA,OAAA,EAOF,IACE,SAAA,KAOF,KC7HA,IACA,IACA,KD+HE,YAAA,SAAA,CAAA,UACA,UAAA,IAkBF,OC7IA,MACA,SACA,OACA,SD+IE,MAAA,QACA,KAAA,QACA,OAAA,EAOF,OACE,SAAA,QAUF,OC1JA,OD4JE,eAAA,KAWF,OCnKA,wBACA,kBACA,mBDqKE,mBAAA,OACA,OAAA,QAOF,iBCxKA,qBD0KE,OAAA,QAOF,yBC7KA,wBD+KE,OAAA,EACA,QAAA,EAQF,MACE,YAAA,OAWF,qBC5LA,kBD8LE,mBAAA,WAAA,gBAAA,WAAA,WAAA,WACA,QAAA,EASF,8CCjMA,8CDmME,OAAA,KAQF,mBACE,mBAAA,UACA,mBAAA,YAAA,gBAAA,YAAA,WAAA,YASF,iDC5MA,8CD8ME,mBAAA,KAOF,SACE,OAAA,IAAA,MAAA,OACA,OAAA,EAAA,IACA,QAAA,MAAA,OAAA,MAQF,OACE,OAAA,EACA,QAAA,EAOF,SACE,SAAA,KAQF,SACE,YAAA,IAUF,MACE,gBAAA,SACA,eAAA,EAGF,GC3OA,GD6OE,QAAA,EDlPF,qFGhLA,aACE,ED2LA,OADA,QCvLE,MAAA,eACA,YAAA,eACA,WAAA,cACA,mBAAA,eAAA,WAAA,eAGF,ED0LA,UCxLE,gBAAA,UAGF,cACE,QAAA,KAAA,WAAA,IAGF,kBACE,QAAA,KAAA,YAAA,IAKF,mBDqLA,6BCnLE,QAAA,GDuLF,WCpLA,IAEE,OAAA,IAAA,MAAA,KACA,kBAAA,MAGF,MACE,QAAA,mBDqLF,IClLA,GAEE,kBAAA,MAGF,IACE,UAAA,eDmLF,GACA,GCjLA,EAGE,QAAA,EACA,OAAA,EAGF,GD+KA,GC7KE,iBAAA,MAMF,QACE,QAAA,KAEF,YD2KA,oBCxKI,iBAAA,eAGJ,OACE,OAAA,IAAA,MAAA,KAGF,OACE,gBAAA,mBADF,UD2KA,UCtKI,iBAAA,eD0KJ,mBCvKA,mBAGI,OAAA,IAAA,MAAA,gBCrFN,WACE,YAAA,uBACA,IAAA,+CACA,IAAA,sDAAA,2BAAA,CAAA,iDAAA,eAAA,CAAA,gDAAA,cAAA,CAAA,+CAAA,kBAAA,CAAA,2EAAA,cAQF,WACE,SAAA,SACA,IAAA,IACA,QAAA,aACA,YAAA,uBACA,WAAA,OACA,YAAA,IACA,YAAA,EACA,uBAAA,YACA,wBAAA,UAIkC,2BAAW,QAAA,QACX,uBAAW,QAAA,QF2P/C,sBEzPoC,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,qBAAW,QAAA,QACX,0BAAW,QAAA,QACX,qBAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,sBAAW,QAAA,QACX,yBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,+BAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,gCAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,gCAAW,QAAA,QACX,gCAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,0BAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,mCAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,sBAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,0BAAW,QAAA,QACX,4BAAW,QAAA,QACX,qCAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,mCAAW,QAAA,QACX,uCAAW,QAAA,QACX,gCAAW,QAAA,QACX,oCAAW,QAAA,QACX,qCAAW,QAAA,QACX,yCAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,iCAAW,QAAA,QACX,oCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,qBAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QASX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,+BAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,mCAAW,QAAA,QACX,4BAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,kCAAW,QAAA,QACX,mCAAW,QAAA,QACX,sCAAW,QAAA,QACX,0CAAW,QAAA,QACX,oCAAW,QAAA,QACX,wCAAW,QAAA,QACX,qCAAW,QAAA,QACX,iCAAW,QAAA,QACX,gCAAW,QAAA,QACX,kCAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,0BAAW,QAAA,QCxS/C,ECkEE,mBAAA,WACG,gBAAA,WACK,WAAA,WJo+BV,OGriCA,QC+DE,mBAAA,WACG,gBAAA,WACK,WAAA,WDzDV,KACE,UAAA,KACA,4BAAA,cAGF,KACE,YAAA,gBAAA,CAAA,SAAA,CAAA,KAAA,CAAA,WACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,iBAAA,KHoiCF,OGhiCA,MHiiCA,OACA,SG9hCE,YAAA,QACA,UAAA,QACA,YAAA,QAMF,EACE,MAAA,QACA,gBAAA,KH8hCF,QG5hCE,QAEE,MAAA,QACA,gBAAA,UAGF,QEnDA,QAAA,IAAA,KAAA,yBACA,eAAA,KF6DF,OACE,OAAA,EAMF,IACE,eAAA,OHqhCF,4BADA,0BGhhCA,gBH+gCA,iBADA,eMxlCE,QAAA,MACA,UAAA,KACA,OAAA,KH6EF,aACE,cAAA,IAMF,eACE,QAAA,IACA,YAAA,WACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,cAAA,IC+FA,mBAAA,IAAA,IAAA,YACK,cAAA,IAAA,IAAA,YACG,WAAA,IAAA,IAAA,YE5LR,QAAA,aACA,UAAA,KACA,OAAA,KHiGF,YACE,cAAA,IAMF,GACE,WAAA,KACA,cAAA,KACA,OAAA,EACA,WAAA,IAAA,MAAA,KAQF,SACE,SAAA,SACA,MAAA,IACA,OAAA,IACA,QAAA,EACA,OAAA,KACA,SAAA,OACA,KAAA,cACA,OAAA,EAQA,0BH8/BF,yBG5/BI,SAAA,OACA,MAAA,KACA,OAAA,KACA,OAAA,EACA,SAAA,QACA,KAAA,KAWJ,cACE,OAAA,QH4/BF,IACA,IACA,IACA,IACA,IACA,IOtpCA,GP4oCA,GACA,GACA,GACA,GACA,GO9oCE,YAAA,QACA,YAAA,IACA,YAAA,IACA,MAAA,QPyqCF,WAZA,UAaA,WAZA,UAaA,WAZA,UAaA,WAZA,UAaA,WAZA,UAaA,WAZA,UACA,UOxqCA,SPyqCA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SOxpCI,YAAA,IACA,YAAA,EACA,MAAA,KP8qCJ,IAEA,IAEA,IO9qCA,GP2qCA,GAEA,GO1qCE,WAAA,KACA,cAAA,KPqrCF,WANA,UAQA,WANA,UAQA,WANA,UACA,UOxrCA,SP0rCA,UANA,SAQA,UANA,SO9qCI,UAAA,IPyrCJ,IAEA,IAEA,IO1rCA,GPurCA,GAEA,GOtrCE,WAAA,KACA,cAAA,KPisCF,WANA,UAQA,WANA,UAQA,WANA,UACA,UOpsCA,SPssCA,UANA,SAQA,UANA,SO1rCI,UAAA,IPqsCJ,IOjsCA,GAAU,UAAA,KPqsCV,IOpsCA,GAAU,UAAA,KPwsCV,IOvsCA,GAAU,UAAA,KP2sCV,IO1sCA,GAAU,UAAA,KP8sCV,IO7sCA,GAAU,UAAA,KPitCV,IOhtCA,GAAU,UAAA,KAMV,EACE,OAAA,EAAA,EAAA,KAGF,MACE,cAAA,KACA,UAAA,KACA,YAAA,IACA,YAAA,IAEA,yBAAA,MACE,UAAA,MPitCJ,OOxsCA,MAEE,UAAA,IP0sCF,MOvsCA,KAEE,QAAA,KACA,iBAAA,QAIF,WAAuB,WAAA,KACvB,YAAuB,WAAA,MACvB,aAAuB,WAAA,OACvB,cAAuB,WAAA,QACvB,aAAuB,YAAA,OAGvB,gBAAuB,eAAA,UACvB,gBAAuB,eAAA,UACvB,iBAAuB,eAAA,WAGvB,YACE,MAAA,KAEF,cCvGE,MAAA,QR2zCF,qBQ1zCE,qBAEE,MAAA,QDuGJ,cC1GE,MAAA,QRk0CF,qBQj0CE,qBAEE,MAAA,QD0GJ,WC7GE,MAAA,QRy0CF,kBQx0CE,kBAEE,MAAA,QD6GJ,cChHE,MAAA,QRg1CF,qBQ/0CE,qBAEE,MAAA,QDgHJ,aCnHE,MAAA,QRu1CF,oBQt1CE,oBAEE,MAAA,QDuHJ,YAGE,MAAA,KE7HA,iBAAA,QT+1CF,mBS91CE,mBAEE,iBAAA,QF6HJ,YEhIE,iBAAA,QTs2CF,mBSr2CE,mBAEE,iBAAA,QFgIJ,SEnIE,iBAAA,QT62CF,gBS52CE,gBAEE,iBAAA,QFmIJ,YEtIE,iBAAA,QTo3CF,mBSn3CE,mBAEE,iBAAA,QFsIJ,WEzIE,iBAAA,QT23CF,kBS13CE,kBAEE,iBAAA,QF8IJ,aACE,eAAA,IACA,OAAA,KAAA,EAAA,KACA,cAAA,IAAA,MAAA,KPgvCF,GOxuCA,GAEE,WAAA,EACA,cAAA,KP4uCF,MAFA,MACA,MO9uCA,MAMI,cAAA,EAOJ,eACE,aAAA,EACA,WAAA,KAIF,aALE,aAAA,EACA,WAAA,KAMA,YAAA,KAFF,gBAKI,QAAA,aACA,cAAA,IACA,aAAA,IAKJ,GACE,WAAA,EACA,cAAA,KPouCF,GOluCA,GAEE,YAAA,WAEF,GACE,YAAA,IAEF,GACE,YAAA,EAaA,yBAAA,kBAEI,MAAA,KACA,MAAA,MACA,MAAA,KACA,WAAA,MGxNJ,SAAA,OACA,cAAA,SACA,YAAA,OHiNA,kBASI,YAAA,OP4tCN,0BOjtCA,YAEE,OAAA,KAGF,YACE,UAAA,IA9IqB,eAAA,UAmJvB,WACE,QAAA,KAAA,KACA,OAAA,EAAA,EAAA,KACA,UAAA,OACA,YAAA,IAAA,MAAA,KPitCF,yBO5sCI,wBP2sCJ,yBO1sCM,cAAA,EPgtCN,kBO1tCA,kBPytCA,iBOtsCI,QAAA,MACA,UAAA,IACA,YAAA,WACA,MAAA,KP4sCJ,yBO1sCI,yBPysCJ,wBOxsCM,QAAA,cAQN,oBPqsCA,sBOnsCE,cAAA,KACA,aAAA,EACA,WAAA,MACA,aAAA,IAAA,MAAA,KACA,YAAA,EP0sCF,kCOpsCI,kCPksCJ,iCAGA,oCAJA,oCAEA,mCOnsCe,QAAA,GP4sCf,iCO3sCI,iCPysCJ,gCAGA,mCAJA,mCAEA,kCOzsCM,QAAA,cAMN,QACE,cAAA,KACA,WAAA,OACA,YAAA,WIxSF,KXm/CA,IACA,IACA,KWj/CE,YAAA,KAAA,CAAA,MAAA,CAAA,QAAA,CAAA,aAAA,CAAA,UAIF,KACE,QAAA,IAAA,IACA,UAAA,IACA,MAAA,QACA,iBAAA,QACA,cAAA,IAIF,IACE,QAAA,IAAA,IACA,UAAA,IACA,MAAA,KACA,iBAAA,KACA,cAAA,IACA,mBAAA,MAAA,EAAA,KAAA,EAAA,gBAAA,WAAA,MAAA,EAAA,KAAA,EAAA,gBANF,QASI,QAAA,EACA,UAAA,KACA,YAAA,IACA,mBAAA,KAAA,WAAA,KAKJ,IACE,QAAA,MACA,QAAA,MACA,OAAA,EAAA,EAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,WAAA,UACA,UAAA,WACA,iBAAA,QACA,OAAA,IAAA,MAAA,KACA,cAAA,IAXF,SAeI,QAAA,EACA,UAAA,QACA,MAAA,QACA,YAAA,SACA,iBAAA,YACA,cAAA,EAKJ,gBACE,WAAA,MACA,WAAA,OC1DF,WCHE,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KDGA,yBAAA,WACE,MAAA,OAEF,yBAAA,WACE,MAAA,OAEF,0BAAA,WACE,MAAA,QAUJ,iBCvBE,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KD6BF,KCvBE,aAAA,MACA,YAAA,MD0BF,gBACE,aAAA,EACA,YAAA,EAFF,8BAKI,cAAA,EACA,aAAA,EZwiDJ,UAoCA,WAIA,WAIA,WAxCA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAjCA,UAoCA,WAIA,WAIA,WAxCA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAjCA,UAoCA,WAIA,WAIA,WAxCA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UatnDC,UbynDD,WAIA,WAIA,WAxCA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UAIA,UcpmDM,SAAA,SAEA,WAAA,IAEA,cAAA,KACA,aAAA,KDtBL,UbmpDD,WACA,WACA,WAVA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,Uc3mDM,MAAA,KDvCL,WC+CG,MAAA,KD/CH,WC+CG,MAAA,aD/CH,WC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,YD/CH,gBC8DG,MAAA,KD9DH,gBC8DG,MAAA,aD9DH,gBC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,YD9DH,eCmEG,MAAA,KDnEH,gBCoDG,KAAA,KDpDH,gBCoDG,KAAA,aDpDH,gBCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,YDpDH,eCyDG,KAAA,KDzDH,kBCwEG,YAAA,KDxEH,kBCwEG,YAAA,aDxEH,kBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,YDxEH,iBCwEG,YAAA,EFCJ,yBCzEC,Ub2zDC,WACA,WACA,WAVA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UcnxDI,MAAA,KDvCL,WC+CG,MAAA,KD/CH,WC+CG,MAAA,aD/CH,WC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,YD/CH,gBC8DG,MAAA,KD9DH,gBC8DG,MAAA,aD9DH,gBC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,YD9DH,eCmEG,MAAA,KDnEH,gBCoDG,KAAA,KDpDH,gBCoDG,KAAA,aDpDH,gBCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,YDpDH,eCyDG,KAAA,KDzDH,kBCwEG,YAAA,KDxEH,kBCwEG,YAAA,aDxEH,kBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,YDxEH,iBCwEG,YAAA,GFUJ,yBClFC,Ubo+DC,WACA,WACA,WAVA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,Uc57DI,MAAA,KDvCL,WC+CG,MAAA,KD/CH,WC+CG,MAAA,aD/CH,WC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,YD/CH,gBC8DG,MAAA,KD9DH,gBC8DG,MAAA,aD9DH,gBC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,YD9DH,eCmEG,MAAA,KDnEH,gBCoDG,KAAA,KDpDH,gBCoDG,KAAA,aDpDH,gBCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,YDpDH,eCyDG,KAAA,KDzDH,kBCwEG,YAAA,KDxEH,kBCwEG,YAAA,aDxEH,kBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,YDxEH,iBCwEG,YAAA,GFmBJ,0BC3FC,Ub6oEC,WACA,WACA,WAVA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UcrmEI,MAAA,KDvCL,WC+CG,MAAA,KD/CH,WC+CG,MAAA,aD/CH,WC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,ID/CH,UC+CG,MAAA,aD/CH,UC+CG,MAAA,YD/CH,gBC8DG,MAAA,KD9DH,gBC8DG,MAAA,aD9DH,gBC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,ID9DH,eC8DG,MAAA,aD9DH,eC8DG,MAAA,YD9DH,eCmEG,MAAA,KDnEH,gBCoDG,KAAA,KDpDH,gBCoDG,KAAA,aDpDH,gBCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,IDpDH,eCoDG,KAAA,aDpDH,eCoDG,KAAA,YDpDH,eCyDG,KAAA,KDzDH,kBCwEG,YAAA,KDxEH,kBCwEG,YAAA,aDxEH,kBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,IDxEH,iBCwEG,YAAA,aDxEH,iBCwEG,YAAA,YDxEH,iBCwEG,YAAA,GCjEJ,MACE,iBAAA,YADF,uBAQI,SAAA,OACA,QAAA,aACA,MAAA,KAKA,sBf+xEJ,sBe9xEM,SAAA,OACA,QAAA,WACA,MAAA,KAKN,QACE,YAAA,IACA,eAAA,IACA,MAAA,KACA,WAAA,KAGF,GACE,WAAA,KAMF,OACE,MAAA,KACA,UAAA,KACA,cAAA,Kf6xEF,mBAHA,mBAIA,mBAHA,mBACA,mBe/xEA,mBAWQ,QAAA,IACA,YAAA,WACA,eAAA,IACA,WAAA,IAAA,MAAA,KAdR,mBAoBI,eAAA,OACA,cAAA,IAAA,MAAA,KfyxEJ,uCe9yEA,uCf+yEA,wCAHA,wCAIA,2CAHA,2Ce/wEQ,WAAA,EA9BR,mBAoCI,WAAA,IAAA,MAAA,KApCJ,cAyCI,iBAAA,KfoxEJ,6BAHA,6BAIA,6BAHA,6BACA,6Be5wEA,6BAOQ,QAAA,IAWR,gBACE,OAAA,IAAA,MAAA,KfqwEF,4BAHA,4BAIA,4BAHA,4BACA,4BerwEA,4BAQQ,OAAA,IAAA,MAAA,KfmwER,4Be3wEA,4BAeM,oBAAA,IAUN,yCAEI,iBAAA,QASJ,4BAEI,iBAAA,QfqvEJ,0BAGA,0BATA,0BAGA,0BAIA,0BAGA,0BATA,0BAGA,0BACA,0BAGA,0BgBt4EE,0BhBg4EF,0BgBz3EM,iBAAA,QhBs4EN,sCAEA,sCADA,oCgBj4EE,sChB+3EF,sCgBz3EM,iBAAA,QhBs4EN,2BAGA,2BATA,2BAGA,2BAIA,2BAGA,2BATA,2BAGA,2BACA,2BAGA,2BgB35EE,2BhBq5EF,2BgB94EM,iBAAA,QhB25EN,uCAEA,uCADA,qCgBt5EE,uChBo5EF,uCgB94EM,iBAAA,QhB25EN,wBAGA,wBATA,wBAGA,wBAIA,wBAGA,wBATA,wBAGA,wBACA,wBAGA,wBgBh7EE,wBhB06EF,wBgBn6EM,iBAAA,QhBg7EN,oCAEA,oCADA,kCgB36EE,oChBy6EF,oCgBn6EM,iBAAA,QhBg7EN,2BAGA,2BATA,2BAGA,2BAIA,2BAGA,2BATA,2BAGA,2BACA,2BAGA,2BgBr8EE,2BhB+7EF,2BgBx7EM,iBAAA,QhBq8EN,uCAEA,uCADA,qCgBh8EE,uChB87EF,uCgBx7EM,iBAAA,QhBq8EN,0BAGA,0BATA,0BAGA,0BAIA,0BAGA,0BATA,0BAGA,0BACA,0BAGA,0BgB19EE,0BhBo9EF,0BgB78EM,iBAAA,QhB09EN,sCAEA,sCADA,oCgBr9EE,sChBm9EF,sCgB78EM,iBAAA,QDoJN,kBACE,WAAA,KACA,WAAA,KAEA,oCAAA,kBACE,MAAA,KACA,cAAA,KACA,WAAA,OACA,mBAAA,yBACA,OAAA,IAAA,MAAA,KALF,yBASI,cAAA,Efq0EJ,qCAHA,qCAIA,qCAHA,qCACA,qCe70EA,qCAkBU,YAAA,OAlBV,kCA0BI,OAAA,Ef+zEJ,0DAHA,0DAIA,0DAHA,0DACA,0Dex1EA,0DAmCU,YAAA,Ef8zEV,yDAHA,yDAIA,yDAHA,yDACA,yDeh2EA,yDAuCU,aAAA,Efg0EV,yDev2EA,yDfw2EA,yDAFA,yDelzEU,cAAA,GEzNZ,SAIE,UAAA,EACA,QAAA,EACA,OAAA,EACA,OAAA,EAGF,OACE,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,KACA,UAAA,KACA,YAAA,QACA,MAAA,KACA,OAAA,EACA,cAAA,IAAA,MAAA,QAGF,MACE,QAAA,aACA,UAAA,KACA,cAAA,IACA,YAAA,IAUF,mBb6BE,mBAAA,WACG,gBAAA,WACK,WAAA,WarBR,mBAAA,KACA,gBAAA,KAAA,WAAA,KjBkgFF,qBiB9/EA,kBAEE,OAAA,IAAA,EAAA,EACA,WAAA,MACA,YAAA,OjBogFF,wCADA,qCADA,8BAFA,+BACA,2BiB3/EE,4BAGE,OAAA,YAIJ,iBACE,QAAA,MAIF,kBACE,QAAA,MACA,MAAA,KAIF,iBjBu/EA,aiBr/EE,OAAA,KjB0/EF,2BiBt/EA,uBjBq/EA,wBK/kFE,QAAA,IAAA,KAAA,yBACA,eAAA,KYgGF,OACE,QAAA,MACA,YAAA,IACA,UAAA,KACA,YAAA,WACA,MAAA,KA0BF,cACE,QAAA,MACA,MAAA,KACA,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,iBAAA,KACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,cAAA,Ib3EA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBAyHR,mBAAA,aAAA,YAAA,IAAA,CAAA,WAAA,YAAA,KACK,cAAA,aAAA,YAAA,IAAA,CAAA,WAAA,YAAA,KACG,mBAAA,aAAA,YAAA,IAAA,CAAA,mBAAA,YAAA,KAAA,WAAA,aAAA,YAAA,IAAA,CAAA,mBAAA,YAAA,KAAA,WAAA,aAAA,YAAA,IAAA,CAAA,WAAA,YAAA,KAAA,WAAA,aAAA,YAAA,IAAA,CAAA,WAAA,YAAA,IAAA,CAAA,mBAAA,YAAA,Kc1IR,oBACE,aAAA,QACA,QAAA,EdYF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,qBAiCR,gCACE,MAAA,KACA,QAAA,EAEF,oCAA0B,MAAA,KAC1B,yCAAgC,MAAA,Ka+ChC,0BACE,iBAAA,YACA,OAAA,EAQF,wBjBq+EF,wBACA,iCiBn+EI,iBAAA,KACA,QAAA,EAGF,wBjBo+EF,iCiBl+EI,OAAA,YAIF,sBACE,OAAA,KAcJ,qDAKI,8BjBm9EF,wCACA,+BAFA,8BiBj9EI,YAAA,KjB09EJ,iCAEA,2CACA,kCAFA,iCiBx9EE,0BjBq9EF,oCACA,2BAFA,0BiBl9EI,YAAA,KjB+9EJ,iCAEA,2CACA,kCAFA,iCiB79EE,0BjB09EF,oCACA,2BAFA,0BiBv9EI,YAAA,MAWN,YACE,cAAA,KjBy9EF,UiBj9EA,OAEE,SAAA,SACA,QAAA,MACA,WAAA,KACA,cAAA,KjBm9EF,yBiBh9EE,sBjBk9EF,mCADA,gCiB98EM,OAAA,YjBm9EN,gBiB99EA,aAgBI,WAAA,KACA,aAAA,KACA,cAAA,EACA,YAAA,IACA,OAAA,QjBm9EJ,+BACA,sCiBj9EA,yBjB+8EA,gCiB38EE,SAAA,SACA,WAAA,MACA,YAAA,MjBi9EF,oBiB98EA,cAEE,WAAA,KjBg9EF,iBiB58EA,cAEE,SAAA,SACA,QAAA,aACA,aAAA,KACA,cAAA,EACA,YAAA,IACA,eAAA,OACA,OAAA,QjB88EF,0BiB38EE,uBjB68EF,oCADA,iCiB18EI,OAAA,YjB+8EJ,kCiB58EA,4BAEE,WAAA,EACA,YAAA,KASF,qBACE,WAAA,KAEA,YAAA,IACA,eAAA,IAEA,cAAA,EAEA,8BjBm8EF,8BiBj8EI,cAAA,EACA,aAAA,EAaJ,UC3PE,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,cAAA,IAEA,gBACE,OAAA,KACA,YAAA,KlBsrFJ,0BkBnrFE,kBAEE,OAAA,KDiPJ,6BAEI,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,cAAA,IANJ,mCASI,OAAA,KACA,YAAA,KjBq8EJ,6CiB/8EA,qCAcI,OAAA,KAdJ,oCAiBI,OAAA,KACA,WAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IAIJ,UCvRE,OAAA,KACA,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UACA,cAAA,IAEA,gBACE,OAAA,KACA,YAAA,KlB2tFJ,0BkBxtFE,kBAEE,OAAA,KD6QJ,6BAEI,OAAA,KACA,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UACA,cAAA,IANJ,mCASI,OAAA,KACA,YAAA,KjB88EJ,6CiBx9EA,qCAcI,OAAA,KAdJ,oCAiBI,OAAA,KACA,WAAA,KACA,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UASJ,cAEE,SAAA,SAFF,4BAMI,cAAA,OAIJ,uBACE,SAAA,SACA,IAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,MACA,MAAA,KACA,OAAA,KACA,YAAA,KACA,WAAA,OACA,eAAA,KjBo8EF,oDADA,uCiBj8EA,iCAGE,MAAA,KACA,OAAA,KACA,YAAA,KjBo8EF,oDADA,uCiBj8EA,iCAGE,MAAA,KACA,OAAA,KACA,YAAA,KjBq8EF,uBAEA,8BAJA,4BiB/7EA,yBjBg8EA,oBAEA,2BAGA,4BAEA,mCAHA,yBAEA,gCkBx1FI,MAAA,QDkZJ,2BC9YI,aAAA,QdiDF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBchDN,iCACE,aAAA,Qd8CJ,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,QACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,Qa4VV,gCCpYI,MAAA,QACA,iBAAA,QACA,aAAA,QDkYJ,oCC9XI,MAAA,QlB61FJ,uBAEA,8BAJA,4BiB19EA,yBjB29EA,oBAEA,2BAGA,4BAEA,mCAHA,yBAEA,gCkBt3FI,MAAA,QDqZJ,2BCjZI,aAAA,QdiDF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBchDN,iCACE,aAAA,Qd8CJ,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,QACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,Qa+VV,gCCvYI,MAAA,QACA,iBAAA,QACA,aAAA,QDqYJ,oCCjYI,MAAA,QlB23FJ,qBAEA,4BAJA,0BiBr/EA,uBjBs/EA,kBAEA,yBAGA,0BAEA,iCAHA,uBAEA,8BkBp5FI,MAAA,QDwZJ,yBCpZI,aAAA,QdiDF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBchDN,+BACE,aAAA,Qd8CJ,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,QACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,CAAA,EAAA,EAAA,IAAA,QakWV,8BC1YI,MAAA,QACA,iBAAA,QACA,aAAA,QDwYJ,kCCpYI,MAAA,QD2YF,2CACE,IAAA,KAEF,mDACE,IAAA,EAUJ,YACE,QAAA,MACA,WAAA,IACA,cAAA,KACA,MAAA,QAkBA,yBAAA,yBAGI,QAAA,aACA,cAAA,EACA,eAAA,OALJ,2BAUI,QAAA,aACA,MAAA,KACA,eAAA,OAZJ,kCAiBI,QAAA,aAjBJ,0BAqBI,QAAA,aACA,eAAA,OjBi/EJ,wCiBvgFA,6CjBsgFA,2CiB3+EM,MAAA,KA3BN,wCAiCI,MAAA,KAjCJ,4BAqCI,cAAA,EACA,eAAA,OjB4+EJ,uBiBlhFA,oBA6CI,QAAA,aACA,WAAA,EACA,cAAA,EACA,eAAA,OjBy+EJ,6BiBzhFA,0BAmDM,aAAA,EjB0+EN,4CiB7hFA,sCAwDI,SAAA,SACA,YAAA,EAzDJ,kDA8DI,IAAA,GjBw+EN,2BAEA,kCiB/9EA,wBjB89EA,+BiBr9EI,YAAA,IACA,WAAA,EACA,cAAA,EjB09EJ,2BiBr+EA,wBAiBI,WAAA,KAjBJ,6BJ9gBE,aAAA,MACA,YAAA,MIwiBA,yBAAA,gCAEI,YAAA,IACA,cAAA,EACA,WAAA,OA/BN,sDAwCI,MAAA,KAQA,yBAAA,+CAEI,YAAA,KACA,UAAA,MAKJ,yBAAA,+CAEI,YAAA,IACA,UAAA,ME9kBR,KACE,QAAA,aACA,cAAA,EACA,YAAA,IACA,WAAA,OACA,YAAA,OACA,eAAA,OACA,iBAAA,aAAA,aAAA,aACA,OAAA,QACA,iBAAA,KACA,OAAA,IAAA,MAAA,YCoCA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,cAAA,IhBqKA,oBAAA,KACG,iBAAA,KACC,gBAAA,KACI,YAAA,KJs1FV,kBAHA,kBACA,WACA,kBAHA,kBmB1hGI,WdrBF,QAAA,IAAA,KAAA,yBACA,eAAA,KLwjGF,WADA,WmB7hGE,WAGE,MAAA,KACA,gBAAA,KnB+hGJ,YmB5hGE,YAEE,iBAAA,KACA,QAAA,Ef2BF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBexBR,cnB4hGF,eACA,wBmB1hGI,OAAA,YE9CF,OAAA,kBACA,QAAA,IjBiEA,mBAAA,KACQ,WAAA,KefN,enB4hGJ,yBmB1hGM,eAAA,KASN,aC7DE,MAAA,KACA,iBAAA,KACA,aAAA,KpBqlGF,mBoBnlGE,mBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,mBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpBqlGJ,oBoBnlGE,oBpBolGF,mCoBjlGI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpB2lGJ,0BAHA,0BAHA,0BAKA,0BAHA,0BoBrlGI,0BpB0lGJ,yCAHA,yCAHA,yCoBjlGM,MAAA,KACA,iBAAA,QACA,aAAA,QpBgmGN,4BAHA,4BoBvlGI,4BpB2lGJ,6BAHA,6BAHA,6BAOA,sCAHA,sCAHA,sCoBnlGM,iBAAA,KACA,aAAA,KDuBN,oBClBI,MAAA,KACA,iBAAA,KDoBJ,aChEE,MAAA,KACA,iBAAA,QACA,aAAA,QpB0oGF,mBoBxoGE,mBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,mBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpB0oGJ,oBoBxoGE,oBpByoGF,mCoBtoGI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpBgpGJ,0BAHA,0BAHA,0BAKA,0BAHA,0BoB1oGI,0BpB+oGJ,yCAHA,yCAHA,yCoBtoGM,MAAA,KACA,iBAAA,QACA,aAAA,QpBqpGN,4BAHA,4BoB5oGI,4BpBgpGJ,6BAHA,6BAHA,6BAOA,sCAHA,sCAHA,sCoBxoGM,iBAAA,QACA,aAAA,QD0BN,oBCrBI,MAAA,QACA,iBAAA,KDwBJ,aCpEE,MAAA,KACA,iBAAA,QACA,aAAA,QpB+rGF,mBoB7rGE,mBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,mBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpB+rGJ,oBoB7rGE,oBpB8rGF,mCoB3rGI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpBqsGJ,0BAHA,0BAHA,0BAKA,0BAHA,0BoB/rGI,0BpBosGJ,yCAHA,yCAHA,yCoB3rGM,MAAA,KACA,iBAAA,QACA,aAAA,QpB0sGN,4BAHA,4BoBjsGI,4BpBqsGJ,6BAHA,6BAHA,6BAOA,sCAHA,sCAHA,sCoB7rGM,iBAAA,QACA,aAAA,QD8BN,oBCzBI,MAAA,QACA,iBAAA,KD4BJ,UCxEE,MAAA,KACA,iBAAA,QACA,aAAA,QpBovGF,gBoBlvGE,gBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,gBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpBovGJ,iBoBlvGE,iBpBmvGF,gCoBhvGI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpB0vGJ,uBAHA,uBAHA,uBAKA,uBAHA,uBoBpvGI,uBpByvGJ,sCAHA,sCAHA,sCoBhvGM,MAAA,KACA,iBAAA,QACA,aAAA,QpB+vGN,yBAHA,yBoBtvGI,yBpB0vGJ,0BAHA,0BAHA,0BAOA,mCAHA,mCAHA,mCoBlvGM,iBAAA,QACA,aAAA,QDkCN,iBC7BI,MAAA,QACA,iBAAA,KDgCJ,aC5EE,MAAA,KACA,iBAAA,QACA,aAAA,QpByyGF,mBoBvyGE,mBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,mBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpByyGJ,oBoBvyGE,oBpBwyGF,mCoBryGI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpB+yGJ,0BAHA,0BAHA,0BAKA,0BAHA,0BoBzyGI,0BpB8yGJ,yCAHA,yCAHA,yCoBryGM,MAAA,KACA,iBAAA,QACA,aAAA,QpBozGN,4BAHA,4BoB3yGI,4BpB+yGJ,6BAHA,6BAHA,6BAOA,sCAHA,sCAHA,sCoBvyGM,iBAAA,QACA,aAAA,QDsCN,oBCjCI,MAAA,QACA,iBAAA,KDoCJ,YChFE,MAAA,KACA,iBAAA,QACA,aAAA,QpB81GF,kBoB51GE,kBAEE,MAAA,KACA,iBAAA,QACA,aAAA,QAEF,kBACE,MAAA,KACA,iBAAA,QACA,aAAA,QpB81GJ,mBoB51GE,mBpB61GF,kCoB11GI,MAAA,KACA,iBAAA,QACA,iBAAA,KACA,aAAA,QpBo2GJ,yBAHA,yBAHA,yBAKA,yBAHA,yBoB91GI,yBpBm2GJ,wCAHA,wCAHA,wCoB11GM,MAAA,KACA,iBAAA,QACA,aAAA,QpBy2GN,2BAHA,2BoBh2GI,2BpBo2GJ,4BAHA,4BAHA,4BAOA,qCAHA,qCAHA,qCoB51GM,iBAAA,QACA,aAAA,QD0CN,mBCrCI,MAAA,QACA,iBAAA,KD6CJ,UACE,YAAA,IACA,MAAA,QACA,cAAA,EAEA,UnBwzGF,iBADA,iBAEA,oBACA,6BmBrzGI,iBAAA,YfnCF,mBAAA,KACQ,WAAA,KeqCR,UnB0zGF,iBADA,gBADA,gBmBpzGI,aAAA,YnB0zGJ,gBmBxzGE,gBAEE,MAAA,QACA,gBAAA,UACA,iBAAA,YnB2zGJ,0BmBvzGI,0BnBwzGJ,mCAFA,mCmBpzGM,MAAA,KACA,gBAAA,KnB0zGN,mBmBjzGA,QC9EE,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UACA,cAAA,IpBm4GF,mBmBpzGA,QClFE,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,cAAA,IpB04GF,mBmBvzGA,QCtFE,QAAA,IAAA,IACA,UAAA,KACA,YAAA,IACA,cAAA,ID2FF,WACE,QAAA,MACA,MAAA,KAIF,sBACE,WAAA,InBuzGF,6BADA,4BmB/yGE,6BACE,MAAA,KG1JJ,MACE,QAAA,ElBoLA,mBAAA,QAAA,KAAA,OACK,cAAA,QAAA,KAAA,OACG,WAAA,QAAA,KAAA,OkBnLR,SACE,QAAA,EAIJ,UACE,QAAA,KAEA,aAAY,QAAA,MACZ,eAAY,QAAA,UACZ,kBAAY,QAAA,gBAGd,YACE,SAAA,SACA,OAAA,EACA,SAAA,OlBsKA,4BAAA,MAAA,CAAA,WACQ,uBAAA,MAAA,CAAA,WAAA,oBAAA,MAAA,CAAA,WAOR,4BAAA,KACQ,uBAAA,KAAA,oBAAA,KAGR,mCAAA,KACQ,8BAAA,KAAA,2BAAA,KmB5MV,OACE,QAAA,aACA,MAAA,EACA,OAAA,EACA,YAAA,IACA,eAAA,OACA,WAAA,IAAA,OACA,WAAA,IAAA,QACA,aAAA,IAAA,MAAA,YACA,YAAA,IAAA,MAAA,YvBu/GF,UuBn/GA,QAEE,SAAA,SAIF,uBACE,QAAA,EAIF,eACE,SAAA,SACA,IAAA,KACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,MAAA,KACA,UAAA,MACA,QAAA,IAAA,EACA,OAAA,IAAA,EAAA,EACA,UAAA,KACA,WAAA,KACA,WAAA,KACA,iBAAA,KACA,gBAAA,YACA,OAAA,IAAA,MAAA,KACA,OAAA,IAAA,MAAA,gBACA,cAAA,InBuBA,mBAAA,EAAA,IAAA,KAAA,iBACQ,WAAA,EAAA,IAAA,KAAA,iBmBlBR,0BACE,MAAA,EACA,KAAA,KAzBJ,wBCzBE,OAAA,IACA,OAAA,IAAA,EACA,SAAA,OACA,iBAAA,QDsBF,oBAmCI,QAAA,MACA,QAAA,IAAA,KACA,MAAA,KACA,YAAA,IACA,YAAA,WACA,MAAA,KACA,YAAA,OvB8+GJ,0BuB5+GI,0BAEE,MAAA,QACA,gBAAA,KACA,iBAAA,QAOJ,yBvBw+GF,+BADA,+BuBp+GI,MAAA,KACA,gBAAA,KACA,iBAAA,QACA,QAAA,EASF,2BvBi+GF,iCADA,iCuB79GI,MAAA,KvBk+GJ,iCuB99GE,iCAEE,gBAAA,KACA,OAAA,YACA,iBAAA,YACA,iBAAA,KEzGF,OAAA,0DF+GF,qBAGI,QAAA,MAHJ,QAQI,QAAA,EAQJ,qBACE,MAAA,EACA,KAAA,KAQF,oBACE,MAAA,KACA,KAAA,EAIF,iBACE,QAAA,MACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,YAAA,OAIF,mBACE,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EACA,QAAA,IAIF,2BACE,MAAA,EACA,KAAA,KAQF,evB+7GA,sCuB37GI,QAAA,GACA,WAAA,EACA,cAAA,IAAA,OACA,cAAA,IAAA,QAPJ,uBvBs8GA,8CuB37GI,IAAA,KACA,OAAA,KACA,cAAA,IASJ,yBACE,6BApEA,MAAA,EACA,KAAA,KAmEA,kCA1DA,MAAA,KACA,KAAA,GG1IF,W1BkoHA,oB0BhoHE,SAAA,SACA,QAAA,aACA,eAAA,O1BooHF,yB0BxoHA,gBAMI,SAAA,SACA,MAAA,K1B4oHJ,gCAFA,gCAFA,+BAFA,+BAKA,uBAFA,uBAFA,sB0BroHI,sBAIE,QAAA,EAMN,qB1BooHA,2BACA,2BACA,iC0BjoHI,YAAA,KAKJ,aACE,YAAA,KADF,kB1BmoHA,wBACA,0B0B7nHI,MAAA,KAPJ,kB1BwoHA,wBACA,0B0B7nHI,YAAA,IAIJ,yEACE,cAAA,EAIF,4BACE,YAAA,EACA,mECpDA,wBAAA,EACA,2BAAA,EDwDF,6C1B2nHA,8C2B5qHE,uBAAA,EACA,0BAAA,EDsDF,sBACE,MAAA,KAEF,8DACE,cAAA,EAEF,mE1B0nHA,oE2B/rHE,wBAAA,EACA,2BAAA,ED0EF,oECnEE,uBAAA,EACA,0BAAA,EDuEF,mC1BwnHA,iC0BtnHE,QAAA,EAiBF,iCACE,cAAA,IACA,aAAA,IAEF,oCACE,cAAA,KACA,aAAA,KAKF,iCtB/CE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBsBkDR,0CtBnDA,mBAAA,KACQ,WAAA,KsByDV,YACE,YAAA,EAGF,eACE,aAAA,IAAA,IAAA,EACA,oBAAA,EAGF,uBACE,aAAA,EAAA,IAAA,IAOF,yB1B4lHA,+BACA,oC0BzlHI,QAAA,MACA,MAAA,KACA,MAAA,KACA,UAAA,KAPJ,oCAcM,MAAA,KAdN,8B1BumHA,oCACA,oCACA,0C0BnlHI,WAAA,KACA,YAAA,EAKF,4DACE,cAAA,EAEF,sDC7KA,uBAAA,IACA,wBAAA,IAOA,2BAAA,EACA,0BAAA,EDwKA,sDCjLA,uBAAA,EACA,wBAAA,EAOA,2BAAA,IACA,0BAAA,ID6KF,uEACE,cAAA,EAEF,4E1BqlHA,6E2BtwHE,2BAAA,EACA,0BAAA,EDsLF,6EC/LE,uBAAA,EACA,wBAAA,EDsMF,qBACE,QAAA,MACA,MAAA,KACA,aAAA,MACA,gBAAA,SAJF,0B1BslHA,gC0B/kHI,QAAA,WACA,MAAA,KACA,MAAA,GATJ,qCAYI,MAAA,KAZJ,+CAgBI,KAAA,K1BmlHJ,gD0BlkHA,6C1BmkHA,2DAFA,wD0B5jHM,SAAA,SACA,KAAA,cACA,eAAA,KE1ON,aACE,SAAA,SACA,QAAA,MACA,gBAAA,SAGA,0BACE,MAAA,KACA,cAAA,EACA,aAAA,EATJ,2BAeI,SAAA,SACA,QAAA,EAKA,MAAA,KAEA,MAAA,KACA,cAAA,EAEA,iCACE,QAAA,EAUN,8B5B2xHA,mCACA,sCkBpwHE,OAAA,KACA,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UACA,cAAA,IAEA,oClBswHF,yCACA,4CkBtwHI,OAAA,KACA,YAAA,KlB4wHJ,8CACA,mDACA,sDkB3wHE,sClBuwHF,2CACA,8CkBtwHI,OAAA,KUhCJ,8B5B6yHA,mCACA,sCkB3xHE,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,cAAA,IAEA,oClB6xHF,yCACA,4CkB7xHI,OAAA,KACA,YAAA,KlBmyHJ,8CACA,mDACA,sDkBlyHE,sClB8xHF,2CACA,8CkB7xHI,OAAA,KlBqyHJ,2B4B5zHA,mB5B2zHA,iB4BxzHE,QAAA,W5B8zHF,8D4B5zHE,sD5B2zHF,oD4B1zHI,cAAA,EAIJ,mB5B2zHA,iB4BzzHE,MAAA,GACA,YAAA,OACA,eAAA,OAKF,mBACE,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,cAAA,IAGA,4BACE,QAAA,IAAA,KACA,UAAA,KACA,cAAA,IAEF,4BACE,QAAA,KAAA,KACA,UAAA,KACA,cAAA,I5ByzHJ,wC4B70HA,qCA0BI,WAAA,EAKJ,uC5BkzHA,+BACA,kCACA,6CACA,8CAEA,6DADA,wE2B55HE,wBAAA,EACA,2BAAA,EC8GF,+BACE,aAAA,EAEF,sC5BmzHA,8BAKA,+DADA,oDAHA,iCACA,4CACA,6C2Bh6HE,uBAAA,EACA,0BAAA,ECkHF,8BACE,YAAA,EAKF,iBACE,SAAA,SAGA,UAAA,EACA,YAAA,OALF,sBAUI,SAAA,SAVJ,2BAYM,YAAA,K5BizHN,6BADA,4B4B7yHI,4BAGE,QAAA,EAKJ,kC5B0yHF,wC4BvyHM,aAAA,KAGJ,iC5BwyHF,uC4BryHM,QAAA,EACA,YAAA,KC/JN,KACE,aAAA,EACA,cAAA,EACA,WAAA,KAHF,QAOI,SAAA,SACA,QAAA,MARJ,UAWM,SAAA,SACA,QAAA,MACA,QAAA,KAAA,K7By8HN,gB6Bx8HM,gBAEE,gBAAA,KACA,iBAAA,KAKJ,mBACE,MAAA,K7Bu8HN,yB6Br8HM,yBAEE,MAAA,KACA,gBAAA,KACA,OAAA,YACA,iBAAA,YAOJ,a7Bi8HJ,mBADA,mB6B77HM,iBAAA,KACA,aAAA,QAzCN,kBLLE,OAAA,IACA,OAAA,IAAA,EACA,SAAA,OACA,iBAAA,QKEF,cA0DI,UAAA,KASJ,UACE,cAAA,IAAA,MAAA,KADF,aAGI,MAAA,KAEA,cAAA,KALJ,eASM,aAAA,IACA,YAAA,WACA,OAAA,IAAA,MAAA,YACA,cAAA,IAAA,IAAA,EAAA,EACA,qBACE,aAAA,KAAA,KAAA,KAMF,sB7B86HN,4BADA,4B6B16HQ,MAAA,KACA,OAAA,QACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,oBAAA,YAKN,wBAqDA,MAAA,KA8BA,cAAA,EAnFA,2BAwDE,MAAA,KAxDF,6BA0DI,cAAA,IACA,WAAA,OA3DJ,iDAgEE,IAAA,KACA,KAAA,KAGF,yBAAA,2BAEI,QAAA,WACA,MAAA,GAHJ,6BAKM,cAAA,GAzEN,6BAuFE,aAAA,EACA,cAAA,IAxFF,kC7Bu8HF,wCADA,wC6Bx2HI,OAAA,IAAA,MAAA,KAGF,yBAAA,6BAEI,cAAA,IAAA,MAAA,KACA,cAAA,IAAA,IAAA,EAAA,EAHJ,kC7Bg3HA,wCADA,wC6Bv2HI,oBAAA,MAhGN,cAEI,MAAA,KAFJ,gBAMM,cAAA,IANN,iBASM,YAAA,IAKA,uB7By8HN,6BADA,6B6Br8HQ,MAAA,KACA,iBAAA,QAQR,gBAEI,MAAA,KAFJ,mBAIM,WAAA,IACA,YAAA,EAYN,eACE,MAAA,KADF,kBAII,MAAA,KAJJ,oBAMM,cAAA,IACA,WAAA,OAPN,wCAYI,IAAA,KACA,KAAA,KAGF,yBAAA,kBAEI,QAAA,WACA,MAAA,GAHJ,oBAKM,cAAA,GASR,oBACE,cAAA,EADF,yBAKI,aAAA,EACA,cAAA,IANJ,8B7By7HA,oCADA,oC6B56HI,OAAA,IAAA,MAAA,KAGF,yBAAA,yBAEI,cAAA,IAAA,MAAA,KACA,cAAA,IAAA,IAAA,EAAA,EAHJ,8B7Bo7HA,oCADA,oC6B36HI,oBAAA,MAUN,uBAEI,QAAA,KAFJ,qBAKI,QAAA,MASJ,yBAEE,WAAA,KF7OA,uBAAA,EACA,wBAAA,EGQF,QACE,SAAA,SACA,WAAA,KACA,cAAA,KACA,OAAA,IAAA,MAAA,YAKA,yBAAA,QACE,cAAA,KAaF,yBAAA,eACE,MAAA,MAeJ,iBACE,cAAA,KACA,aAAA,KACA,WAAA,QACA,WAAA,IAAA,MAAA,YACA,mBAAA,MAAA,EAAA,IAAA,EAAA,qBAAA,WAAA,MAAA,EAAA,IAAA,EAAA,qBAEA,2BAAA,MAEA,oBACE,WAAA,KAGF,yBAAA,iBACE,MAAA,KACA,WAAA,EACA,mBAAA,KAAA,WAAA,KAEA,0BACE,QAAA,gBACA,OAAA,eACA,eAAA,EACA,SAAA,kBAGF,oBACE,WAAA,Q9BknIJ,sC8B7mIE,mC9B4mIF,oC8BzmII,cAAA,EACA,aAAA,G9B+mIN,qB8B1mIA,kBAWE,SAAA,MACA,MAAA,EACA,KAAA,EACA,QAAA,K9BmmIF,sC8BjnIA,mCAGI,WAAA,MAEA,4D9BinIF,sC8BjnIE,mCACE,WAAA,OAWJ,yB9B2mIA,qB8B3mIA,kBACE,cAAA,GAIJ,kBACE,IAAA,EACA,aAAA,EAAA,EAAA,IAEF,qBACE,OAAA,EACA,cAAA,EACA,aAAA,IAAA,EAAA,E9B+mIF,kCAFA,gCACA,4B8BtmIA,0BAII,aAAA,MACA,YAAA,MAEA,yB9BwmIF,kCAFA,gCACA,4B8BvmIE,0BACE,aAAA,EACA,YAAA,GAaN,mBACE,QAAA,KACA,aAAA,EAAA,EAAA,IAEA,yBAAA,mBACE,cAAA,GAOJ,cACE,MAAA,KACA,OAAA,KACA,QAAA,KAAA,KACA,UAAA,KACA,YAAA,K9B8lIF,oB8B5lIE,oBAEE,gBAAA,KATJ,kBAaI,QAAA,MAGF,yBACE,iC9B0lIF,uC8BxlII,YAAA,OAWN,eACE,SAAA,SACA,MAAA,MACA,QAAA,IAAA,KACA,aAAA,KC9LA,WAAA,IACA,cAAA,ID+LA,iBAAA,YACA,iBAAA,KACA,OAAA,IAAA,MAAA,YACA,cAAA,IAIA,qBACE,QAAA,EAdJ,yBAmBI,QAAA,MACA,MAAA,KACA,OAAA,IACA,cAAA,IAtBJ,mCAyBI,WAAA,IAGF,yBAAA,eACE,QAAA,MAUJ,YACE,OAAA,MAAA,MADF,iBAII,YAAA,KACA,eAAA,KACA,YAAA,KAGF,yBAAA,iCAGI,SAAA,OACA,MAAA,KACA,MAAA,KACA,WAAA,EACA,iBAAA,YACA,OAAA,EACA,mBAAA,KAAA,WAAA,K9BykIJ,kD8BllIA,sCAYM,QAAA,IAAA,KAAA,IAAA,KAZN,sCAeM,YAAA,K9B0kIN,4C8BzkIM,4CAEE,iBAAA,MAOR,yBAAA,YACE,MAAA,KACA,OAAA,EAFF,eAKI,MAAA,KALJ,iBAOM,YAAA,KACA,eAAA,MAYR,aACE,QAAA,KAAA,KACA,aAAA,MACA,YAAA,MACA,WAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,Y1B5NA,mBAAA,MAAA,EAAA,IAAA,EAAA,oBAAA,CAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,oBAAA,CAAA,EAAA,IAAA,EAAA,qB2BjER,WAAA,IACA,cAAA,Id6cA,yBAAA,yBAGI,QAAA,aACA,cAAA,EACA,eAAA,OALJ,2BAUI,QAAA,aACA,MAAA,KACA,eAAA,OAZJ,kCAiBI,QAAA,aAjBJ,0BAqBI,QAAA,aACA,eAAA,OjB+4HJ,wCiBr6HA,6CjBo6HA,2CiBz4HM,MAAA,KA3BN,wCAiCI,MAAA,KAjCJ,4BAqCI,cAAA,EACA,eAAA,OjB04HJ,uBiBh7HA,oBA6CI,QAAA,aACA,WAAA,EACA,cAAA,EACA,eAAA,OjBu4HJ,6BiBv7HA,0BAmDM,aAAA,EjBw4HN,4CiB37HA,sCAwDI,SAAA,SACA,YAAA,EAzDJ,kDA8DI,IAAA,GaxOF,yBAAA,yBACE,cAAA,IAEA,oCACE,cAAA,GASN,yBAAA,aACE,MAAA,KACA,YAAA,EACA,eAAA,EACA,aAAA,EACA,YAAA,EACA,OAAA,E1BvPF,mBAAA,KACQ,WAAA,M0B+PV,8BACE,WAAA,EHpUA,uBAAA,EACA,wBAAA,EGuUF,mDACE,cAAA,EHzUA,uBAAA,IACA,wBAAA,IAOA,2BAAA,EACA,0BAAA,EG0UF,YChVE,WAAA,IACA,cAAA,IDkVA,mBCnVA,WAAA,KACA,cAAA,KDqVA,mBCtVA,WAAA,KACA,cAAA,KD+VF,aChWE,WAAA,KACA,cAAA,KDkWA,yBAAA,aACE,MAAA,KACA,aAAA,KACA,YAAA,MAaJ,yBACE,aEtWA,MAAA,eFuWA,cE1WA,MAAA,gBF4WE,aAAA,MAFF,4BAKI,aAAA,GAUN,gBACE,iBAAA,QACA,aAAA,QAFF,8BAKI,MAAA,K9BmlIJ,oC8BllII,oCAEE,MAAA,QACA,iBAAA,YATN,6BAcI,MAAA,KAdJ,iCAmBM,MAAA,K9BglIN,uC8B9kIM,uCAEE,MAAA,KACA,iBAAA,YAIF,sC9B6kIN,4CADA,4C8BzkIQ,MAAA,KACA,iBAAA,QAIF,wC9B2kIN,8CADA,8C8BvkIQ,MAAA,KACA,iBAAA,YAOF,oC9BskIN,0CADA,0C8BlkIQ,MAAA,KACA,iBAAA,QAIJ,yBAAA,sDAIM,MAAA,K9BmkIR,4D8BlkIQ,4DAEE,MAAA,KACA,iBAAA,YAIF,2D9BikIR,iEADA,iE8B7jIU,MAAA,KACA,iBAAA,QAIF,6D9B+jIR,mEADA,mE8B3jIU,MAAA,KACA,iBAAA,aA/EZ,+BAuFI,aAAA,K9B4jIJ,qC8B3jII,qCAEE,iBAAA,KA1FN,yCA6FM,iBAAA,KA7FN,iC9B0pIA,6B8BvjII,aAAA,QAnGJ,6BA4GI,MAAA,KACA,mCACE,MAAA,KA9GN,0BAmHI,MAAA,K9BojIJ,gC8BnjII,gCAEE,MAAA,K9BsjIN,0C8BljIM,0C9BmjIN,mDAFA,mD8B/iIQ,MAAA,KAQR,gBACE,iBAAA,KACA,aAAA,QAFF,8BAKI,MAAA,Q9B+iIJ,oC8B9iII,oCAEE,MAAA,KACA,iBAAA,YATN,6BAcI,MAAA,QAdJ,iCAmBM,MAAA,Q9B4iIN,uC8B1iIM,uCAEE,MAAA,KACA,iBAAA,YAIF,sC9ByiIN,4CADA,4C8BriIQ,MAAA,KACA,iBAAA,QAIF,wC9BuiIN,8CADA,8C8BniIQ,MAAA,KACA,iBAAA,YAMF,oC9BmiIN,0CADA,0C8B/hIQ,MAAA,KACA,iBAAA,QAIJ,yBAAA,kEAIM,aAAA,QAJN,0DAOM,iBAAA,QAPN,sDAUM,MAAA,Q9BgiIR,4D8B/hIQ,4DAEE,MAAA,KACA,iBAAA,YAIF,2D9B8hIR,iEADA,iE8B1hIU,MAAA,KACA,iBAAA,QAIF,6D9B4hIR,mEADA,mE8BxhIU,MAAA,KACA,iBAAA,aApFZ,+BA6FI,aAAA,K9BwhIJ,qC8BvhII,qCAEE,iBAAA,KAhGN,yCAmGM,iBAAA,KAnGN,iC9B4nIA,6B8BnhII,aAAA,QAzGJ,6BA6GI,MAAA,QACA,mCACE,MAAA,KA/GN,0BAoHI,MAAA,Q9BqhIJ,gC8BphII,gCAEE,MAAA,K9BuhIN,0C8BnhIM,0C9BohIN,mDAFA,mD8BhhIQ,MAAA,KGtoBR,YACE,QAAA,IAAA,KACA,cAAA,KACA,WAAA,KACA,iBAAA,QACA,cAAA,IALF,eAQI,QAAA,aARJ,yBAWM,QAAA,EAAA,IACA,MAAA,KACA,QAAA,SAbN,oBAkBI,MAAA,KCpBJ,YACE,QAAA,aACA,aAAA,EACA,OAAA,KAAA,EACA,cAAA,IAJF,eAOI,QAAA,OAPJ,iBlCyrJA,oBkC/qJM,SAAA,SACA,MAAA,KACA,QAAA,IAAA,KACA,YAAA,KACA,YAAA,WACA,MAAA,QACA,gBAAA,KACA,iBAAA,KACA,OAAA,IAAA,MAAA,KlCorJN,uBkClrJM,uBlCmrJN,0BAFA,0BkC/qJQ,QAAA,EACA,MAAA,QACA,iBAAA,KACA,aAAA,KAGJ,6BlCkrJJ,gCkC/qJQ,YAAA,EPnBN,uBAAA,IACA,0BAAA,IOsBE,4BlCirJJ,+B2BhtJE,wBAAA,IACA,2BAAA,IOwCE,sBlC+qJJ,4BAFA,4BADA,yBAIA,+BAFA,+BkC3qJM,QAAA,EACA,MAAA,KACA,OAAA,QACA,iBAAA,QACA,aAAA,QlCmrJN,wBAEA,8BADA,8BkCxuJA,2BlCsuJA,iCADA,iCkCtqJM,MAAA,KACA,OAAA,YACA,iBAAA,KACA,aAAA,KASN,oBlCqqJA,uBmC7uJM,QAAA,KAAA,KACA,UAAA,KACA,YAAA,UAEF,gCnC+uJJ,mC2B1uJE,uBAAA,IACA,0BAAA,IQAE,+BnC8uJJ,kC2BvvJE,wBAAA,IACA,2BAAA,IO2EF,oBlCgrJA,uBmC7vJM,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IAEF,gCnC+vJJ,mC2B1vJE,uBAAA,IACA,0BAAA,IQAE,+BnC8vJJ,kC2BvwJE,wBAAA,IACA,2BAAA,ISHF,OACE,aAAA,EACA,OAAA,KAAA,EACA,WAAA,OACA,WAAA,KAJF,UAOI,QAAA,OAPJ,YpCuxJA,eoC7wJM,QAAA,aACA,QAAA,IAAA,KACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,cAAA,KpCixJN,kBoC/xJA,kBAmBM,gBAAA,KACA,iBAAA,KApBN,epCoyJA,kBoCzwJM,MAAA,MA3BN,mBpCwyJA,sBoCtwJM,MAAA,KAlCN,mBpC6yJA,yBADA,yBAEA,sBoCnwJM,MAAA,KACA,OAAA,YACA,iBAAA,KC9CN,OACE,QAAA,OACA,QAAA,KAAA,KAAA,KACA,UAAA,IACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OACA,YAAA,OACA,eAAA,SACA,cAAA,MrCuzJF,cqCnzJI,cAEE,MAAA,KACA,gBAAA,KACA,OAAA,QAKJ,aACE,QAAA,KAIF,YACE,SAAA,SACA,IAAA,KAOJ,eCtCE,iBAAA,KtCk1JF,2BsC/0JI,2BAEE,iBAAA,QDqCN,eC1CE,iBAAA,QtCy1JF,2BsCt1JI,2BAEE,iBAAA,QDyCN,eC9CE,iBAAA,QtCg2JF,2BsC71JI,2BAEE,iBAAA,QD6CN,YClDE,iBAAA,QtCu2JF,wBsCp2JI,wBAEE,iBAAA,QDiDN,eCtDE,iBAAA,QtC82JF,2BsC32JI,2BAEE,iBAAA,QDqDN,cC1DE,iBAAA,QtCq3JF,0BsCl3JI,0BAEE,iBAAA,QCFN,OACE,QAAA,aACA,UAAA,KACA,QAAA,IAAA,IACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OACA,YAAA,OACA,eAAA,OACA,iBAAA,KACA,cAAA,KAGA,aACE,QAAA,KAIF,YACE,SAAA,SACA,IAAA,KvCq3JJ,0BuCl3JE,eAEE,IAAA,EACA,QAAA,IAAA,IvCo3JJ,cuC/2JI,cAEE,MAAA,KACA,gBAAA,KACA,OAAA,QAKJ,+BvC42JF,4BuC12JI,MAAA,QACA,iBAAA,KAGF,wBACE,MAAA,MAGF,+BACE,aAAA,IAGF,uBACE,YAAA,IC1DJ,WACE,YAAA,KACA,eAAA,KACA,cAAA,KACA,MAAA,QACA,iBAAA,KxCu6JF,ewC56JA,cASI,MAAA,QATJ,aAaI,cAAA,KACA,UAAA,KACA,YAAA,IAfJ,cAmBI,iBAAA,QAGF,sBxCk6JF,4BwCh6JI,cAAA,KACA,aAAA,KACA,cAAA,IA1BJ,sBA8BI,UAAA,KAGF,oCAAA,WACE,YAAA,KACA,eAAA,KAEA,sBxCi6JF,4BwC/5JI,cAAA,KACA,aAAA,KxCm6JJ,ewC16JA,cAYI,UAAA,MC1CN,WACE,QAAA,MACA,QAAA,IACA,cAAA,KACA,YAAA,WACA,iBAAA,KACA,OAAA,IAAA,MAAA,KACA,cAAA,IrCiLA,mBAAA,OAAA,IAAA,YACK,cAAA,OAAA,IAAA,YACG,WAAA,OAAA,IAAA,YJ+xJV,iByCz9JA,eAaI,aAAA,KACA,YAAA,KzCi9JJ,mBADA,kByC58JE,kBAGE,aAAA,QArBJ,oBA0BI,QAAA,IACA,MAAA,KC3BJ,OACE,QAAA,KACA,cAAA,KACA,OAAA,IAAA,MAAA,YACA,cAAA,IAJF,UAQI,WAAA,EACA,MAAA,QATJ,mBAcI,YAAA,IAdJ,S1Co/JA,U0Ch+JI,cAAA,EApBJ,WAwBI,WAAA,IASJ,mB1C09JA,mB0Cx9JE,cAAA,KAFF,0B1C89JA,0B0Cx9JI,SAAA,SACA,IAAA,KACA,MAAA,MACA,MAAA,QAQJ,eCvDE,MAAA,QACA,iBAAA,QACA,aAAA,QDqDF,kBClDI,iBAAA,QDkDJ,2BC9CI,MAAA,QDkDJ,YC3DE,MAAA,QACA,iBAAA,QACA,aAAA,QDyDF,eCtDI,iBAAA,QDsDJ,wBClDI,MAAA,QDsDJ,eC/DE,MAAA,QACA,iBAAA,QACA,aAAA,QD6DF,kBC1DI,iBAAA,QD0DJ,2BCtDI,MAAA,QD0DJ,cCnEE,MAAA,QACA,iBAAA,QACA,aAAA,QDiEF,iBC9DI,iBAAA,QD8DJ,0BC1DI,MAAA,QCDJ,wCACE,KAAQ,oBAAA,KAAA,EACR,GAAQ,oBAAA,EAAA,GAIV,mCACE,KAAQ,oBAAA,KAAA,EACR,GAAQ,oBAAA,EAAA,GAFV,gCACE,KAAQ,oBAAA,KAAA,EACR,GAAQ,oBAAA,EAAA,GAQV,UACE,OAAA,KACA,cAAA,KACA,SAAA,OACA,iBAAA,QACA,cAAA,IxCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,eACQ,WAAA,MAAA,EAAA,IAAA,IAAA,ewClCV,cACE,MAAA,KACA,MAAA,GACA,OAAA,KACA,UAAA,KACA,YAAA,KACA,MAAA,KACA,WAAA,OACA,iBAAA,QxCyBA,mBAAA,MAAA,EAAA,KAAA,EAAA,gBACQ,WAAA,MAAA,EAAA,KAAA,EAAA,gBAyHR,mBAAA,MAAA,IAAA,KACK,cAAA,MAAA,IAAA,KACG,WAAA,MAAA,IAAA,KJw6JV,sB4CnjKA,gCCDI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKDEF,wBAAA,KAAA,KAAA,gBAAA,KAAA,K5CwjKF,qB4CjjKA,+BxC5CE,kBAAA,qBAAA,GAAA,OAAA,SACK,aAAA,qBAAA,GAAA,OAAA,SACG,UAAA,qBAAA,GAAA,OAAA,SwCmDV,sBEvEE,iBAAA,QAGA,wCDgDE,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKDsBJ,mBE3EE,iBAAA,QAGA,qCDgDE,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKD0BJ,sBE/EE,iBAAA,QAGA,wCDgDE,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKD8BJ,qBEnFE,iBAAA,QAGA,uCDgDE,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKExDJ,OAEE,WAAA,KAEA,mBACE,WAAA,EAIJ,O/CqpKA,Y+CnpKE,SAAA,OACA,KAAA,EAGF,YACE,MAAA,QAGF,cACE,QAAA,MAGA,4BACE,UAAA,KAIJ,a/CgpKA,mB+C9oKE,aAAA,KAGF,Y/C+oKA,kB+C7oKE,cAAA,K/CkpKF,Y+C/oKA,Y/C8oKA,a+C3oKE,QAAA,WACA,eAAA,IAGF,cACE,eAAA,OAGF,cACE,eAAA,OAIF,eACE,WAAA,EACA,cAAA,IAMF,YACE,aAAA,EACA,WAAA,KCrDF,YAEE,aAAA,EACA,cAAA,KAQF,iBACE,SAAA,SACA,QAAA,MACA,QAAA,KAAA,KAEA,cAAA,KACA,iBAAA,KACA,OAAA,IAAA,MAAA,KAGA,6BrB7BA,uBAAA,IACA,wBAAA,IqB+BA,4BACE,cAAA,ErBzBF,2BAAA,IACA,0BAAA,IqB6BA,0BhDqrKF,gCADA,gCgDjrKI,MAAA,KACA,OAAA,YACA,iBAAA,KALF,mDhD4rKF,yDADA,yDgDlrKM,MAAA,QATJ,gDhDisKF,sDADA,sDgDprKM,MAAA,KAKJ,wBhDqrKF,8BADA,8BgDjrKI,QAAA,EACA,MAAA,KACA,iBAAA,QACA,aAAA,QANF,iDhDisKF,wDAHA,uDADA,uDAMA,8DAHA,6DAJA,uDAMA,8DAHA,6DgDnrKM,MAAA,QAZJ,8ChDwsKF,oDADA,oDgDxrKM,MAAA,QAWN,kBhDkrKA,uBgDhrKE,MAAA,KAFF,2ChDsrKA,gDgDjrKI,MAAA,KhDsrKJ,wBgDlrKE,wBhDmrKF,6BAFA,6BgD/qKI,MAAA,KACA,gBAAA,KACA,iBAAA,QAIJ,uBACE,MAAA,KACA,WAAA,KnCvGD,yBoCIG,MAAA,QACA,iBAAA,QAEA,0BjDuxKJ,+BiDrxKM,MAAA,QAFF,mDjD2xKJ,wDiDtxKQ,MAAA,QjD2xKR,gCiDxxKM,gCjDyxKN,qCAFA,qCiDrxKQ,MAAA,QACA,iBAAA,QAEF,iCjD4xKN,uCAFA,uCADA,sCAIA,4CAFA,4CiDxxKQ,MAAA,KACA,iBAAA,QACA,aAAA,QpCzBP,sBoCIG,MAAA,QACA,iBAAA,QAEA,uBjDozKJ,4BiDlzKM,MAAA,QAFF,gDjDwzKJ,qDiDnzKQ,MAAA,QjDwzKR,6BiDrzKM,6BjDszKN,kCAFA,kCiDlzKQ,MAAA,QACA,iBAAA,QAEF,8BjDyzKN,oCAFA,oCADA,mCAIA,yCAFA,yCiDrzKQ,MAAA,KACA,iBAAA,QACA,aAAA,QpCzBP,yBoCIG,MAAA,QACA,iBAAA,QAEA,0BjDi1KJ,+BiD/0KM,MAAA,QAFF,mDjDq1KJ,wDiDh1KQ,MAAA,QjDq1KR,gCiDl1KM,gCjDm1KN,qCAFA,qCiD/0KQ,MAAA,QACA,iBAAA,QAEF,iCjDs1KN,uCAFA,uCADA,sCAIA,4CAFA,4CiDl1KQ,MAAA,KACA,iBAAA,QACA,aAAA,QpCzBP,wBoCIG,MAAA,QACA,iBAAA,QAEA,yBjD82KJ,8BiD52KM,MAAA,QAFF,kDjDk3KJ,uDiD72KQ,MAAA,QjDk3KR,+BiD/2KM,+BjDg3KN,oCAFA,oCiD52KQ,MAAA,QACA,iBAAA,QAEF,gCjDm3KN,sCAFA,sCADA,qCAIA,2CAFA,2CiD/2KQ,MAAA,KACA,iBAAA,QACA,aAAA,QDiGR,yBACE,WAAA,EACA,cAAA,IAEF,sBACE,cAAA,EACA,YAAA,IExHF,OACE,cAAA,KACA,iBAAA,KACA,OAAA,IAAA,MAAA,YACA,cAAA,I9C0DA,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gB8CtDV,YACE,QAAA,KAKF,eACE,QAAA,KAAA,KACA,cAAA,IAAA,MAAA,YvBtBA,uBAAA,IACA,wBAAA,IuBmBF,0CAMI,MAAA,QAKJ,aACE,WAAA,EACA,cAAA,EACA,UAAA,KACA,MAAA,QlD24KF,oBAEA,sBkDj5KA,elD84KA,mBAEA,qBkDr4KI,MAAA,QAKJ,cACE,QAAA,KAAA,KACA,iBAAA,QACA,WAAA,IAAA,MAAA,KvB1CA,2BAAA,IACA,0BAAA,IuBmDF,mBlD+3KA,mCkD53KI,cAAA,EAHJ,oClDm4KA,oDkD73KM,aAAA,IAAA,EACA,cAAA,EAIF,4DlD63KJ,4EkD33KQ,WAAA,EvBzEN,uBAAA,IACA,wBAAA,IuB8EE,0DlD23KJ,0EkDz3KQ,cAAA,EvBzEN,2BAAA,IACA,0BAAA,IuBmDF,+EvB5DE,uBAAA,EACA,wBAAA,EuB4FF,wDAEI,iBAAA,EAGJ,0BACE,iBAAA,ElDw3KF,8BkDh3KA,clD+2KA,gCkD32KI,cAAA,ElDi3KJ,sCkDr3KA,sBlDo3KA,wCkD72KM,cAAA,KACA,aAAA,KlDk3KN,wDkD13KA,0BvB3GE,uBAAA,IACA,wBAAA,I3B2+KF,yFAFA,yFACA,2DkDh4KA,2DAmBQ,uBAAA,IACA,wBAAA,IlDo3KR,wGAIA,wGANA,wGAIA,wGAHA,0EAIA,0EkD34KA,0ElDy4KA,0EkDj3KU,uBAAA,IlD03KV,uGAIA,uGANA,uGAIA,uGAHA,yEAIA,yEkDr5KA,yElDm5KA,yEkDv3KU,wBAAA,IlD83KV,sDkD15KA,yBvBnGE,2BAAA,IACA,0BAAA,I3BigLF,qFAEA,qFkDj6KA,wDlDg6KA,wDkDv3KQ,2BAAA,IACA,0BAAA,IlD43KR,oGAIA,oGAFA,oGAIA,oGkD56KA,uElDy6KA,uEAFA,uEAIA,uEkD73KU,0BAAA,IlDk4KV,mGAIA,mGAFA,mGAIA,mGkDt7KA,sElDm7KA,sEAFA,sEAIA,sEkDn4KU,2BAAA,IAlDV,0BlD07KA,qCACA,0BACA,qCkDj4KI,WAAA,IAAA,MAAA,KlDq4KJ,kDkDh8KA,kDA+DI,WAAA,EA/DJ,uBlDo8KA,yCkDj4KI,OAAA,ElD44KJ,+CANA,+CAQA,+CANA,+CAEA,+CkD78KA,+ClDg9KA,iEANA,iEAQA,iEANA,iEAEA,iEANA,iEkD93KU,YAAA,ElDm5KV,8CANA,8CAQA,8CANA,8CAEA,8CkD39KA,8ClD89KA,gEANA,gEAQA,gEANA,gEAEA,gEANA,gEkDx4KU,aAAA,ElDu5KV,+CAIA,+CkDz+KA,+ClDu+KA,+CADA,iEAIA,iEANA,iEAIA,iEkDj5KU,cAAA,EAvFV,8ClDi/KA,8CAFA,8CAIA,8CALA,gEAIA,gEAFA,gEAIA,gEkDp5KU,cAAA,EAhGV,yBAsGI,cAAA,EACA,OAAA,EAUJ,aACE,cAAA,KADF,oBAKI,cAAA,EACA,cAAA,IANJ,2BASM,WAAA,IATN,4BAcI,cAAA,ElD04KJ,wDkDx5KA,wDAkBM,WAAA,IAAA,MAAA,KAlBN,2BAuBI,WAAA,EAvBJ,uDAyBM,cAAA,IAAA,MAAA,KAON,eC5PE,aAAA,KAEA,8BACE,MAAA,KACA,iBAAA,QACA,aAAA,KAHF,0DAMI,iBAAA,KANJ,qCASI,MAAA,QACA,iBAAA,KAGJ,yDAEI,oBAAA,KD8ON,eC/PE,aAAA,QAEA,8BACE,MAAA,KACA,iBAAA,QACA,aAAA,QAHF,0DAMI,iBAAA,QANJ,qCASI,MAAA,QACA,iBAAA,KAGJ,yDAEI,oBAAA,QDiPN,eClQE,aAAA,QAEA,8BACE,MAAA,QACA,iBAAA,QACA,aAAA,QAHF,0DAMI,iBAAA,QANJ,qCASI,MAAA,QACA,iBAAA,QAGJ,yDAEI,oBAAA,QDoPN,YCrQE,aAAA,QAEA,2BACE,MAAA,QACA,iBAAA,QACA,aAAA,QAHF,uDAMI,iBAAA,QANJ,kCASI,MAAA,QACA,iBAAA,QAGJ,sDAEI,oBAAA,QDuPN,eCxQE,aAAA,QAEA,8BACE,MAAA,QACA,iBAAA,QACA,aAAA,QAHF,0DAMI,iBAAA,QANJ,qCASI,MAAA,QACA,iBAAA,QAGJ,yDAEI,oBAAA,QD0PN,cC3QE,aAAA,QAEA,6BACE,MAAA,QACA,iBAAA,QACA,aAAA,QAHF,yDAMI,iBAAA,QANJ,oCASI,MAAA,QACA,iBAAA,QAGJ,wDAEI,oBAAA,QChBN,kBACE,SAAA,SACA,QAAA,MACA,OAAA,EACA,QAAA,EACA,SAAA,OALF,yCpDivLA,wBADA,yBAEA,yBACA,wBoDvuLI,SAAA,SACA,IAAA,EACA,OAAA,EACA,KAAA,EACA,MAAA,KACA,OAAA,KACA,OAAA,EAKJ,wBACE,eAAA,OAIF,uBACE,eAAA,IC3BF,MACE,WAAA,KACA,QAAA,KACA,cAAA,KACA,iBAAA,QACA,OAAA,IAAA,MAAA,QACA,cAAA,IjD0DA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBiDjEV,iBASI,aAAA,KACA,aAAA,gBAKJ,SACE,QAAA,KACA,cAAA,IAEF,SACE,QAAA,IACA,cAAA,ICpBF,OACE,MAAA,MACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,YAAA,EAAA,IAAA,EAAA,KjCTA,OAAA,kBACA,QAAA,GrBkyLF,asDvxLE,aAEE,MAAA,KACA,gBAAA,KACA,OAAA,QjChBF,OAAA,kBACA,QAAA,GiCuBA,aACE,QAAA,EACA,OAAA,QACA,WAAA,IACA,OAAA,EACA,mBAAA,KACA,gBAAA,KAAA,WAAA,KCxBJ,YACE,SAAA,OAIF,OACE,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,SAAA,OACA,2BAAA,MAIA,QAAA,EAGA,0BnDiHA,kBAAA,kBACI,cAAA,kBACC,aAAA,kBACG,UAAA,kBAkER,mBAAA,kBAAA,IAAA,SAEK,cAAA,aAAA,IAAA,SACG,WAAA,kBAAA,IAAA,SAAA,WAAA,UAAA,IAAA,SAAA,WAAA,UAAA,IAAA,QAAA,CAAA,kBAAA,IAAA,QAAA,CAAA,aAAA,IAAA,SmDrLR,wBnD6GA,kBAAA,eACI,cAAA,eACC,aAAA,eACG,UAAA,emD9GV,mBACE,WAAA,OACA,WAAA,KAIF,cACE,SAAA,SACA,MAAA,KACA,OAAA,KAIF,eACE,SAAA,SACA,iBAAA,KACA,gBAAA,YACA,OAAA,IAAA,MAAA,KACA,OAAA,IAAA,MAAA,eACA,cAAA,InDcA,mBAAA,EAAA,IAAA,IAAA,eACQ,WAAA,EAAA,IAAA,IAAA,emDZR,QAAA,EAIF,gBACE,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EACA,QAAA,KACA,iBAAA,KAEA,qBlCpEA,OAAA,iBACA,QAAA,EkCoEA,mBlCrEA,OAAA,kBACA,QAAA,GkCyEF,cACE,QAAA,KACA,cAAA,IAAA,MAAA,QAIF,qBACE,WAAA,KAIF,aACE,OAAA,EACA,YAAA,WAKF,YACE,SAAA,SACA,QAAA,KAIF,cACE,QAAA,KACA,WAAA,MACA,WAAA,IAAA,MAAA,QAHF,wBAQI,cAAA,EACA,YAAA,IATJ,mCAaI,YAAA,KAbJ,oCAiBI,YAAA,EAKJ,yBACE,SAAA,SACA,IAAA,QACA,MAAA,KACA,OAAA,KACA,SAAA,OAIF,yBAEE,cACE,MAAA,MACA,OAAA,KAAA,KAEF,enDrEA,mBAAA,EAAA,IAAA,KAAA,eACQ,WAAA,EAAA,IAAA,KAAA,emDyER,UAAY,MAAA,OAGd,yBACE,UAAY,MAAA,OC9Id,SACE,SAAA,SACA,QAAA,KACA,QAAA,MCRA,YAAA,gBAAA,CAAA,SAAA,CAAA,KAAA,CAAA,WAEA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KACA,eAAA,OACA,WAAA,OACA,aAAA,OACA,UAAA,OACA,YAAA,ODHA,UAAA,KnCTA,OAAA,iBACA,QAAA,EmCYA,YnCbA,OAAA,kBACA,QAAA,GmCaA,aACE,QAAA,IAAA,EACA,WAAA,KAEF,eACE,QAAA,EAAA,IACA,YAAA,IAEF,gBACE,QAAA,IAAA,EACA,WAAA,IAEF,cACE,QAAA,EAAA,IACA,YAAA,KAIF,4BACE,OAAA,EACA,KAAA,IACA,YAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEF,iCACE,MAAA,IACA,OAAA,EACA,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEF,kCACE,OAAA,EACA,KAAA,IACA,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEF,8BACE,IAAA,IACA,KAAA,EACA,WAAA,KACA,aAAA,IAAA,IAAA,IAAA,EACA,mBAAA,KAEF,6BACE,IAAA,IACA,MAAA,EACA,WAAA,KACA,aAAA,IAAA,EAAA,IAAA,IACA,kBAAA,KAEF,+BACE,IAAA,EACA,KAAA,IACA,YAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEF,oCACE,IAAA,EACA,MAAA,IACA,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEF,qCACE,IAAA,EACA,KAAA,IACA,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAKJ,eACE,UAAA,MACA,QAAA,IAAA,IACA,MAAA,KACA,WAAA,OACA,iBAAA,KACA,cAAA,IAIF,eACE,SAAA,SACA,MAAA,EACA,OAAA,EACA,aAAA,YACA,aAAA,MEzGF,SACE,SAAA,SACA,IAAA,EACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,UAAA,MACA,QAAA,IDXA,YAAA,gBAAA,CAAA,SAAA,CAAA,KAAA,CAAA,WAEA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KACA,eAAA,OACA,WAAA,OACA,aAAA,OACA,UAAA,OACA,YAAA,OCAA,UAAA,KACA,iBAAA,KACA,gBAAA,YACA,OAAA,IAAA,MAAA,KACA,OAAA,IAAA,MAAA,eACA,cAAA,ItDiDA,mBAAA,EAAA,IAAA,KAAA,eACQ,WAAA,EAAA,IAAA,KAAA,esD9CR,aAAQ,WAAA,MACR,eAAU,YAAA,KACV,gBAAW,WAAA,KACX,cAAS,YAAA,MAvBX,gBA4BI,aAAA,KAEA,gB1DkjMJ,sB0DhjMM,SAAA,SACA,QAAA,MACA,MAAA,EACA,OAAA,EACA,aAAA,YACA,aAAA,MAGF,sBACE,QAAA,GACA,aAAA,KAIJ,oBACE,OAAA,MACA,KAAA,IACA,YAAA,MACA,iBAAA,KACA,iBAAA,gBACA,oBAAA,EACA,0BACE,OAAA,IACA,YAAA,MACA,QAAA,IACA,iBAAA,KACA,oBAAA,EAGJ,sBACE,IAAA,IACA,KAAA,MACA,WAAA,MACA,mBAAA,KACA,mBAAA,gBACA,kBAAA,EACA,4BACE,OAAA,MACA,KAAA,IACA,QAAA,IACA,mBAAA,KACA,kBAAA,EAGJ,uBACE,IAAA,MACA,KAAA,IACA,YAAA,MACA,iBAAA,EACA,oBAAA,KACA,oBAAA,gBACA,6BACE,IAAA,IACA,YAAA,MACA,QAAA,IACA,iBAAA,EACA,oBAAA,KAIJ,qBACE,IAAA,IACA,MAAA,MACA,WAAA,MACA,mBAAA,EACA,kBAAA,KACA,kBAAA,gBACA,2BACE,MAAA,IACA,OAAA,MACA,QAAA,IACA,mBAAA,EACA,kBAAA,KAKN,eACE,QAAA,IAAA,KACA,OAAA,EACA,UAAA,KACA,iBAAA,QACA,cAAA,IAAA,MAAA,QACA,cAAA,IAAA,IAAA,EAAA,EAGF,iBACE,QAAA,IAAA,KCpHF,UACE,SAAA,SAGF,gBACE,SAAA,SACA,MAAA,KACA,SAAA,OAHF,sBAMI,SAAA,SACA,QAAA,KvD6KF,mBAAA,IAAA,YAAA,KACK,cAAA,IAAA,YAAA,KACG,WAAA,IAAA,YAAA,KJs/LV,4B2D5qMA,0BAcM,YAAA,EAIF,8BAAA,uBAAA,sBvDuLF,mBAAA,kBAAA,IAAA,YAEK,cAAA,aAAA,IAAA,YACG,WAAA,kBAAA,IAAA,YAAA,WAAA,UAAA,IAAA,YAAA,WAAA,UAAA,IAAA,WAAA,CAAA,kBAAA,IAAA,WAAA,CAAA,aAAA,IAAA,YA7JR,4BAAA,OAEQ,oBAAA,OA+GR,oBAAA,OAEQ,YAAA,OJ0hMR,mC2DrqMI,2BvDmHJ,kBAAA,sBACQ,UAAA,sBuDjHF,KAAA,E3DwqMN,kC2DtqMI,2BvD8GJ,kBAAA,uBACQ,UAAA,uBuD5GF,KAAA,E3D0qMN,6B2DxqMI,gC3DuqMJ,iCI9jMA,kBAAA,mBACQ,UAAA,mBuDtGF,KAAA,GArCR,wB3DgtMA,sBACA,sB2DpqMI,QAAA,MA7CJ,wBAiDI,KAAA,EAjDJ,sB3DwtMA,sB2DlqMI,SAAA,SACA,IAAA,EACA,MAAA,KAxDJ,sBA4DI,KAAA,KA5DJ,sBA+DI,KAAA,MA/DJ,2B3DouMA,4B2DjqMI,KAAA,EAnEJ,6BAuEI,KAAA,MAvEJ,8BA0EI,KAAA,KAQJ,kBACE,SAAA,SACA,IAAA,EACA,OAAA,EACA,KAAA,EACA,MAAA,IACA,UAAA,KACA,MAAA,KACA,WAAA,OACA,YAAA,EAAA,IAAA,IAAA,eACA,iBAAA,ctCpGA,OAAA,kBACA,QAAA,GsCyGA,uBdrGE,iBAAA,sEACA,iBAAA,iEACA,iBAAA,uFAAA,iBAAA,kEACA,OAAA,+GACA,kBAAA,ScoGF,wBACE,MAAA,EACA,KAAA,Kd1GA,iBAAA,sEACA,iBAAA,iEACA,iBAAA,uFAAA,iBAAA,kEACA,OAAA,+GACA,kBAAA,S7C6wMJ,wB2DlqME,wBAEE,MAAA,KACA,gBAAA,KACA,QAAA,EtCxHF,OAAA,kBACA,QAAA,GrB8xMF,0CACA,2CAFA,6B2DpsMA,6BAuCI,SAAA,SACA,IAAA,IACA,QAAA,EACA,QAAA,aACA,WAAA,M3DmqMJ,0C2D9sMA,6BA+CI,KAAA,IACA,YAAA,M3DmqMJ,2C2DntMA,6BAoDI,MAAA,IACA,aAAA,M3DmqMJ,6B2DxtMA,6BAyDI,MAAA,KACA,OAAA,KACA,YAAA,MACA,YAAA,EAIA,oCACE,QAAA,QAIF,oCACE,QAAA,QAUN,qBACE,SAAA,SACA,OAAA,KACA,KAAA,IACA,QAAA,GACA,MAAA,IACA,aAAA,EACA,YAAA,KACA,WAAA,OACA,WAAA,KATF,wBAYI,QAAA,aACA,MAAA,KACA,OAAA,KACA,OAAA,IACA,YAAA,OACA,OAAA,QAUA,iBAAA,OACA,iBAAA,cAEA,OAAA,IAAA,MAAA,KACA,cAAA,KA/BJ,6BAmCI,MAAA,KACA,OAAA,KACA,OAAA,EACA,iBAAA,KAOJ,kBACE,SAAA,SACA,MAAA,IACA,OAAA,KACA,KAAA,IACA,QAAA,GACA,YAAA,KACA,eAAA,KACA,MAAA,KACA,WAAA,OACA,YAAA,EAAA,IAAA,IAAA,eAEA,uBACE,YAAA,KAMJ,oCAGE,0C3D+nMA,2CAEA,6BADA,6B2D3nMI,MAAA,KACA,OAAA,KACA,WAAA,MACA,UAAA,KARJ,0C3DwoMA,6B2D5nMI,YAAA,MAZJ,2C3D4oMA,6B2D5nMI,aAAA,MAKJ,kBACE,MAAA,IACA,KAAA,IACA,eAAA,KAIF,qBACE,OAAA,M3D0oMJ,qCADA,sCADA,mBADA,oBAXA,gB4D73ME,iB5Dm4MF,uBADA,wBADA,iBADA,kBADA,wBADA,yBASA,mCADA,oCAqBA,oBADA,qBADA,oBADA,qBAXA,WADA,YAOA,uBADA,wBADA,qBADA,sBADA,cADA,eAOA,aADA,cAGA,kBADA,mBAjBA,WADA,Y4Dl4MI,QAAA,MACA,QAAA,I5Dm6MJ,qCADA,mB4Dh6ME,gB5D65MF,uBADA,iBADA,wBAIA,mCAUA,oBADA,oBANA,WAGA,uBADA,qBADA,cAGA,aACA,kBATA,W4D75MI,MAAA,K5BNJ,c6BVE,QAAA,MACA,aAAA,KACA,YAAA,K7BWF,YACE,MAAA,gBAEF,WACE,MAAA,eAQF,MACE,QAAA,eAEF,MACE,QAAA,gBAEF,WACE,WAAA,OAEF,W8BzBE,KAAA,CAAA,CAAA,EAAA,EACA,MAAA,YACA,YAAA,KACA,iBAAA,YACA,OAAA,E9B8BF,QACE,QAAA,eAOF,OACE,SAAA,M+BjCF,cACE,MAAA,a/D88MF,YADA,YADA,Y+Dt8MA,YClBE,QAAA,ehEs+MF,kBACA,mBACA,yBALA,kBACA,mBACA,yBALA,kBACA,mBACA,yB+Dz8MA,kB/Dq8MA,mBACA,yB+D17ME,QAAA,eAIA,yBAAA,YCjDA,QAAA,gBACA,iBAAU,QAAA,gBACV,cAAU,QAAA,oBhE4/MV,cgE3/MA,cACU,QAAA,sBDkDV,yBAAA,kBACE,QAAA,iBAIF,yBAAA,mBACE,QAAA,kBAIF,yBAAA,yBACE,QAAA,wBAKF,+CAAA,YCtEA,QAAA,gBACA,iBAAU,QAAA,gBACV,cAAU,QAAA,oBhE0hNV,cgEzhNA,cACU,QAAA,sBDuEV,+CAAA,kBACE,QAAA,iBAIF,+CAAA,mBACE,QAAA,kBAIF,+CAAA,yBACE,QAAA,wBAKF,gDAAA,YC3FA,QAAA,gBACA,iBAAU,QAAA,gBACV,cAAU,QAAA,oBhEwjNV,cgEvjNA,cACU,QAAA,sBD4FV,gDAAA,kBACE,QAAA,iBAIF,gDAAA,mBACE,QAAA,kBAIF,gDAAA,yBACE,QAAA,wBAKF,0BAAA,YChHA,QAAA,gBACA,iBAAU,QAAA,gBACV,cAAU,QAAA,oBhEslNV,cgErlNA,cACU,QAAA,sBDiHV,0BAAA,kBACE,QAAA,iBAIF,0BAAA,mBACE,QAAA,kBAIF,0BAAA,yBACE,QAAA,wBAKF,yBAAA,WC7HA,QAAA,gBDkIA,+CAAA,WClIA,QAAA,gBDuIA,gDAAA,WCvIA,QAAA,gBD4IA,0BAAA,WC5IA,QAAA,gBDuJF,eCvJE,QAAA,eD0JA,aAAA,eClKA,QAAA,gBACA,oBAAU,QAAA,gBACV,iBAAU,QAAA,oBhE2oNV,iBgE1oNA,iBACU,QAAA,sBDkKZ,qBACE,QAAA,eAEA,aAAA,qBACE,QAAA,iBAGJ,sBACE,QAAA,eAEA,aAAA,sBACE,QAAA,kBAGJ,4BACE,QAAA,eAEA,aAAA,4BACE,QAAA,wBAKF,aAAA,cCrLA,QAAA","sourcesContent":["/*!\n * Bootstrap v3.4.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: none;\n text-decoration: underline;\n text-decoration: underline dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"../fonts/glyphicons-halflings-regular.eot\");\n src: url(\"../fonts/glyphicons-halflings-regular.eot?#iefix\") format(\"embedded-opentype\"), url(\"../fonts/glyphicons-halflings-regular.woff2\") format(\"woff2\"), url(\"../fonts/glyphicons-halflings-regular.woff\") format(\"woff\"), url(\"../fonts/glyphicons-halflings-regular.ttf\") format(\"truetype\"), url(\"../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular\") format(\"svg\");\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: 400;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: \"\\2014 \\00A0\";\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: \"\";\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: \"\\00A0 \\2014\";\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n.row-no-gutters [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n.col-xs-1,\n.col-sm-1,\n.col-md-1,\n.col-lg-1,\n.col-xs-2,\n.col-sm-2,\n.col-md-2,\n.col-lg-2,\n.col-xs-3,\n.col-sm-3,\n.col-md-3,\n.col-lg-3,\n.col-xs-4,\n.col-sm-4,\n.col-md-4,\n.col-lg-4,\n.col-xs-5,\n.col-sm-5,\n.col-md-5,\n.col-lg-5,\n.col-xs-6,\n.col-sm-6,\n.col-md-6,\n.col-lg-6,\n.col-xs-7,\n.col-sm-7,\n.col-md-7,\n.col-lg-7,\n.col-xs-8,\n.col-sm-8,\n.col-md-8,\n.col-lg-8,\n.col-xs-9,\n.col-sm-9,\n.col-md-9,\n.col-lg-9,\n.col-xs-10,\n.col-sm-10,\n.col-md-10,\n.col-lg-10,\n.col-xs-11,\n.col-sm-11,\n.col-md-11,\n.col-lg-11,\n.col-xs-12,\n.col-sm-12,\n.col-md-12,\n.col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1,\n .col-sm-2,\n .col-sm-3,\n .col-sm-4,\n .col-sm-5,\n .col-sm-6,\n .col-sm-7,\n .col-sm-8,\n .col-sm-9,\n .col-sm-10,\n .col-sm-11,\n .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1,\n .col-md-2,\n .col-md-3,\n .col-md-4,\n .col-md-5,\n .col-md-6,\n .col-md-7,\n .col-md-8,\n .col-md-9,\n .col-md-10,\n .col-md-11,\n .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1,\n .col-lg-2,\n .col-lg-3,\n .col-lg-4,\n .col-lg-5,\n .col-lg-6,\n .col-lg-7,\n .col-lg-8,\n .col-lg-9,\n .col-lg-10,\n .col-lg-11,\n .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: 0.01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: 700;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-appearance: none;\n appearance: none;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n opacity: 0.65;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n background-image: none;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n background-image: none;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n background-image: none;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n background-image: none;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n background-image: none;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n background-image: none;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: 400;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: 400;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-right: 15px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: 0.2em 0.6em 0.3em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #eeeeee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: 0.2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 12px;\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: \"\\2039\";\n}\n.carousel-control .icon-next:before {\n content: \"\\203a\";\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable\n\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// 1. Remove the bottom border in Chrome 57- and Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n//\n\nabbr[title] {\n border-bottom: none; // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*!\n * Bootstrap v3.4.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: none;\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n -moz-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n -webkit-box-shadow: none !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"../fonts/glyphicons-halflings-regular.eot\");\n src: url(\"../fonts/glyphicons-halflings-regular.eot?#iefix\") format(\"embedded-opentype\"), url(\"../fonts/glyphicons-halflings-regular.woff2\") format(\"woff2\"), url(\"../fonts/glyphicons-halflings-regular.woff\") format(\"woff\"), url(\"../fonts/glyphicons-halflings-regular.ttf\") format(\"truetype\"), url(\"../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular\") format(\"svg\");\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: 400;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: \"\\2014 \\00A0\";\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: \"\";\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: \"\\00A0 \\2014\";\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n.row-no-gutters [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n.col-xs-1,\n.col-sm-1,\n.col-md-1,\n.col-lg-1,\n.col-xs-2,\n.col-sm-2,\n.col-md-2,\n.col-lg-2,\n.col-xs-3,\n.col-sm-3,\n.col-md-3,\n.col-lg-3,\n.col-xs-4,\n.col-sm-4,\n.col-md-4,\n.col-lg-4,\n.col-xs-5,\n.col-sm-5,\n.col-md-5,\n.col-lg-5,\n.col-xs-6,\n.col-sm-6,\n.col-md-6,\n.col-lg-6,\n.col-xs-7,\n.col-sm-7,\n.col-md-7,\n.col-lg-7,\n.col-xs-8,\n.col-sm-8,\n.col-md-8,\n.col-lg-8,\n.col-xs-9,\n.col-sm-9,\n.col-md-9,\n.col-lg-9,\n.col-xs-10,\n.col-sm-10,\n.col-md-10,\n.col-lg-10,\n.col-xs-11,\n.col-sm-11,\n.col-md-11,\n.col-lg-11,\n.col-xs-12,\n.col-sm-12,\n.col-md-12,\n.col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1,\n .col-sm-2,\n .col-sm-3,\n .col-sm-4,\n .col-sm-5,\n .col-sm-6,\n .col-sm-7,\n .col-sm-8,\n .col-sm-9,\n .col-sm-10,\n .col-sm-11,\n .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1,\n .col-md-2,\n .col-md-3,\n .col-md-4,\n .col-md-5,\n .col-md-6,\n .col-md-7,\n .col-md-8,\n .col-md-9,\n .col-md-10,\n .col-md-11,\n .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1,\n .col-lg-2,\n .col-lg-3,\n .col-lg-4,\n .col-lg-5,\n .col-lg-6,\n .col-lg-7,\n .col-lg-8,\n .col-lg-9,\n .col-lg-10,\n .col-lg-11,\n .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: 0.01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: 700;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n opacity: 0.65;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n background-image: none;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n background-image: none;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n background-image: none;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n background-image: none;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n background-image: none;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n background-image: none;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: 400;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n -o-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n -o-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n -o-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: 400;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n border-top: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-right: 15px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: 0.2em 0.6em 0.3em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@-o-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n -webkit-background-size: 40px 40px;\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #eeeeee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: 0.2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out, -o-transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 12px;\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: -webkit-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out, -o-transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: \"\\2039\";\n}\n.carousel-control .icon-next:before {\n content: \"\\203a\";\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important; // Black prints faster: h5bp.com/s\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n}\n","// stylelint-disable value-list-comma-newline-after, value-list-comma-space-after, indentation, declaration-colon-newline-after, font-family-no-missing-generic-family-keyword\n\n//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n//
Star\n\n// Import the fonts\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"@{icon-font-path}@{icon-font-name}.eot\");\n src: url(\"@{icon-font-path}@{icon-font-name}.eot?#iefix\") format(\"embedded-opentype\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff2\") format(\"woff2\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff\") format(\"woff\"),\n url(\"@{icon-font-path}@{icon-font-name}.ttf\") format(\"truetype\"),\n url(\"@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}\") format(\"svg\");\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// https://getbootstrap.com/docs/3.4/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: https://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// stylelint-disable indentation, property-no-vendor-prefix, selector-no-vendor-prefix\n\n// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n word-wrap: break-word;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// stylelint-disable media-feature-name-no-vendor-prefix, media-feature-parentheses-space-inside, media-feature-name-no-unknown, indentation, at-rule-name-space-after\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","// stylelint-disable selector-list-comma-newline-after, selector-no-qualifying-type\n\n//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: 400;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n padding: .2em;\n background-color: @state-warning-bg;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: \"\\2014 \\00A0\"; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: \"\"; }\n &:after {\n content: \"\\00A0 \\2014\"; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n color: @pre-color;\n word-break: break-all;\n word-wrap: break-word;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n padding-right: ceil((@gutter / 2));\n padding-left: floor((@gutter / 2));\n margin-right: auto;\n margin-left: auto;\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-right: floor((@gutter / -2));\n margin-left: ceil((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-right: floor((@grid-gutter-width / 2));\n padding-left: ceil((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","// stylelint-disable selector-max-type, selector-max-compound-selectors, selector-no-qualifying-type\n\n//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n\n // Table cell sizing\n //\n // Reset default table behavior\n\n col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-column;\n float: none;\n }\n\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-cell;\n float: none;\n }\n }\n}\n\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\n\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n min-height: .01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n overflow-x: auto;\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * .75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type, property-no-vendor-prefix, media-feature-name-no-vendor-prefix\n\n//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: 700;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\ninput[type=\"search\"] {\n // Override content-box in Normalize (* isn't specific enough)\n .box-sizing(border-box);\n\n // Search inputs in iOS\n //\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n -webkit-appearance: none;\n appearance: none;\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n\n // Apply same disabled cursor tweak as for inputs\n // Some special care is needed because